931 lines
21 KiB
C
931 lines
21 KiB
C
|
/*
|
|||
|
* user.c
|
|||
|
*
|
|||
|
* Created on: Sep 23, 2024
|
|||
|
* Author: 10425
|
|||
|
*/
|
|||
|
#include "user.h"
|
|||
|
|
|||
|
volatile uint8_t usart_count = 0; //串口接收数据个数
|
|||
|
uint8_t RxBuff[BUFF_LEN] = {0}; //串口接收缓冲区
|
|||
|
uint8_t TXBuff[BUFF_LEN] = {0}; //串口发送缓冲区
|
|||
|
uint8_t uBuff[BUFF_LEN] = {0}; //用户缓冲区
|
|||
|
volatile int8_t polarity = 1; //电场极性,投退状态
|
|||
|
volatile uint8_t electric_flag = 0; //外加的反向电场极限,0为负,1为正
|
|||
|
|
|||
|
volatile struct REGISTER dev_reg ={0};
|
|||
|
|
|||
|
uint16_t RegularConvData_Tab[ADCBUFF_LEN] = {0}; //ADC采集原始数据
|
|||
|
volatile int16_t adc_positive = 0, adc_negative=0; //加外加电场后的adc值
|
|||
|
|
|||
|
char version_string[]="DCE-2406-V6.0_HAL";
|
|||
|
uint16_t version_number = 600;
|
|||
|
|
|||
|
|
|||
|
uint16_t user_temp = 0;
|
|||
|
/*1:传感器数据 2:投退状态 3:电机状态
|
|||
|
* 4:PWM波占空比 5:传感器缩放系数 6:传感器加减系数
|
|||
|
* 7:电机运行时间 8:设置波特率 9:温湿度
|
|||
|
* 10:方波投退判断阈值 11:传感器退阈值 12:电压值
|
|||
|
* 13:电压阈值,电压小于该值时为退
|
|||
|
*/
|
|||
|
int16_t user_register[14] = {0}; //寄存器值
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//求adc波形的峰峰值
|
|||
|
void ADC_MAX(void)
|
|||
|
{
|
|||
|
uint8_t i =0;
|
|||
|
static uint8_t number = 0;
|
|||
|
uint16_t max = 0,min = 0;
|
|||
|
static int16_t adc1_max = 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];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(max - min > 0)
|
|||
|
{
|
|||
|
adc1_max += max - min;
|
|||
|
}
|
|||
|
|
|||
|
if(number++>=4)
|
|||
|
{
|
|||
|
adc1_max = adc1_max/5*3300/4095;
|
|||
|
adc1_max = adc1_max*dev_reg.adcValue_factor/10 + dev_reg.adcValue_addnum;
|
|||
|
adc1_max = polarity*adc1_max;
|
|||
|
// if(humidness>50)
|
|||
|
// adc1_max += 0.3801*humidness*humidness - 16.825*humidness + 148.37;
|
|||
|
|
|||
|
dev_reg.adc_max = adc1_max;
|
|||
|
|
|||
|
|
|||
|
if(electric_flag == 1)
|
|||
|
{
|
|||
|
if(dev_reg.adc_max>adc_positive)
|
|||
|
{
|
|||
|
adc_positive = dev_reg.adc_max;
|
|||
|
}
|
|||
|
}
|
|||
|
else if(electric_flag == 0)
|
|||
|
{
|
|||
|
if(dev_reg.adc_max<adc_negative)
|
|||
|
{
|
|||
|
adc_negative = dev_reg.adc_max;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
adc1_max = 0;
|
|||
|
number = 0;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void user_init(void)
|
|||
|
{
|
|||
|
uint8_t parameters[18];
|
|||
|
|
|||
|
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
|
|||
|
__HAL_UART_CLEAR_IT(&huart1,UART_CLEAR_IDLEF|UART_CLEAR_TCF);
|
|||
|
bsp_InitTimer();
|
|||
|
AHT20_Init(&SENx,2000,0x38);
|
|||
|
HAL_StatusTypeDef status = AT24C16_Init();
|
|||
|
if(status != HAL_OK);
|
|||
|
|
|||
|
HAL_TIM_Base_Start_IT(&htim14);
|
|||
|
HAL_TIM_PWM_Start_IT(&htim14, TIM_CHANNEL_1); //开启PWM波输出
|
|||
|
|
|||
|
HAL_UART_DMAStop(&huart1);//复位DMA //串口DMA接受
|
|||
|
HAL_UART_Receive_DMA(&huart1,(uint8_t *)RxBuff,sizeof(RxBuff));
|
|||
|
|
|||
|
|
|||
|
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)RegularConvData_Tab, ADCBUFF_LEN); //开启ADC转换
|
|||
|
|
|||
|
// //DE发射器使能,高电平有效,RE接收器使能,低电平有效
|
|||
|
HAL_GPIO_WritePin(TXEN_485_GPIO_Port, TXEN_485_Pin, GPIO_PIN_RESET);
|
|||
|
|
|||
|
//读取设备参数
|
|||
|
// uint8_t a[] = {1,2,3,4,5};
|
|||
|
// AT24C16_WriteBytes(0,a, 5);
|
|||
|
status=AT24C16_ReadBytes(0, parameters, sizeof(parameters));
|
|||
|
if(status == HAL_OK)
|
|||
|
{
|
|||
|
dev_reg.addr = parameters[0]<<8| parameters[1];
|
|||
|
if(dev_reg.addr == 0xFF )
|
|||
|
{
|
|||
|
dev_reg.addr =1;
|
|||
|
}
|
|||
|
|
|||
|
dev_reg.baud_rate = parameters[2]<<8|parameters[3];
|
|||
|
if(dev_reg.baud_rate == 0xFF)
|
|||
|
{
|
|||
|
dev_reg.baud_rate =0;
|
|||
|
}
|
|||
|
Uart_SetBaud(dev_reg.baud_rate);
|
|||
|
|
|||
|
dev_reg.pwm_pulse = parameters[4]<<8 | parameters[5];
|
|||
|
if(dev_reg.pwm_pulse == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.pwm_pulse = 700;
|
|||
|
}
|
|||
|
__HAL_TIM_SET_COMPARE(&htim14,TIM_CHANNEL_1,dev_reg.pwm_pulse);
|
|||
|
|
|||
|
dev_reg.adcValue_factor = parameters[6]<<8 | parameters[7];
|
|||
|
if(dev_reg.adcValue_factor == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.adcValue_factor = 10;
|
|||
|
}
|
|||
|
|
|||
|
dev_reg.adcValue_addnum = parameters[8]<<8 | parameters[9];
|
|||
|
if(dev_reg.adcValue_addnum==0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.adcValue_addnum =0;
|
|||
|
}
|
|||
|
|
|||
|
//投退方波阈值
|
|||
|
dev_reg.estimate_value = parameters[10]<<8 | parameters[11];
|
|||
|
if(dev_reg.estimate_value == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.estimate_value = 40;
|
|||
|
}
|
|||
|
|
|||
|
//传感器退阈值
|
|||
|
dev_reg.threshold_value = parameters[12]<<8 | parameters[13];
|
|||
|
if(dev_reg.threshold_value == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.threshold_value =0;
|
|||
|
}
|
|||
|
|
|||
|
//电压标定值
|
|||
|
dev_reg.reference = parameters[14]<<8 | parameters[15];
|
|||
|
if(dev_reg.reference == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.reference =0;
|
|||
|
}
|
|||
|
|
|||
|
//电压阈值
|
|||
|
dev_reg.voltage_thresh = parameters[16]<<8 | parameters[17];
|
|||
|
if(dev_reg.voltage_thresh == 0xFFFF)
|
|||
|
{
|
|||
|
dev_reg.voltage_thresh = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void Usart_Receive()
|
|||
|
{
|
|||
|
if( (uint16_t)uBuff[0] == dev_reg.addr )
|
|||
|
{
|
|||
|
switch(uBuff[1])
|
|||
|
{
|
|||
|
case 0x03: //读传感器数据
|
|||
|
MODBUS_03H();
|
|||
|
break;
|
|||
|
|
|||
|
case 0x06:
|
|||
|
MODBUS_06H();
|
|||
|
break;
|
|||
|
|
|||
|
case 0x10:
|
|||
|
MODBUS_10H();
|
|||
|
break;
|
|||
|
|
|||
|
default:break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//广播指令
|
|||
|
else if((uint16_t)uBuff[0] == 0 )
|
|||
|
{
|
|||
|
switch(uBuff[1])
|
|||
|
{
|
|||
|
case 0x06:
|
|||
|
MODBUS_06H();
|
|||
|
break;
|
|||
|
case 0x10:
|
|||
|
MODBUS_10H();
|
|||
|
break;
|
|||
|
|
|||
|
default:break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* Name: CRC-16/MODBUS x16+x15+x2+1
|
|||
|
* Poly: 0x8005
|
|||
|
* Init: 0xFFFF
|
|||
|
* Refin: True
|
|||
|
* Refout: True
|
|||
|
* Xorout: 0x0000
|
|||
|
* Note:
|
|||
|
**********************************************************/
|
|||
|
uint16_t crc16_modbus(uint8_t *data, uint16_t length)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
uint16_t crc = 0xffff; // Initial value
|
|||
|
while(length--)
|
|||
|
{
|
|||
|
crc ^= *data++; // crc ^= *data; data++;
|
|||
|
for (i = 0; i < 8; ++i)
|
|||
|
{
|
|||
|
if (crc & 1)
|
|||
|
crc = (crc >> 1) ^ 0xA001; // 0xA001 = reverse 0x8005
|
|||
|
else
|
|||
|
crc = (crc >> 1);
|
|||
|
}
|
|||
|
}
|
|||
|
return crc;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void MODBUS_03H()
|
|||
|
{
|
|||
|
//接收到的数据帧
|
|||
|
//485地址 功能位 寄存器地址 寄存器个数 crc低位 crc高位
|
|||
|
uint8_t crch,crcl;
|
|||
|
uint16_t crcack;
|
|||
|
uint16_t addr = (uint16_t)uBuff[2]<<8 | uBuff[3]; //寄存器地址
|
|||
|
uint16_t number = (uint16_t)uBuff[4]<<8 | uBuff[5]; //寄存器数量
|
|||
|
uint16_t crc = crc16_modbus(uBuff,6); //计算CRC
|
|||
|
crch = crc>>8;
|
|||
|
crcl = crc&0x00FF;
|
|||
|
|
|||
|
user_register[1] = dev_reg.adc_max;
|
|||
|
user_register[2] = dev_reg.adc_state;
|
|||
|
if(dev_reg.voltage == 0) user_register[2]= 0;
|
|||
|
else if(abs(dev_reg.voltage) < dev_reg.voltage_thresh && user_temp>6)
|
|||
|
{
|
|||
|
user_register[2]= 0;
|
|||
|
dev_reg.voltage = 0;
|
|||
|
}
|
|||
|
user_register[3] = dev_reg.motor_state;
|
|||
|
user_register[4] = dev_reg.pwm_pulse;
|
|||
|
user_register[5] = dev_reg.adcValue_factor;
|
|||
|
user_register[6] = dev_reg.adcValue_addnum;
|
|||
|
user_register[7] = dev_reg.peak_value;
|
|||
|
user_register[8] = dev_reg.baud_rate;
|
|||
|
user_register[9] = (dev_reg.humidness<<8)|dev_reg.tempe;
|
|||
|
user_register[10] = dev_reg.estimate_value;
|
|||
|
user_register[11] = dev_reg.threshold_value;
|
|||
|
user_register[12] = dev_reg.voltage;
|
|||
|
user_register[13] = dev_reg.voltage_thresh;
|
|||
|
if( (addr+number) <= 14 && crcl == uBuff[6] && crch == uBuff[7])
|
|||
|
{
|
|||
|
uint8_t cnt = 0;
|
|||
|
TXBuff[cnt++] = uBuff[0];
|
|||
|
TXBuff[cnt++] = uBuff[1];
|
|||
|
TXBuff[cnt++] = number*2; //数据个数,单位/字节
|
|||
|
for(uint8_t i =0;i<number;i++)
|
|||
|
{
|
|||
|
TXBuff[cnt++] = user_register[addr+i] >>8;
|
|||
|
TXBuff[cnt++] = user_register[addr+i] & 0xFF;
|
|||
|
}
|
|||
|
crcack = crc16_modbus(TXBuff,cnt);
|
|||
|
TXBuff[cnt++] = crcack & 0xff;
|
|||
|
TXBuff[cnt++] = crcack >>8;
|
|||
|
send_ack(cnt);
|
|||
|
}
|
|||
|
|
|||
|
//读取版本号
|
|||
|
if(addr == 0x00FF && number == 0x0001 && crcl== uBuff[6] && crch== uBuff[7]) //比较寄存器值和CRC校验值
|
|||
|
{
|
|||
|
|
|||
|
uint8_t i;
|
|||
|
for(i=0;i<strlen(version_string);i++)
|
|||
|
{
|
|||
|
TXBuff[i] = version_string[i];
|
|||
|
}
|
|||
|
|
|||
|
send_ack(strlen(version_string)); //打印版本号
|
|||
|
}
|
|||
|
|
|||
|
//版本号
|
|||
|
if( addr == 0xFD && crcl == uBuff[6] && crch == uBuff[7])
|
|||
|
{
|
|||
|
uint8_t cnt = 0;
|
|||
|
TXBuff[cnt++] = uBuff[0];
|
|||
|
TXBuff[cnt++] = uBuff[1];
|
|||
|
TXBuff[cnt++] = number*2; //数据个数,单位/字节
|
|||
|
TXBuff[cnt++] = version_number >>8;
|
|||
|
TXBuff[cnt++] = version_number & 0xFF;
|
|||
|
crcack = crc16_modbus(TXBuff,cnt);
|
|||
|
TXBuff[cnt++] = crcack & 0xff;
|
|||
|
TXBuff[cnt++] = crcack >>8;
|
|||
|
send_ack(cnt);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void MODBUS_06H()
|
|||
|
{
|
|||
|
enum WRITE_REG_ADDR write_reg_addr;
|
|||
|
|
|||
|
int16_t data = ((int16_t)uBuff[4]<<8)|uBuff[5]; //数据 //要修改的数据
|
|||
|
uint16_t reg = ((int16_t)uBuff[2]<<8)|uBuff[3]; //寄存器地址 //寄存器地址
|
|||
|
uint16_t crc = crc16_modbus( uBuff,6);
|
|||
|
for(uint8_t i = 0;i<6;i++)
|
|||
|
{
|
|||
|
TXBuff[i] = uBuff[i];
|
|||
|
}
|
|||
|
TXBuff[6] = crc&0xFF;
|
|||
|
TXBuff[7] = crc>>8;
|
|||
|
|
|||
|
if(TXBuff[6]!=uBuff[6] || TXBuff[7]!=uBuff[7])return;
|
|||
|
|
|||
|
//修改地址
|
|||
|
if(reg == 0x000f )
|
|||
|
{
|
|||
|
if(data>=1 && data <= 247)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.addr;
|
|||
|
dev_reg.addr = data;
|
|||
|
write_reg_addr = write_addr;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.addr = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置PWM波占空比
|
|||
|
if(reg == 0x0004)
|
|||
|
{
|
|||
|
if(data>=0 && data <= 1000)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.addr;
|
|||
|
dev_reg.pwm_pulse = data;
|
|||
|
write_reg_addr = write_pulse;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
__HAL_TIM_SET_COMPARE(&htim14,TIM_CHANNEL_1,dev_reg.pwm_pulse); //设置脉宽
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.pwm_pulse = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置传感器缩放系数
|
|||
|
if(reg == 0x0005)
|
|||
|
{
|
|||
|
if(data>=-3300 && data <= 3300)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.adcValue_factor;
|
|||
|
dev_reg.adcValue_factor = data*10/dev_reg.adc_max;
|
|||
|
if(data>=5 && data <= 20)dev_reg.adcValue_factor = data;
|
|||
|
|
|||
|
write_reg_addr = write_factor;
|
|||
|
if(dev_reg.adcValue_factor>=5 && dev_reg.adcValue_factor<=20)
|
|||
|
{
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.adcValue_factor = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置传感器加减系数
|
|||
|
if(reg == 0x0006)
|
|||
|
{
|
|||
|
if(data>= -2000 && data <= 2000)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.adcValue_addnum;
|
|||
|
dev_reg.adcValue_addnum = data;
|
|||
|
write_reg_addr = write_addnum;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.adcValue_addnum = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置波特率
|
|||
|
if(reg == 0x0008)
|
|||
|
{
|
|||
|
if(data>= 0 && data <= 3)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.baud_rate;
|
|||
|
dev_reg.baud_rate = data;
|
|||
|
write_reg_addr = write_baud;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.baud_rate = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置投退方波阈值
|
|||
|
if(reg == 0x000A)
|
|||
|
{
|
|||
|
if(data>= 0 && data <= 1500)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.estimate_value;
|
|||
|
dev_reg.estimate_value = data;
|
|||
|
write_reg_addr = write_estimate;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.estimate_value = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置原始数据退阈值
|
|||
|
if(reg == 0x000B)
|
|||
|
{
|
|||
|
if(data>= 0 && data <= 1500)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.threshold_value;
|
|||
|
dev_reg.threshold_value = data;
|
|||
|
write_reg_addr = write_threshold;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.threshold_value = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置电压参考值
|
|||
|
if(reg == 12)
|
|||
|
{
|
|||
|
if(data>= -220 && data <= 220)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.reference;
|
|||
|
if(data != 0)
|
|||
|
{
|
|||
|
dev_reg.reference = 110.0/data*dev_reg.adc_max;
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.reference =1;
|
|||
|
}
|
|||
|
write_reg_addr = write_reference;
|
|||
|
if(write_flash(write_reg_addr,dev_reg.reference)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.threshold_value = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//设置电压阈值
|
|||
|
if(reg == 13)
|
|||
|
{
|
|||
|
if(data>= 0 && data <= 220)
|
|||
|
{
|
|||
|
int16_t temp = dev_reg.voltage_thresh;
|
|||
|
dev_reg.voltage_thresh = data;
|
|||
|
write_reg_addr = write_voltageth;
|
|||
|
if(write_flash(write_reg_addr,data)==HAL_OK)
|
|||
|
{
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
else {
|
|||
|
dev_reg.voltage_thresh = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void MODBUS_10H()
|
|||
|
{
|
|||
|
//用于更新代码,每次固定接收128字节数据
|
|||
|
static uint16_t current_addr =1; //当前寄存器地址,表示当前的块号
|
|||
|
static uint16_t file_size; //文件大小
|
|||
|
static uint16_t current_size = 0;
|
|||
|
uint16_t crctemp;
|
|||
|
|
|||
|
uint16_t reg_addr = (uint16_t)uBuff[2]<<8 | uBuff[3]; //寄存器地址
|
|||
|
uint16_t reg_number = (uint16_t)uBuff[4]<<8 | uBuff[5]; //寄存器数量
|
|||
|
uint8_t byte_number = uBuff[6]; //字节数
|
|||
|
uint16_t crc = crc16_modbus( uBuff,7+byte_number);
|
|||
|
if((crc&0xFF)!=uBuff[6+byte_number+1] || crc>>8!=uBuff[6+byte_number+2]
|
|||
|
|| (reg_addr>current_addr&®_addr!=0xFFFF))
|
|||
|
{
|
|||
|
|
|||
|
//返回错误响应
|
|||
|
if(uBuff[0]!=0) //地址不为0时
|
|||
|
{
|
|||
|
TXBuff[0] = dev_reg.addr;
|
|||
|
TXBuff[1] = 0x10;
|
|||
|
TXBuff[2] = 1; //错误码
|
|||
|
crctemp = crc16_modbus(TXBuff, 3);
|
|||
|
TXBuff[3] = crctemp&0xFF;
|
|||
|
TXBuff[4] = crctemp>>8;
|
|||
|
send_ack(5);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t data[128];
|
|||
|
memcpy(data,&uBuff[7],128);
|
|||
|
//起始段
|
|||
|
if(reg_addr == 0 && reg_number == 1 && byte_number == 2)
|
|||
|
{
|
|||
|
// bsp_StartAutoTimer(8, 100); //升级程序时,灯变为快闪
|
|||
|
file_size =0;
|
|||
|
current_addr = 0;
|
|||
|
file_size = data[0]<<8 | data[1];
|
|||
|
current_addr++;
|
|||
|
}
|
|||
|
|
|||
|
//数据段
|
|||
|
else if(reg_addr == current_addr && reg_number==64 && byte_number == 128)
|
|||
|
{
|
|||
|
if(write_code(app2_addr+current_size,data,128) != HAL_OK)
|
|||
|
{
|
|||
|
//返回错误响应
|
|||
|
if(uBuff[0]!=0) //地址不为0时
|
|||
|
{
|
|||
|
TXBuff[0] = dev_reg.addr;
|
|||
|
TXBuff[1] = 0x10;
|
|||
|
TXBuff[2] = 1; //错误码
|
|||
|
crctemp = crc16_modbus(TXBuff, 3);
|
|||
|
TXBuff[3] = crctemp&0xFF;
|
|||
|
TXBuff[4] = crctemp>>8;
|
|||
|
send_ack(5);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
current_size+= 128;
|
|||
|
current_addr++;
|
|||
|
}
|
|||
|
|
|||
|
//结束段
|
|||
|
else if (reg_addr == 0xFFFF && reg_number == 1 && byte_number == 2)
|
|||
|
{
|
|||
|
if(((data[0]<<8|data[1]) == current_addr) && current_size >= file_size)
|
|||
|
{
|
|||
|
//正常响应
|
|||
|
if(uBuff[0]!=0) //地址不为0时
|
|||
|
{
|
|||
|
TXBuff[0] = dev_reg.addr;
|
|||
|
TXBuff[1] = 0x10;
|
|||
|
TXBuff[2] = reg_addr>>8; //错误码
|
|||
|
TXBuff[3] = reg_addr&0xFF;
|
|||
|
TXBuff[4] = reg_number>>8; //错误码
|
|||
|
TXBuff[5] = reg_number&0xFF;
|
|||
|
crctemp = crc16_modbus(TXBuff, 3);
|
|||
|
TXBuff[6] = crctemp&0xFF;
|
|||
|
TXBuff[7] = crctemp>>8;
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
|
|||
|
//跳转
|
|||
|
if(( ( *(volatile uint32_t*)app2_addr)&0x2FFE0000 )==0x20000000)
|
|||
|
{
|
|||
|
|
|||
|
// uint8_t aa[2] = {0,0};
|
|||
|
// AT24C16_WriteBytes(FILE_SIZE_ADDR, aa, sizeof(aa));
|
|||
|
// AT24C16_ReadBytes(FILE_SIZE_ADDR, aa, sizeof(aa));
|
|||
|
|
|||
|
// 禁用中断
|
|||
|
HAL_ADC_Stop_DMA(&hadc1);
|
|||
|
__disable_irq();
|
|||
|
SCB->VTOR = app2_addr;
|
|||
|
|
|||
|
LoadApp loadapp;
|
|||
|
|
|||
|
loadapp=(LoadApp)( *(volatile uint32_t*)(app2_addr+4) ); //用户代码区第二个字为程序开始地址(复位地址)
|
|||
|
__set_MSP(*(volatile uint32_t*)app2_addr); //初始化MSP
|
|||
|
|
|||
|
loadapp();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else {
|
|||
|
// bsp_StartAutoTimer(8, 500); //升级程序时,灯变为快闪
|
|||
|
file_size =0;
|
|||
|
current_addr = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//正常响应
|
|||
|
if(uBuff[0]!=0) //地址不为0时
|
|||
|
{
|
|||
|
TXBuff[0] = dev_reg.addr;
|
|||
|
TXBuff[1] = 0x10;
|
|||
|
TXBuff[2] = reg_addr>>8; //寄存器地址
|
|||
|
TXBuff[3] = reg_addr&0xFF;
|
|||
|
TXBuff[4] = reg_number>>8;
|
|||
|
TXBuff[5] = reg_number&0xFF; //寄存器个数
|
|||
|
crctemp = crc16_modbus(TXBuff, 6);
|
|||
|
TXBuff[6] = crctemp&0xFF;
|
|||
|
TXBuff[7] = crctemp>>8;
|
|||
|
send_ack(8);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//写入代码,length长度必须为8的倍数,
|
|||
|
HAL_StatusTypeDef write_code(uint32_t addr,uint8_t* data,uint16_t length)
|
|||
|
{
|
|||
|
FLASH_EraseInitTypeDef EraseInitType;
|
|||
|
uint32_t PageError;
|
|||
|
uint32_t current_page = (addr-FLASH_BASE_ADDR)/FLASH_SECTOR_SIZE;
|
|||
|
|
|||
|
HAL_FLASH_Unlock();
|
|||
|
if( (addr-FLASH_BASE_ADDR)%FLASH_SECTOR_SIZE == 0)
|
|||
|
{
|
|||
|
EraseInitType.TypeErase = FLASH_TYPEERASE_PAGES; //页擦书
|
|||
|
EraseInitType.Page = current_page; //擦除起始页
|
|||
|
EraseInitType.NbPages = 1; //擦除数量
|
|||
|
|
|||
|
if(HAL_FLASHEx_Erase(&EraseInitType, &PageError)!= HAL_OK)
|
|||
|
{
|
|||
|
return HAL_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
uint64_t *a = (uint64_t*)data;
|
|||
|
for(int i=0;i<length/8;i++)
|
|||
|
{
|
|||
|
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr+i*8, *(a+i)) != HAL_OK)
|
|||
|
{
|
|||
|
return HAL_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
HAL_FLASH_Lock();
|
|||
|
return HAL_OK;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void send_ack(uint8_t cnt)
|
|||
|
{
|
|||
|
HAL_GPIO_WritePin(TXEN_485_GPIO_Port, TXEN_485_Pin, GPIO_PIN_SET);//使能485芯片发送
|
|||
|
HAL_UART_Transmit_DMA(&huart1, TXBuff, cnt);
|
|||
|
while(HAL_DMA_GetState(&hdma_usart1_tx) != HAL_DMA_STATE_READY);
|
|||
|
delay_ms(5);
|
|||
|
HAL_GPIO_WritePin(TXEN_485_GPIO_Port, TXEN_485_Pin, GPIO_PIN_RESET);//使能485芯片接收
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void Uart_SetBaud(int16_t baud)
|
|||
|
{
|
|||
|
HAL_UART_DeInit(&huart1); //如果不清除,DMA会产生bug
|
|||
|
|
|||
|
huart1.Instance = USART1;
|
|||
|
huart1.Init.BaudRate = 9600;
|
|||
|
if(baud == 1)
|
|||
|
{
|
|||
|
huart1.Init.BaudRate = 19200;
|
|||
|
}
|
|||
|
else if(baud == 2)
|
|||
|
{
|
|||
|
huart1.Init.BaudRate = 57600;
|
|||
|
}
|
|||
|
else if(baud == 3)
|
|||
|
{
|
|||
|
huart1.Init.BaudRate = 115200;
|
|||
|
}
|
|||
|
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
|||
|
huart1.Init.StopBits = UART_STOPBITS_1;
|
|||
|
huart1.Init.Parity = UART_PARITY_NONE;
|
|||
|
huart1.Init.Mode = UART_MODE_TX_RX;
|
|||
|
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
|||
|
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
|||
|
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
|||
|
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
|||
|
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
|||
|
if (HAL_UART_Init(&huart1) != HAL_OK)
|
|||
|
{
|
|||
|
Error_Handler();
|
|||
|
}
|
|||
|
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
|
|||
|
{
|
|||
|
Error_Handler();
|
|||
|
}
|
|||
|
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
|
|||
|
{
|
|||
|
Error_Handler();
|
|||
|
}
|
|||
|
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
|
|||
|
{
|
|||
|
Error_Handler();
|
|||
|
}
|
|||
|
|
|||
|
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
|
|||
|
__HAL_UART_CLEAR_IT(&huart1,UART_CLEAR_IDLEF|UART_CLEAR_TCF);
|
|||
|
}
|
|||
|
|
|||
|
//保存数据
|
|||
|
HAL_StatusTypeDef write_flash(uint16_t addr,int16_t data)
|
|||
|
{
|
|||
|
uint8_t temp[2];
|
|||
|
temp[0] = data>>8;
|
|||
|
temp[1] = data&0xFF;
|
|||
|
addr = addr+1;
|
|||
|
return AT24C16_WriteBytes(addr, temp, sizeof(temp));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//外部中断回调函数,
|
|||
|
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
|
|||
|
{
|
|||
|
static uint8_t count = 0,polaNumber =0;
|
|||
|
static int16_t last_negative = 0;
|
|||
|
static GPIO_PinState PH2_value =GPIO_PIN_RESET,PH1_value = GPIO_PIN_RESET;
|
|||
|
PH2_value = HAL_GPIO_ReadPin(PH2_GPIO_Port, PH2_Pin);
|
|||
|
PH1_value = HAL_GPIO_ReadPin(PH1_GPIO_Port, PH1_Pin);
|
|||
|
|
|||
|
if(GPIO_Pin == PH1_Pin && PH1_value == GPIO_PIN_SET )
|
|||
|
{
|
|||
|
|
|||
|
//判断电机运动状态
|
|||
|
static uint32_t last_tick = 0;
|
|||
|
// last_tick = HAL_GetTick();
|
|||
|
uint32_t a = HAL_GetTick();
|
|||
|
if( (a -last_tick) < 8)
|
|||
|
{
|
|||
|
bsp_StartAutoTimer(4,1000); //1秒没有检测到上升沿,说明电机不正常或红外线发射接收不正常
|
|||
|
if(dev_reg.motor_state == 1)
|
|||
|
{
|
|||
|
bsp_StartAutoTimer(2,500); //led2闪烁
|
|||
|
dev_reg.motor_state = 0;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
last_tick = a;
|
|||
|
|
|||
|
//判断极性
|
|||
|
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 == SDA_Pin) //判断压板投退状态
|
|||
|
{
|
|||
|
bsp_StartAutoTimer(3,5000); //5秒没有上升下降沿,说明可能没有加反向电场
|
|||
|
static uint8_t posinumber =0,neganumber = 0;
|
|||
|
if(HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin) == GPIO_PIN_SET) //上升沿
|
|||
|
{
|
|||
|
electric_flag = 1;
|
|||
|
dev_reg.peak_value = adc_positive - adc_negative;
|
|||
|
if(adc_positive - adc_negative >dev_reg.estimate_value)
|
|||
|
{
|
|||
|
if(adc_positive>0) //电压为正
|
|||
|
{
|
|||
|
posinumber++;
|
|||
|
neganumber = 0;
|
|||
|
if(posinumber>=3)
|
|||
|
{
|
|||
|
dev_reg.adc_state = 0; //0是退
|
|||
|
}
|
|||
|
}
|
|||
|
else { //电压为负时,峰峰值计算时,当前的正值减上上次的负值
|
|||
|
dev_reg.peak_value = adc_positive - last_negative;
|
|||
|
if(adc_positive-last_negative>dev_reg.estimate_value)
|
|||
|
{
|
|||
|
posinumber++;
|
|||
|
neganumber = 0;
|
|||
|
if(posinumber>=3)
|
|||
|
{
|
|||
|
dev_reg.adc_state = 0; //0是退
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
neganumber++;
|
|||
|
posinumber = 0;
|
|||
|
if(neganumber>=3)
|
|||
|
{
|
|||
|
dev_reg.adc_state = 1; //1是投
|
|||
|
}
|
|||
|
if(neganumber>250)neganumber = 3;
|
|||
|
}
|
|||
|
}
|
|||
|
if(posinumber>250)posinumber = 3;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
neganumber++;
|
|||
|
posinumber = 0;
|
|||
|
if(neganumber>=2)
|
|||
|
{
|
|||
|
dev_reg.adc_state = 1; //1是投
|
|||
|
}
|
|||
|
if(neganumber>250)neganumber = 3;
|
|||
|
}
|
|||
|
last_negative =adc_negative;
|
|||
|
|
|||
|
if(dev_reg.threshold_value>=10 && abs(adc_positive)<dev_reg.threshold_value
|
|||
|
&& abs(adc_negative)<dev_reg.threshold_value)
|
|||
|
{
|
|||
|
dev_reg.adc_state = 0; //0是退
|
|||
|
}
|
|||
|
|
|||
|
adc_positive = dev_reg.adc_max; //上升沿赋值正值,下降沿赋值负值
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
|
|||
|
{
|
|||
|
if(GPIO_Pin == SDA_Pin)
|
|||
|
{
|
|||
|
if(HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin) == GPIO_PIN_RESET)
|
|||
|
{
|
|||
|
electric_flag = 0;
|
|||
|
}
|
|||
|
adc_negative = dev_reg.adc_max;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//计算电压值,每6秒钟调用一次
|
|||
|
void calculate_voltage(void)
|
|||
|
{
|
|||
|
static uint16_t last_count = 0,count =0;
|
|||
|
static int16_t last_adc = 0;
|
|||
|
static int8_t a = 0;
|
|||
|
|
|||
|
if(dev_reg.adc_state == 0)
|
|||
|
{
|
|||
|
dev_reg.voltage = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if(dev_reg.reference == 0) //0为默认处理方式,
|
|||
|
{
|
|||
|
count++;
|
|||
|
a = dev_reg.adc_max/abs(dev_reg.adc_max);
|
|||
|
dev_reg.voltage =a*110;
|
|||
|
if(count -last_count >= 5 ) //每6秒钟调用一次
|
|||
|
{
|
|||
|
if(abs(dev_reg.adc_max-last_adc) < 30 && count >= 30)
|
|||
|
{
|
|||
|
dev_reg.reference = dev_reg.adc_max;
|
|||
|
count =0;
|
|||
|
}
|
|||
|
last_count = count;
|
|||
|
last_adc = dev_reg.adc_max;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else if(dev_reg.reference == 1) //人为设置电压参考值为0时的处理
|
|||
|
{
|
|||
|
dev_reg.voltage =0;
|
|||
|
if(abs(dev_reg.adc_max-last_adc)>300 )
|
|||
|
{
|
|||
|
dev_reg.reference = 0;
|
|||
|
write_flash(write_reference,dev_reg.reference);
|
|||
|
|
|||
|
}
|
|||
|
last_adc = dev_reg.adc_max;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|