110VCGQ/project/powerV2/Core/Src/Backup/user.c.bak

199 lines
4.2 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"
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;
}