110VCGQ/project/110Vchuanganqi_0303/Core/Src/user.c
2023-04-21 17:47:03 +08:00

380 lines
9.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* user.c
*
* Created on: 2023年1月29日
* Author: wyf
*/
#include "user.h"
#include "user_lib.h"
uint16_t RS485ADDR = 0;
uint16_t RegularConvData_Tab[ADCBUFF_LEN] = {0};//ADC采集原始数据
int16_t adc_max = 0,adc1_max = 0; //最终峰峰值和
int16_t adc_positive = 0, adc_negative=0; //加外加电场后的adc值和压板投退状态
uint8_t usart_count = 0; //串口接收数据个数
uint16_t pwm_pulse = 0; //pwm波脉宽
int16_t adcValue_factor = 0; //adc测量值得修正系数*10
uint8_t RxBuff[BUFF_LEN] = {0}; //串口接收缓冲区
uint8_t TXBuff[BUFF_LEN] = {0}; //串口发送缓冲区
uint8_t uBuff[BUFF_LEN] = {0}; //用户缓冲区
int8_t polarity = 1,adc_state = 1; //电场极性,投退状态
uint8_t electric_flag = 0; //外加的反向电场极限0为负1为正
//计算峰峰值
void ADC_MAX(void)
{
uint8_t i =0;
static uint8_t number = 0;
uint16_t max = 0,min = 0;
max = RegularConvData_Tab[0];
min = RegularConvData_Tab[0];
for(i = 1;i<ADCBUFF_LEN;i++)
{
if(RegularConvData_Tab[i] > max )
{
max = RegularConvData_Tab[i];
}
else if(RegularConvData_Tab[i] < min )
{
min = RegularConvData_Tab[i];
}
}
if(max - min > 0)
{
adc1_max += max - min;
}
if(number++>=4)
{
adc1_max = adc1_max/5*3300/4095;
adc1_max = adc1_max*adcValue_factor/10;
adc1_max =polarity*adc1_max;
if(abs(adc1_max-adc_max) > 10)
{
adc_max = adc1_max;
}
if(electric_flag == 1)
{
adc_positive = adc_max;
}
else if(electric_flag == 0)
{
adc_negative = adc_max;
}
adc1_max = 0;
number = 0;
}
}
void Usart_Receive(void)
{
if( (uint16_t)uBuff[0] == RS485ADDR && usart_count == 8)
{
switch(uBuff[1]) //第二个字节,功能码
{
case 0x03: //读取传感器数据
MODBUS_03H();
break;
case 0x06: //修改modbus从机地址默认为1
MODBUS_06H();
break;
default:break;
}
}
//处理广播命令
else if( (uint16_t)uBuff[0] == 0 && usart_count== 8)
{
switch(uBuff[1]) //第二个字节,功能码
{
case 0x06: //修改modbus从机地址默认为1
MODBUS_06H();
break;
default:break;
}
}
usart_count = 0; // 清零,下次再次进入
// memset(uBuff, 0, sizeof(uBuff)); // 清空
}
//读取传感器数值
void MODBUS_03H(void)
{
uint8_t crch,crcl;
uint16_t crcack;
uint16_t addr = BEBufToUint16( (uint8_t*)(&uBuff[2])); //寄存器地址
uint16_t number = BEBufToUint16( (uint8_t*)(&uBuff[4])); //寄存器数量
uint16_t crc = CRC16_Modbus( (uint8_t*)(&uBuff[0]),6); //计算CRC
crch = crc>>8;
crcl = crc&0x00FF;
//返回传感器测量数据
if(addr == 0x0001 && number == 0x0002 &&crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值
{
TXBuff[0] = uBuff[0]; //传感器地址
TXBuff[1] = uBuff[1]; //功能码
TXBuff[2] = 0x04; //数据的字节数
TXBuff[3] = adc_max>>8; //数据的高字节
TXBuff[4] = adc_max&0x00ff; //数据的低字节
TXBuff[5] = adc_state>>8; //投退状态
TXBuff[6] = adc_state&0xff; //投退状态
crcack = CRC16_Modbus( (uint8_t*)(&TXBuff[0]),7); //计算返回数据CRC
TXBuff[7] = crcack>>8; //返回数据crc高字节
TXBuff[8] = crcack&0x00ff; //crc低字节
send_ack(9+2);
}
//返回软件版本
if(addr == 0x00FF && number == 0x0001 && crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值
{
uint8_t string[]="DCE-2302-V4_HAL";
uint8_t i;
for(i=0;i<sizeof(string);i++)
{
TXBuff[i] = string[i];
}
send_ack(sizeof(string)+1); //打印版本号
}
//返回传感器运行时间
//返回pwm波占空比
if(addr == 0x0002 && number == 0x0001 &&crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值
{
TXBuff[0] = uBuff[0]; //传感器地址
TXBuff[1] = uBuff[1]; //功能码
TXBuff[2] = 0x02; //数据的字节数
TXBuff[3] = pwm_pulse>>8; //数据的高字节
TXBuff[4] = pwm_pulse&0x00ff; //数据的低字节
crcack = CRC16_Modbus( (uint8_t*)(&TXBuff[0]),5); //计算返回数据CRC
TXBuff[5] = crcack>>8; //返回数据crc高字节
TXBuff[6] = crcack&0x00ff; //crc低字节
send_ack(7+2);
}
//返回修改系数
if(addr == 0x0003 && number == 0x0001 &&crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值
{
TXBuff[0] = uBuff[0]; //传感器地址
TXBuff[1] = uBuff[1]; //功能码
TXBuff[2] = 0x02; //数据的字节数
TXBuff[3] = adcValue_factor>>8; //数据的高字节
TXBuff[4] = adcValue_factor&0x00ff; //数据的低字节
crcack = CRC16_Modbus( (uint8_t*)(&TXBuff[0]),5); //计算返回数据CRC
TXBuff[5] = crcack>>8; //返回数据crc高字节
TXBuff[6] = crcack&0x00ff; //crc低字节
send_ack(7+2);
}
}
void MODBUS_06H(void)
{
uint8_t i;
int16_t data = (uBuff[4]<<8)|uBuff[5]; //要修改的数据
uint16_t reg = BEBufToUint16( (uint8_t*)(&uBuff[2])); //寄存器地址
uint16_t crc = CRC16_Modbus( (uint8_t*)(&uBuff[0]),6); //计算CRC
for( i = 0; i<6; i++)
{
TXBuff[i] = uBuff[i];
}
TXBuff[6] = crc>>8;
TXBuff[7] = crc&0x00FF;
//修改地址
if(reg == 0x000f && TXBuff[6]== uBuff[6] && TXBuff[7]== uBuff[7]) //比较寄存器值和CRC校验值
{
if(data>=1 && data<= 247) //从机地址要大于等于1小于等于247
{
RS485ADDR = data; //更新地址
__set_PRIMASK(1); /* 关中断 */
if(write_flash() == 0)
{
__set_PRIMASK(0); /* 开中断 */
if(uBuff[0] != 0)
{
send_ack(8+2);
}
}
}
else //地址超出范围时的返回值
{
TXBuff[4] = 0xFF;
TXBuff[5] = 0xFF;
crc = CRC16_Modbus( (uint8_t*)(&uBuff[0]),6); //计算CRC
TXBuff[6] = crc>>8;
TXBuff[7] = crc&0x00FF;
if(uBuff[0] != 0) //广播地址不返回
{
send_ack(8+2);
}
}
}
//设置PWM波脉宽
else if(reg == 0x0002 && TXBuff[6]== uBuff[6] && TXBuff[7]== uBuff[7])
{
if(data>=1 && data<= 1000) //从机地址要大于等于1小于等于247
{
pwm_pulse = data; //更新地址
__HAL_TIM_SET_COMPARE(&htim14,TIM_CHANNEL_1,pwm_pulse); //设置脉宽
__set_PRIMASK(1); /* 关中断 */
if(write_flash() == 0)
{
__set_PRIMASK(0); /* 开中断 */
send_ack(8+2);
}
}
}
//设置数系数
else if(reg == 0x0003 && TXBuff[6]== uBuff[6] && TXBuff[7]== uBuff[7])
{
if(data>=-3300 && data<= 3300) //数据大于1小于3300
{
adcValue_factor = data*10/adc_max;
if(data == 1)adcValue_factor = 10;
__set_PRIMASK(1); /* 关中断 */
if(write_flash() == 0)
{
__set_PRIMASK(0); /* 开中断 */
send_ack(8+2);
}
}
}
memset(uBuff, 0, sizeof(uBuff)); // 清空
}
void send_ack(uint8_t a)
{
HAL_GPIO_WritePin(TX485_PN_GPIO_Port, TX485_PN_Pin, GPIO_PIN_SET);//使能485芯片发送
HAL_UART_Transmit_DMA(&huart1, TXBuff, a);
while(HAL_DMA_GetState(&hdma_usart1_tx) != HAL_DMA_STATE_READY);
HAL_GPIO_WritePin(TX485_PN_GPIO_Port, TX485_PN_Pin, GPIO_PIN_RESET);//使能485芯片接收
}
uint8_t write_flash(void)
{
FLASH_EraseInitTypeDef EraseInitType;
uint32_t PageError;
uint8_t a[8] = {0};
//stm32f030F4P6: flash 16k,1k一页共16页
EraseInitType.TypeErase = FLASH_TYPEERASE_PAGES; //页擦书
EraseInitType.PageAddress = FLASH485_ADDR; //擦除页地址
EraseInitType.NbPages = 1; //擦除数量
HAL_FLASH_Unlock(); //解锁
if(HAL_FLASHEx_Erase(&EraseInitType, &PageError) != HAL_OK) //擦除
{
return 1;
}
a[0] = RS485ADDR&0xFF; //地址
a[1] = RS485ADDR>>8;
a[2] = pwm_pulse&0xFF; //占空比
a[3] = pwm_pulse>>8;
a[4] = adcValue_factor&0xFF; //数据修正的比例系数
a[5] = adcValue_factor>>8;
uint64_t *b = (uint64_t*)a;
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, FLASH485_ADDR, *b) != HAL_OK)
{
return 3 ;
}
HAL_FLASH_Lock();
return 0;
}
//判断极性
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
// GPIO_PinState = HAL_GPIO_ReadPin(coderA_GPIO_Port, coderA_Pin);
if(GPIO_Pin == PH1_Pin)
{
GPIO_PinState PH2_value = HAL_GPIO_ReadPin(PH2_GPIO_Port, PH2_Pin);
static uint8_t count = 0,polaNumber =0;
if(PH2_value==GPIO_PIN_SET)
{
polaNumber ++;
}
count++;
if(count>5)
{
if(polaNumber>=3)polarity=1;
else{polarity = -1;}
count =0;
polaNumber =0;
}
}
else if(GPIO_Pin == electric_Pin)
{
bsp_StartAutoTimer(2,5000); //5秒没有上升下降沿说明可能没有加反向电场
static uint8_t posinumber =0,neganumber = 0;
if(HAL_GPIO_ReadPin(electric_GPIO_Port, electric_Pin) == GPIO_PIN_SET) //上升沿
{
electric_flag = 1;
if(adc_positive - adc_negative >100)
{
posinumber++;
if(posinumber>=3)
{
adc_state = 0;
neganumber = 0;
}
if(posinumber>250)posinumber = 3;
}
else
{
neganumber++;
if(neganumber>=3)
{
adc_state = 1;
posinumber = 0;
}
if(neganumber>250)neganumber = 3;
}
if(abs(adc_max) <= 300)
{
adc_state = 0;
}
}
else {
electric_flag = 0;
}
}
}