110VCGQ/project/powerV2/Core/Src/Backup/user.c.bak
2023-07-12 15:15:16 +08:00

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