/* * 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为正 uint16_t estimate_value = 70; //投退判断的差值 //计算峰峰值 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 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校验值 { if(adc_state == 1 && (abs(adc_max)<300) )adc_max = -abs(adc_max); 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); } //返回软件版本 if(addr == 0x00FF && number == 0x0001 && crch== uBuff[6] && crcl== uBuff[7]) //比较寄存器值和CRC校验值 { uint8_t string[]="DCE-2302-V4.3_HAL"; uint8_t i; for(i=0;i>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); } //返回修改系数 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); } } 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); } } } 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); } } } //设置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); } } } //设置数系数 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); } } } 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); delay_ms(5); 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>=10) { 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 >estimate_value) { posinumber++; if(posinumber>=3) { adc_state = 0; //0是退 neganumber = 0; } if(posinumber>250)posinumber = 3; } else { neganumber++; if(neganumber>=3) { adc_state = 1; //1是投 posinumber = 0; } if(neganumber>250)neganumber = 3; } // if(abs(adc_max) <= 300) // { // adc_state = 0; // } } else { electric_flag = 0; if(abs(adc_positive)>1500 ) { estimate_value = 90; } else if(abs(adc_positive)>500 ) { estimate_value = 60; } else { estimate_value = 30; } } } }