110VCGQ/project/110Vchuanganqi_0303/Core/Src/user.c

396 lines
10 KiB
C
Raw Normal View History

2023-04-21 17:47:03 +08:00
/*
* user.c
*
* Created on: 2023129
* 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为正
2023-07-12 14:20:59 +08:00
uint16_t estimate_value = 70; //投退判断的差值
2023-04-21 17:47:03 +08:00
//计算峰峰值
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];
}
}
2023-07-12 14:20:59 +08:00
//求五次的平均值
2023-04-21 17:47:03 +08:00
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;
2023-07-12 14:20:59 +08:00
// if(abs(adc1_max-adc_max) > 10)
// {
2023-04-21 17:47:03 +08:00
adc_max = adc1_max;
2023-07-12 14:20:59 +08:00
// }
2023-04-21 17:47:03 +08:00
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校验值
{
2023-07-12 14:20:59 +08:00
if(adc_state == 1 && (abs(adc_max)<300) )adc_max = -abs(adc_max);
2023-04-21 17:47:03 +08:00
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低字节
2023-07-12 14:20:59 +08:00
send_ack(9);
2023-04-21 17:47:03 +08:00
}
//返回软件版本
if(addr == 0x00FF && number == 0x0001 && crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值
{
2023-07-12 14:20:59 +08:00
uint8_t string[]="DCE-2302-V4.1_HAL";
2023-04-21 17:47:03 +08:00
uint8_t i;
2023-07-12 14:20:59 +08:00
for(i=0;i<strlen(string);i++)
2023-04-21 17:47:03 +08:00
{
TXBuff[i] = string[i];
}
2023-07-12 14:20:59 +08:00
send_ack(strlen(string)); //打印版本号
2023-04-21 17:47:03 +08:00
}
//返回传感器运行时间
//返回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低字节
2023-07-12 14:20:59 +08:00
send_ack(7);
2023-04-21 17:47:03 +08:00
}
//返回修改系数
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低字节
2023-07-12 14:20:59 +08:00
send_ack(7);
2023-04-21 17:47:03 +08:00
}
}
void MODBUS_06H(void)
{
uint8_t i;
int16_t data = (uBuff[4]<<8)|uBuff[5]; //要修改的数据
uint16_t reg = BEBufToUint16( (uint8_t*)(&uBuff[2])); //寄存器地址
2023-07-12 14:20:59 +08:00
uint16_t crc = CRC16_Modbus( (uint8_t*)(&uBuff[0]),6); //计算CRC
2023-04-21 17:47:03 +08:00
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)
{
2023-07-12 14:20:59 +08:00
send_ack(8);
2023-04-21 17:47:03 +08:00
}
}
}
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) //广播地址不返回
{
2023-07-12 14:20:59 +08:00
send_ack(8);
2023-04-21 17:47:03 +08:00
}
}
}
//设置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)
2023-07-12 14:20:59 +08:00
{ __set_PRIMASK(0); /* 开中断 */
send_ack(8);
2023-04-21 17:47:03 +08:00
}
2023-07-12 14:20:59 +08:00
2023-04-21 17:47:03 +08:00
}
}
//设置数系数
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); /* 开中断 */
2023-07-12 14:20:59 +08:00
send_ack(8);
2023-04-21 17:47:03 +08:00
}
}
}
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);
2023-07-12 14:20:59 +08:00
delay_ms(5);
2023-04-21 17:47:03 +08:00
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);
2023-07-12 14:20:59 +08:00
if(GPIO_Pin == PH1_Pin) //判断电场极性
2023-04-21 17:47:03 +08:00
{
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;
}
}
2023-07-12 14:20:59 +08:00
else if(GPIO_Pin == electric_Pin) //判断压板投退状态
2023-04-21 17:47:03 +08:00
{
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;
2023-07-12 14:20:59 +08:00
if(adc_positive - adc_negative >estimate_value)
2023-04-21 17:47:03 +08:00
{
posinumber++;
if(posinumber>=3)
{
2023-07-12 14:20:59 +08:00
adc_state = 0; //0是退
2023-04-21 17:47:03 +08:00
neganumber = 0;
}
if(posinumber>250)posinumber = 3;
}
else
{
neganumber++;
if(neganumber>=3)
{
2023-07-12 14:20:59 +08:00
adc_state = 1; //1是投
2023-04-21 17:47:03 +08:00
posinumber = 0;
}
if(neganumber>250)neganumber = 3;
}
2023-07-12 14:20:59 +08:00
// if(abs(adc_max) <= 300)
// {
// adc_state = 0;
// }
2023-04-21 17:47:03 +08:00
}
else {
electric_flag = 0;
2023-07-12 14:20:59 +08:00
if(abs(adc_positive)>1500 )
{
estimate_value = 150;
}
else if(abs(adc_positive)>500 )
{
estimate_value = 100;
}
else
{
estimate_value = 40;
}
2023-04-21 17:47:03 +08:00
}
}
}