/* * user.c * * Created on: 2023年1月29日 * Author: wyf */ #include "user.h" #include "user_lib.h" uint8_t usart_count = 0; //串口接收数据个数 uint8_t RxBuff[BUFF_LEN] = {0}; //串口接收缓冲区 uint8_t TXBuff[BUFF_LEN] = {0}; //串口发送缓冲区 uint8_t uBuff[BUFF_LEN] = {0}; //用户缓冲区 uint16_t positive_time = 1000; //正电场持续时间 uint16_t negative_time = 1000; //负电场持续时间 uint16_t RS485ADDR = 1; //485地址 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; // 清零,下次再次进入 } //读取传感器数值 void MODBUS_03H(void) { } void MODBUS_06H(void) { uint8_t i; int16_t data = BEBufToUint16( (uint8_t*)(&uBuff[4])); //要修改的数据 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) { if(uBuff[0] != 0) { send_ack(8); } } __set_PRIMASK(0); /* 开中断 */ } 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); } } } //设置正电场持续时间 else if(reg == 0x0004 && TXBuff[6]== uBuff[6] && TXBuff[7]== uBuff[7]) { if(data>=500) { positive_time = data; //更新地址 __set_PRIMASK(1); /* 关中断 */ if(write_flash() == 0) { send_ack(8); } __set_PRIMASK(0); /* 开中断 */ } } //设置负电场持续时间 else if(reg == 0x0005 && TXBuff[6]== uBuff[6] && TXBuff[7]== uBuff[7]) { if(data>=500) //数据大于1小于3300 { negative_time = data; __set_PRIMASK(1); /* 关中断 */ if(write_flash() == 0) { send_ack(8); } __set_PRIMASK(0); /* 开中断 */ } } 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] = positive_time&0xFF; //占空比 a[3] = positive_time>>8; a[4] = negative_time&0xFF; //数据修正的比例系数 a[5] = negative_time>>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; }