Revert "feat:提交0_10V温控继电器固件"

This reverts commit 1eb7209c0a.
This commit is contained in:
yeyangwen
2026-04-02 16:36:19 +08:00
parent 1eb7209c0a
commit c85dd5f6c1
1408 changed files with 0 additions and 188594 deletions

View File

@@ -1,608 +0,0 @@
#include "includes.h"
ZERO_CTRL_RLY c_rly;
void Relay_Init(void)
{
memset(&c_rly,0, sizeof(ZERO_CTRL_RLY));
EEPROM_Init();
GPT_IO_Init(GPT_CHB_PB00);
GPT_Configure(GPTCLK_EN,GPT_PCLK,GPT_IMMEDIATE,0);
GPT_WaveCtrl_Configure(GPT_INCREASE,GPT_SWSYNDIS,GPT_IDLE_LOW,GPT_PRDLD_PEND,GPT_OPM_CONTINUOUS,GPT_BURST_DIS,GPT_CKS_PCLK,GPT_CG_CHAX,GPT_CGFLT_00,GPT_PRDLD_ZERO);
GPT_Period_CMP_Write(10000,0,0);
GPT_WaveLoad_Configure(GPT_WAVEA_IMMEDIATE,GPT_WAVEB_SHADOW,GPT_AQLDA_ZERO,GPT_AQLDB_ZERO);
GPT_WaveOut_Configure(GPT_CHB,GPT_CASEL_CMPA,GPT_CBSEL_CMPA,2,0,1,1,0,0,0,0,0,0);
GPT_Start();
GPT_ConfigInterrupt_CMD(ENABLE,GPT_INT_PEND);
//真-继电器
GPIO_Init(GPIOA0,12,Output);
GPIO_Init(GPIOA0,13,Output);
RLY_1_CLOSE;
RLY_2_CLOSE;
c_rly.rly_control = 0x01; //继电器控制标志位
}
/*****************************************
* @brief 和校验
* @param data: 校验数据
* @param len: 数据长度
* @retval 和校验值
******************************************/
U8_T CheckSum(U8_T *data,U16_T len)
{
U16_T data_sum = 0;
for(U16_T i = 0;i<len;i++)
{
data_sum += data[i];
}
return data_sum;
}
U8_T CheckSum3(U8_T *data,U16_T len,U16_T n)
{
U16_T data_sum = 0;
for(U16_T i = 0;i<len;i++)
{
if(n != i){
data_sum += data[i];
}
}
return data_sum;
}
/*****************************************
* @brief 和校验取反
* @param data: 校验数据
* @param len: 数据长度
* @retval 和校验值
******************************************/
U8_T CheckSum_Check(U8_T *data,U16_T len)
{
U16_T data_sum = 0;
for(U16_T i = 0;i<len;i++)
{
data_sum += data[i];
}
return ~data_sum;
}
U8_T CheckSum_Overlook_Check(U8_T *data, U16_T len, U16_T check_id)
{
U8_T data_sum = 0;
for(U8_T i = 0;i<len;i++)
{
if(check_id != i) data_sum += data[i];
}
return ~data_sum;
}
//选择输出电压0 - 10000mV
U8_T Change_OUTV(U16_T VolOut)
{
if(VolOut > 10000) return 0x01;
GPT0->CMPA = VolOut;
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"CMPA:%d",VolOut);
#endif
return 0x00;
}
/********************************************************************
*@brief 由继电器状态判断当前风速输出PWM波
* @param
* @retval None
* */
void BLV_VolOut_Ctrl(void)
{
c_rly.wind = WIND_STOP;
if(c_rly.rly_state[WINDRLY_HIGH] == Control_ON) // 优先级高>中>抵 , 若同时被控制多个风速继电器,则将按照优先级打开继电器
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"WIND_HIGH");
#endif
c_rly.wind = WIND_HIGH;
//c_rly.rly_state[WINDRLY_MID] = Control_OFF;
//c_rly.rly_state[WINDRLY_LOW] = Control_OFF;
}else if(c_rly.rly_state[WINDRLY_MID] == Control_ON)
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"WIND_MID");
#endif
c_rly.wind = WIND_MID;
//c_rly.rly_state[WINDRLY_LOW] = Control_OFF;
}else if(c_rly.rly_state[WINDRLY_LOW] == Control_ON)
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"WIND_LOW");
#endif
c_rly.wind = WIND_LOW;
}
Dbg_Println(DBG_BIT_SYS_STATUS,"VolOut_Ctrl wind:%d",c_rly.wind);
if(c_rly.wind == WIND_STOP){
Change_OUTV(c_rly.wind_STOP_vol);
}else if(c_rly.wind == WIND_LOW){
Change_OUTV(c_rly.wind_LOW_vol);
}else if(c_rly.wind == WIND_MID){
Change_OUTV(c_rly.wind_MID_vol);
}else if(c_rly.wind == WIND_HIGH){
Change_OUTV(c_rly.wind_HIGH_vol);
}
}
/********************************************************************
*@brief 产生继电器控制,直接控制两个实体继电器状态
* @param rly_id:继电器id
* @param state继电器要改变的状态
* @retval None
* */
void BLV_RLY_Ctrl_Purpose(U8_T rly_id,U8_T state)
{
if(rly_id >= RLY_MAX) return;
switch(state)
{
case Control_ON:
if(c_rly.rly_state[rly_id] != Control_ON)
{
c_rly.rly_state[rly_id] = Control_ON;
if(rly_id == CTRL_RLY1){
RLY_1_OPEN;
}else if(rly_id == CTRL_RLY2){
RLY_2_OPEN;
}
}
break;
case Control_OFF:
if(c_rly.rly_state[rly_id] != Control_OFF)
{
c_rly.rly_state[rly_id] = Control_OFF;
if(rly_id == CTRL_RLY1){
RLY_1_CLOSE;
}else if(rly_id == CTRL_RLY2){
RLY_2_CLOSE;
}
}
break;
case Cnotrol_RES:
if(c_rly.rly_state[rly_id] != Control_OFF)
{
c_rly.rly_state[rly_id] = Control_OFF;
if(rly_id == CTRL_RLY1){
RLY_1_CLOSE;
}else if(rly_id == CTRL_RLY2){
RLY_2_CLOSE;
}
}else if(c_rly.rly_state[rly_id] != Control_ON)
{
c_rly.rly_state[rly_id] = Control_ON;
if(rly_id == CTRL_RLY1){
RLY_1_OPEN;
}else if(rly_id == CTRL_RLY2){
RLY_2_OPEN;
}
}
break;
}
}
//继电器动作处理
void BLV_RLY_Task(void)
{
if(c_rly.rly_control != 0x01)return;
for(U8_T i = 0;i<RLY_MAX;i++)
{
if(c_rly.rly_ctrl_state[i] == RLY_OFF)
{
BLV_RLY_Ctrl_Purpose(i,Control_OFF);
}
else if(c_rly.rly_ctrl_state[i] == RLY_ON)
{
BLV_RLY_Ctrl_Purpose(i,Control_ON);
}else if(c_rly.rly_ctrl_state[i] == RLY_RES)
{
BLV_RLY_Ctrl_Purpose(i,Cnotrol_RES);
}
c_rly.rly_ctrl_state[i] = NO_CTRL;
}
BLV_VolOut_Ctrl(); //风速判断输出pwm
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BLV_RLY_Task");
#endif
c_rly.rly_control = 0x00;
}
U8_T BLV_CMD_SN(U8_T sn)
{
U8_T rely_sn = (sn & 0x0f);
if(rely_sn <0x0F)
{
rely_sn += 1;
}else{
rely_sn = 0x00;
}
return rely_sn;
}
//1、主机下发设置继电器状态
U8_T BLV_A9RLY_CMD_SET_Processing(U8_T *data,U16_T len)
{
if(len < 9) return 0x01;
U8_T t = 0x00;
U8_T SendData[30];
U16_T SendLen = 0x00;
U16_T RLY_STATE = 0x00;
// if(len >= 9)
{
RLY_STATE =(data[SEND_PARA] + (data[SEND_PARA+1]<<8));
c_rly.rly_control = 0x01; //继电器控制标志
for(U8_T i = 0;i<RLY_MAX;i++)
{
t = ((RLY_STATE>>(2*i)) & 0x03);
if(t == NO_CTRL){
c_rly.rly_ctrl_state[i] = NO_CTRL; //默认状态,不用处理
}else if(t == RLY_OFF){
c_rly.rly_ctrl_state[i] = RLY_OFF;
}else if(t == RLY_ON){
c_rly.rly_ctrl_state[i] = RLY_ON;
}else if(t == RLY_RES){
c_rly.rly_ctrl_state[i] = RLY_RES;
}
}
}
//BLV_RLY_Task();
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN; //SN
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_SET_RLYSTATE_REPLY; //回复CMD
SendLen = 0x07;
SendData[SEND_LEN] = SendLen; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
return 0x00;
}
//2、读取继电器状态的回复
void BLV_A9RLY_CMD_READ_Processing(U8_T *data,U16_T len)
{
U8_T SendData[30];
U16_T SendLen = 0x00;
U8_T RLY_State2 = 0x00;
for(U8_T i = 0;i<RLY_MAX;i++)
{
if(c_rly.rly_state[i] == Control_ON)
{
RLY_State2 |= (0x01<<i);
}
}
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN;
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_READ_RLYSTATE_REPLY; //回复CMD
SendData[SendLen++] = RLY_State2;
SendData[SendLen++] = 0x00;
SendData[SendLen++] = 0x00;
SendLen = 0x0A;
SendData[SEND_LEN] = 0x0A; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
}
//3、设置各个风速档位的电压输出值
U8_T BLV_WINDOUT_CMD_SET_Processing(U8_T *data,U16_T len)
{
if(len < 15) return 0x01;
U8_T save_flag = 0x00;
U8_T SendData[30];
U16_T SendLen = 0x00;
U16_T SetVol = 0x00;
// if(len >= 15)
{
for(U8_T i = 0x00; i < 0x04; i++)
{
SetVol = (data[(SEND_PARA+(i*2))] + (data[(SEND_PARA+(i*2+1))]<<8 ));
if(SetVol <= 10000){
switch(i){
case 0x00:
if(c_rly.wind_STOP_vol != SetVol){
c_rly.wind_STOP_vol = SetVol;
save_flag++;
}
break;
case 0x01:
if(c_rly.wind_LOW_vol != SetVol){
c_rly.wind_LOW_vol = SetVol;
save_flag++;
}
break;
case 0x02:
if(c_rly.wind_MID_vol != SetVol){
c_rly.wind_MID_vol = SetVol;
save_flag++;
}
break;
case 0x03:
if(c_rly.wind_HIGH_vol != SetVol){
c_rly.wind_HIGH_vol = SetVol;
save_flag++;
}
break;
}
}
}
}
if(save_flag != 0x00)
{
EEPROM_WritePara(); //保存flash
}
BLV_VolOut_Ctrl();
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN;
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_SET_WINDOUTVOL_REPLY; //回复CMD
SendLen = 0x07;
SendData[SEND_LEN] = SendLen; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
return 0x00;
}
//4、读取各个风速档位的电压输出值
U8_T BLV_WINDOUT_CMD_READ_Processing(U8_T *data,U16_T len)
{
U8_T SendData[30];
U16_T SendLen = 0x00;
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN;
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_READ_WINDOUTVOL_REPLY; //回复CMD
SendData[SendLen++] = (c_rly.wind_STOP_vol & 0xFF);
SendData[SendLen++] = (c_rly.wind_STOP_vol >> 8) & 0xFF;
SendData[SendLen++] = (c_rly.wind_LOW_vol & 0xFF);
SendData[SendLen++] = (c_rly.wind_LOW_vol >> 8) & 0xFF;
SendData[SendLen++] = (c_rly.wind_MID_vol & 0xFF);
SendData[SendLen++] = (c_rly.wind_MID_vol >> 8) & 0xFF;
SendData[SendLen++] = (c_rly.wind_HIGH_vol & 0xFF);
SendData[SendLen++] = (c_rly.wind_HIGH_vol >> 8) & 0xFF;
SendLen = 0x0F;
SendData[SEND_LEN] = SendLen; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
return 0x00;
}
//5、设置端口模式
U8_T BLV_DEVPROT_CMD_SET_Processing(U8_T *data,U16_T len)
{
if(len != 0x08) return 0x01;
U8_T SendData[30];
U16_T SendLen = 0x00;
if((data[SEND_PARA] == ACTIVE_PORT)||((data[SEND_PARA] == POLLING_PORT)))
{
if(data[SEND_PARA] != c_rly.dev_port){
c_rly.dev_port = data[SEND_PARA];
EEPROM_WritePara(); //保存flash
}
}else{
return 0x02;//设置的端口不合法
}
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN;
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_SET_DEVPORT_REPLY; //回复CMD
SendLen = 0x07;
SendData[SEND_LEN] = SendLen; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
return 0x00;
}
//6、读取端口模式
U8_T BLV_DEVPROT_CMD_READ_Processing(U8_T *data,U16_T len)
{
U8_T SendData[30];
U16_T SendLen = 0x00;
c_rly.SN = (data[1]&0x0F);
//回复
SendData[SendLen++] = g_Dip.addr;
SendData[SendLen++] = c_rly.SN;
SendData[SendLen++] = data[2];
SendData[SendLen++] = data[0];
SendData[SendLen++] = 0x00; //len
SendData[SendLen++] = 0x00; //sum
SendData[SendLen++] = CMD_READ_DEVPORT_REPLY; //回复CMD
SendData[SendLen++] = c_rly.dev_port; //端口模式
SendData[SendLen++] = Project_FW_Version; //软件版本号
SendData[SendLen++] = Project_HW_Version; //硬件版本号
SendLen = 0x0A;
SendData[SEND_LEN] = SendLen; //len
SendData[SEND_SUM] = CheckSum_Check(SendData,SendLen);
Set_GroupSend(SendData,SendLen,1,BUSSend_WaitTime1,20); //组包
return 0x00;
}
U8_T BLV_RLY_RS485_Pro(U8_T *RecData, U16_T Len)
{
U8_T ret = 0x00;
if(Len < 0x07)
{
Dbg_Println(DBG_BIT_SYS_STATUS,"Data Len Err");
return 0x01;
}
if(RecData[4] != Len)
{
Dbg_Println(DBG_BIT_SYS_STATUS,"Len Check Err");
return 0x01;
}
if(RecData[2] != A9EXPANDTYPE) //A9继电器设备类型
{
Dbg_Println(DBG_BIT_SYS_STATUS,"Type Check Err");
return 0x02;
}
if(RecData[3] != g_Dip.addr) //地址校验
{
Dbg_Println(DBG_BIT_SYS_STATUS,"Addr Check Err ");
return 0x03;
}
if( CheckSum_Overlook_Check(RecData,Len,SEND_SUM) != RecData[SEND_SUM] ) //和校验
{
Dbg_Println(DBG_BIT_SYS_STATUS,"Sum Check Err: %02x,%02x",RecData[SEND_SUM],CheckSum_Overlook_Check(RecData,Len,SEND_SUM));
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"Sum Check Err: ",RecData,Len);
return 0x05;
}
if((RecData[SEND_SN]&0x0F) == c_rly.SN)
{
Dbg_Println(DBG_BIT_SYS_STATUS,"SN is Equal: %02x",c_rly.SN);
return 0x00;
}
switch(RecData[0x06])
{
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"BLV_RLY_RS485 CMD:%02x",RecData[0x06]);
#endif
case CMD_SET_RLYSTATE:
BLV_A9RLY_CMD_SET_Processing(RecData,Len);
break;
case CMD_READ_RLYSTATE:
BLV_A9RLY_CMD_READ_Processing(RecData,Len);
break;
case CMD_SET_WINDOUTVOL:
BLV_WINDOUT_CMD_SET_Processing(RecData,Len);
break;
case CMD_READ_WINDOUTVOL:
BLV_WINDOUT_CMD_READ_Processing(RecData,Len);
break;
case CMD_SET_DEVPORT:
BLV_DEVPROT_CMD_SET_Processing(RecData,Len);
break;
case CMD_READ_DEVPORT:
BLV_DEVPROT_CMD_READ_Processing(RecData,Len);
break;
}
}
void CTRL_LEDStatus_Task(void)
{
static U32_T Ctrl_LED_tick = 0x00;
if(SysTick_1ms - Ctrl_LED_tick >= 500)
{
Ctrl_LED_tick = SysTick_1ms;
REVERISE_STATUS;
}
}

View File

@@ -1,109 +0,0 @@
#include "includes.h"
DIP_t g_Dip;
void DIP_Switch_Init(void){
GPIO_Init(GPIOA0,10,Intput);
GPIO_Init(GPIOA0,9,Intput);
GPIO_Init(GPIOA0,8,Intput);
GPIO_PullHigh_Init(GPIOA0,10);
GPIO_PullHigh_Init(GPIOA0,9);
GPIO_PullHigh_Init(GPIOA0,8);
memset(&g_Dip,0,sizeof(DIP_t));
delay_nms(20);
/*上电读取拨码状态*/
for (U8_T i = 0; i < DIP_CHN_MAX; i++) {
if(DIP_GetSwitchState(i) == DIP_PRESS){
g_Dip.DIP_val |= DIP_VAL_ON << i;
}
}
g_Dip.DIP_last_val = g_Dip.DIP_val;
g_Dip.addr = ((g_Dip.DIP_val & 0x07)+20);
/*进入设置界面 - 先决条件*/
Dbg_Println(DBG_BIT_SYS_STATUS,"DIP Addr %d",g_Dip.addr);
}
U8_T DIP_GetSwitchState(U8_T i){
U8_T val = 0;
switch (i)
{
case DIP_CH1:
val = GPIO_Read_Status(GPIOA0,10);
break;
case DIP_CH2:
val = GPIO_Read_Status(GPIOA0,9);
break;
case DIP_CH3:
val = GPIO_Read_Status(GPIOA0,8);
break;
}
return val;
}
void DIP_ScanTask(void)
{
static U32_T update_20ms = 0;
if (SysTick_1ms - update_20ms > DIP_SCAN_Time)
{
update_20ms = SysTick_1ms;
for (U8_T i = 0; i < DIP_CHN_MAX; i++)
{
if (DIP_GetSwitchState(i) == DIP_PRESS)
{
g_Dip.delayCnt_OFF[i] = 0;
if (g_Dip.delayCnt_ON[i] < DIP_DELAY_COUNT)
{
g_Dip.delayCnt_ON[i]++;
}
else
{
g_Dip.DIP_val |= (DIP_VAL_ON << i);
g_Dip.delayCnt_ON[i] = 0;
}
}
else
{
g_Dip.delayCnt_ON[i] = 0;
if (g_Dip.delayCnt_OFF[i] < DIP_DELAY_COUNT)
{
g_Dip.delayCnt_OFF[i]++;
}
else
{
g_Dip.DIP_val &= ~(DIP_VAL_ON << i);
g_Dip.delayCnt_OFF[i] = 0;
}
}
}
}
if(g_Dip.DIP_val != g_Dip.DIP_last_val)
{
g_Dip.DIP_last_val = g_Dip.DIP_val;
/*拨码开关 - Bit0~Bit3设备地址*/
g_Dip.addr = ((g_Dip.DIP_val & 0x07)+20);
Dbg_Println(DBG_BIT_SYS_STATUS,"DIP Addr %d",g_Dip.addr);
}
}

View File

@@ -1,372 +0,0 @@
#include "includes.h"
E_MCU_DEV_INFO g_mcu_dev;
U8_T EEPROM_CheckSum(U8_T *data,U16_T len)
{
U8_T data_sum = 0;
for(U16_T i = 0;i<len;i++)
{
data_sum += data[i];
}
return data_sum;
}
void EEPROM_Init(void)
{
U8_T rev = 0;
EnIFCClk; //使能 IFC 时钟
IFC->MR |= 0x10002; //高速模式,延迟 2 个周期
EEPROM_ReadPara();
/*boot*/
memset(&g_mcu_dev,0,sizeof(E_MCU_DEV_INFO));
rev = EEPROM_ReadMCUDevInfo(&g_mcu_dev);
if(g_Dip.addr != g_mcu_dev.dev_addr){
g_mcu_dev.dev_addr = g_Dip.addr;
EEPROM_WriteMCUDevInfo(&g_mcu_dev);
}
if(rev == 0x00){
//读取成功,开始校验以下参数
EEPROM_Validate_MCUDevInfo(&g_mcu_dev);
}else{
//读取失败,恢复默认参数
EEPROM_Default_MCUDevInfo(&g_mcu_dev);
#if DBG_LOG_EN
SYSCON_IWDCNT_Reload();
Dbg_Println(DBG_BIT_SYS_STATUS,"EE Use Defalut Para");
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevBootVer:%d",g_mcu_dev.dev_boot_ver);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevNameLen:%d",g_mcu_dev.dev_name_len);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevName:%s",g_mcu_dev.dev_name);
#endif
}
}
/*******************************************************************************
* Function Name : EEPROM_ReadPara
* Description : 读取参数
* Parameter :
* info :读取参数指针
*******************************************************************************/
U8_T EEPROM_ReadPara(void)
{
U32_T temp_addr = EEPROM_PARA_SaveAddr;
U8_T read_info[10];
U8_T para_data[EEPROM_PARA_Size];
UINT16 read_len = 0;
memset(read_info,0,sizeof(read_info));
memset(para_data,0,sizeof(para_data));
ReadDataArry_U8(temp_addr,4,read_info);
if(read_info[0] == EEPROM_SAVE_Flag){
read_len = read_info[2];
read_len <<= 8;
read_len |= read_info[1];
if((read_len <= EEPROM_PARA_Size) && (read_len == 0x0A)){
temp_addr += EEPROM_Data_Offset;
ReadDataArry_U8(temp_addr,read_len,para_data);
if(CheckSum(para_data,read_len) == read_info[3]){
//校验成功 - 读取参数
c_rly.wind_STOP_vol = (para_data[0] + (para_data[1]<<8));
if(c_rly.wind_STOP_vol > 10000){
c_rly.wind_STOP_vol = EEPROM_WINDSTOP_OUT_Default;
}
c_rly.wind_LOW_vol = (para_data[2] + (para_data[3]<<8));
if(c_rly.wind_LOW_vol > 10000){
c_rly.wind_LOW_vol = EEPROM_WINDLOW_OUT_Default;
}
c_rly.wind_MID_vol = (para_data[4] + (para_data[5]<<8));
if(c_rly.wind_MID_vol > 10000){
c_rly.wind_MID_vol = EEPROM_WINDMID_OUT_Default;
}
c_rly.wind_HIGH_vol = (para_data[6] + (para_data[7]<<8));
if(c_rly.wind_HIGH_vol > 10000){
c_rly.wind_HIGH_vol = EEPROM_WINDHIGH_OUT_Default;
}
//设备端口模式
c_rly.dev_port = para_data[9];
if((c_rly.dev_port != ACTIVE_PORT)&&(c_rly.dev_port != POLLING_PORT))
{
c_rly.dev_port = POLLING_PORT;
}
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara wind_STOP_vol : %d",c_rly.wind_STOP_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara wind_LOW_vol : %d",c_rly.wind_LOW_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara wind_MID_vol : %d",c_rly.wind_MID_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara wind_HIGH_vol : %d",c_rly.wind_HIGH_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara dev_port : %d",c_rly.dev_port);
SYSCON_IWDCNT_Reload();
return 0x00;
}
}
}
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_ReadPara Default!");
//数据读取失败,使用默认参数
c_rly.wind_STOP_vol = EEPROM_WINDSTOP_OUT_Default;
c_rly.wind_LOW_vol = EEPROM_WINDLOW_OUT_Default;
c_rly.wind_MID_vol = EEPROM_WINDMID_OUT_Default;
c_rly.wind_HIGH_vol = EEPROM_WINDHIGH_OUT_Default;
c_rly.dev_port = POLLING_PORT;
SYSCON_IWDCNT_Reload();
Dbg_Println(DBG_BIT_SYS_STATUS,"wind_STOP_vol : %d",c_rly.wind_STOP_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"wind_LOW_vol : %d",c_rly.wind_LOW_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"wind_MID_vol : %d",c_rly.wind_MID_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"wind_HIGH_vol : %d",c_rly.wind_HIGH_vol);
Dbg_Println(DBG_BIT_SYS_STATUS,"dev_port : %d",c_rly.dev_port);
SYSCON_IWDCNT_Reload();
return 0x01;
}
/*******************************************************************************
* Function Name : EEPROM_ValidateWrite
* Description : 校验写入参数
*******************************************************************************/
U8_T EEPROM_ValidateWrite(U32_T Eeprom_Write_SaveAddr,U8_T* Write_Data,U16_T Write_Len){
U8_T Read_para[Write_Len];
U16_T i = 0;
memset(Read_para,0,sizeof(Read_para));
ReadDataArry_U8(Eeprom_Write_SaveAddr,Write_Len,Read_para);
for(i=0;i<Write_Len;i++){
if (Read_para[i]!=Write_Data[i]) {
return 0x01;
}
}
return 0x00;
}
/*******************************************************************************
* Function Name : EEPROM_WritePara
* Description : 保存参数
*******************************************************************************/
U8_T EEPROM_WritePara(void)
{
U32_T temp_addr = EEPROM_PARA_SaveAddr;
U8_T save_para[EEPROM_PARA_Size+10];
UINT16 save_len = 0x0A;
memset(save_para,0,sizeof(save_para));
if(save_len >= EEPROM_PARA_Size) save_len = EEPROM_PARA_Size;
save_para[0] = EEPROM_SAVE_Flag;
save_para[1] = save_len & 0xFF;
save_para[2] = (save_len >> 8) & 0xFF;
save_para[3] = 0x00;
save_para[4] = c_rly.wind_STOP_vol & 0xFF;
save_para[5] = (c_rly.wind_STOP_vol >> 8) & 0xFF;
save_para[6] = c_rly.wind_LOW_vol & 0xFF;
save_para[7] = (c_rly.wind_LOW_vol >> 8) & 0xFF;
save_para[8] = c_rly.wind_MID_vol & 0xFF;
save_para[9] = (c_rly.wind_MID_vol >> 8) & 0xFF;
save_para[10] = c_rly.wind_HIGH_vol & 0xFF;
save_para[11] = (c_rly.wind_HIGH_vol >> 8) & 0xFF;
save_para[12] = g_Dip.addr;
save_para[13] = c_rly.dev_port; //端口模式
save_para[3] = CheckSum(&save_para[4],save_len);
save_len += 4;
Page_ProgramData(temp_addr,save_len,save_para);
if(EEPROM_ValidateWrite(temp_addr,save_para,save_len)){
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_WritePara Save Para Err");
return 0x01;
}
Dbg_Println(DBG_BIT_SYS_STATUS,"EEPROM_WritePara Save Para");
return 0;
}
/****************************<------- boot ------ -->***************************************************/
/*******************************************************************************
* Function Name : EEPROM_ReadMCUDevInfo
* Description : 从EEPROM中读取设备信息
*******************************************************************************/
U8_T EEPROM_ReadMCUDevInfo(E_MCU_DEV_INFO *info)
{
U8_T read_info[6];
U8_T para_data[EEPROM_DATA_Size_Max];
U16_T read_len = 0;
memset(read_info,0,sizeof(read_info));
memset(para_data,0,sizeof(para_data));
ReadDataArry_U8(EEPROM_MCUDevInfo_Address,4,read_info);
if(read_info[0] == EEPROM_SVAE_FLAG){
read_len = read_info[2];
read_len <<= 8;
read_len |= read_info[1];
if(read_len <= EEPROM_DATA_Size_Max){
ReadDataArry_U8(EEPROM_MCUDevInfo_Address+EEPROM_Offset_Data,read_len,para_data);
if(EEPROM_CheckSum(para_data,sizeof(E_MCU_DEV_INFO)) == read_info[3]){
//校验成功
memcpy((uint8_t *)info,para_data,sizeof(E_MCU_DEV_INFO));
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevAddr:%d",g_mcu_dev.dev_addr);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevType:%d",g_mcu_dev.dev_type);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevBootVer:%d",g_mcu_dev.dev_boot_ver);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevAppVer:%d",g_mcu_dev.dev_app_ver);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevNameLen:%d",g_mcu_dev.dev_name_len);
Dbg_Println(DBG_BIT_SYS_STATUS,"EE DevName:%s",g_mcu_dev.dev_name);
#endif
return 0x00;
}
}
}
return 0x01;
}
/*******************************************************************************
* Function Name : EEPROM_WriteMCUDevInfo
* Description : 将设备信息写入到EEPROM中
*******************************************************************************/
U8_T EEPROM_WriteMCUDevInfo(E_MCU_DEV_INFO *info)
{
U8_T save_data[EEPROM_DATA_Size_Max + 6];
U16_T save_len = sizeof(E_MCU_DEV_INFO);
if(save_len >= EEPROM_DATA_Size_Max) save_len = EEPROM_DATA_Size_Max;
save_data[0] = EEPROM_SVAE_FLAG;
save_data[1] = save_len & 0xFF;
save_data[2] = (save_len >> 8) & 0xFF;
memcpy(&save_data[4],(uint8_t *)info,save_len);
save_data[3] = EEPROM_CheckSum(&save_data[4],save_len);
save_len+=4;
Page_ProgramData(EEPROM_MCUDevInfo_Address,save_len,save_data);
return 0;
}
/*******************************************************************************
* Function Name : EEPROM_Default_MCUDevInfo
* Description : EEPROM中参数恢复默认值且将默认参数保存至EEPROM中
*******************************************************************************/
void EEPROM_Default_MCUDevInfo(E_MCU_DEV_INFO *info)
{
#if (Project_Area == 0x01)
/*Boot 区域*/
info->dev_addr = 0x00;
info->dev_type = 0x00;
info->dev_app_ver = 0x00;
info->dev_boot_ver = Project_FW_Version;
info->dev_name_len = sizeof(Peoject_Name);
memset((char *)info->dev_name,0,EEPROM_DEV_NAME_Size);
memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);
EEPROM_WriteMCUDevInfo(info);
#elif (Project_Area == 0x02)
/*APP 区域*/
info->dev_addr = 0x00;
info->dev_type = Project_Type;
info->dev_app_ver = Project_FW_Version;
info->dev_name_len = sizeof(Peoject_Name);
memset((char *)info->dev_name,0,EEPROM_DEV_NAME_Size);
memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);
EEPROM_WriteMCUDevInfo(info);
#endif
}
/*******************************************************************************
* Function Name : EEPROM_Validate_MCUDevInfo
* Description : 校验从EEPROM 中读取的参数是否正确,如果不正确的话,便将当前正确的参数写入
APP区域中判断APP参数与EEPROM中记录的是否一致
Boot区域中判断Boot参数与EEPROM中记录的是否一致
*******************************************************************************/
void EEPROM_Validate_MCUDevInfo(E_MCU_DEV_INFO *info)
{
#if (Project_Area == 0x01)
/*Boot 区域*/
U8_T save_flag = 0;
if(info->dev_boot_ver != Project_FW_Version)
{
info->dev_boot_ver = Project_FW_Version;
save_flag = 0x01;
}
if(save_flag == 0x01)
{
EEPROM_WriteMCUDevInfo(info);
}
#elif (Project_Area == 0x02)
/*APP 区域*/
U8_T save_flag = 0;
if(info->dev_app_ver != Project_FW_Version)
{
info->dev_app_ver = Project_FW_Version;
save_flag = 0x01;
}
if(info->dev_type != Project_Type)
{
info->dev_type = Project_Type;
save_flag = 0x01;
}
if(info->dev_name_len != sizeof(Peoject_Name))
{
info->dev_name_len = sizeof(Peoject_Name);
save_flag = 0x01;
}
if(strncmp((char *)info->dev_name,(char *)Peoject_Name,sizeof(Peoject_Name)))
{
memcpy((char *)info->dev_name,(char *)Peoject_Name,info->dev_name_len);
save_flag = 0x01;
}
if(save_flag == 0x01)
{
EEPROM_WriteMCUDevInfo(info);
}
#endif
}

View File

@@ -1,107 +0,0 @@
#ifndef _RLY_CONTROL_H_
#define _RLY_CONTROL_H_
#include "apt32f102.h"
#include "apt32f102_gpio.h"
#define A9EXPANDTYPE 0x0E//14 //A9RELAY类型
#define CMD_SET_RLYSTATE 0x20 //设置继电器状态
#define CMD_READ_RLYSTATE 0x24 //读取继电器状态
#define CMD_SET_WINDOUTVOL 0x27 //设置各个档位的电压输出0-10000mV
#define CMD_READ_WINDOUTVOL 0x29 //读取各个档位的电压输出0-10000mV
#define CMD_SET_DEVPORT 0x28 //设置端口模式
#define CMD_READ_DEVPORT 0x2A //读取端口模式
#define CMD_SET_RLYSTATE_REPLY 0x30 //回复 -- 设置继电器状态
#define CMD_READ_RLYSTATE_REPLY 0x34 //回复 -- 读取继电器状态
#define CMD_SET_WINDOUTVOL_REPLY 0x37 //回复 -- 设置各个档位的电压输出0-10000mV
#define CMD_READ_WINDOUTVOL_REPLY 0x39 //回复 -- 读取各个档位的电压输出0-10000mV
#define CMD_SET_DEVPORT_REPLY 0x38 //回复 -- 设置端口模式
#define CMD_READ_DEVPORT_REPLY 0x3A //回复 -- 读取端口模式
#define RLY_1_OPEN GPIO_Write_High(GPIOA0,13);
#define RLY_1_CLOSE GPIO_Write_Low(GPIOA0,13);
#define RLY_2_OPEN GPIO_Write_High(GPIOA0,12);
#define RLY_2_CLOSE GPIO_Write_Low(GPIOA0,12);
#define WIND_LOW 0x01
#define WIND_MID 0x02
#define WIND_HIGH 0x03
#define WIND_STOP 0x00
#define Control_OFF 0x00 //继电器
#define Control_ON 0x01 //
#define Cnotrol_RES 0x02
#define ACTIVE_PORT 0x02 //主动端口
#define POLLING_PORT 0x01 //轮训端口
//继电器数量
typedef enum{
CTRL_RLY1 = 0x00,
CTRL_RLY2,
WINDRLY_LOW,
WINDRLY_MID,
WINDRLY_HIGH,
RLY_MAX,
}RLY_g;
//继电器控制状态
typedef enum{
NO_CTRL = 0x00, //继电器不控制
RLY_OFF, //继电器关闭
RLY_ON, //继电器打开
RLY_RES, //继电器翻转
}RLY_CTRL_g;
typedef enum{
SEND_ADDR1 = 0x00,
SEND_SN,
SEND_TYPE,
SEND_ADDR2,
SEND_LEN,
SEND_SUM,
SEND_CMD,
SEND_PARA,
}RECV_g;
typedef struct{
U8_T rly_control; //继电器控制标志位0x00不控制继电器0x01直接控制
U8_T rly_state[RLY_MAX]; //存储继电器状态Control_ONControl_OFF
U8_T rly_ctrl_state[RLY_MAX];
U8_T dev_port; //端口模式0x01,轮询0x02,主动
U8_T SN;
U8_T wind;
U8_T wind_last;
U16_T wind_STOP_vol;
U16_T wind_LOW_vol; //低风速电压记录,0-10000mV
U16_T wind_MID_vol;
U16_T wind_HIGH_vol;
}ZERO_CTRL_RLY;
extern ZERO_CTRL_RLY c_rly;
void Relay_Init(void);
void BLV_RLY_Ctrl_Purpose(U8_T rly_id,U8_T state);
U8_T CheckSum(U8_T *data,U16_T len);
U8_T CheckSum2(U8_T *data,U16_T len);
U8_T BLV_RLY_RS485_Pro(U8_T *RecData, U16_T Len);
void BLV_RLY_Task(void);
U8_T Change_OUTV(U16_T VolOut);
void CTRL_LEDStatus_Task(void);
#endif

View File

@@ -1,44 +0,0 @@
#ifndef _DIP_SWITCH_H_
#define _DIP_SWITCH_H_
#include "apt32f102.h"
#include "apt32f102_gpio.h"
#define DIP_PRESS 0x00 //按键按下为低
#define DIP_LOOSEN 0x01 //按键松开为高
#define DIP_DELAY_COUNT 5 //扫描次数
#define DIP_SCAN_Time 20 //每次扫描时间
typedef enum
{
DIP_CH1,
DIP_CH2,
DIP_CH3,
DIP_CHN_MAX,
}DIP_CHN_e;
typedef enum
{
DIP_VAL_OFF, //松开
DIP_VAL_ON, //按下
}DIP_VAL_e;
typedef struct
{
U8_T delayCnt_ON[DIP_CHN_MAX];
U8_T delayCnt_OFF[DIP_CHN_MAX];
U8_T addr; //2025-06-23
U32_T DIP_val;
U32_T DIP_last_val;
}DIP_t;
extern DIP_t g_Dip;
void DIP_Switch_Init(void);
uint8_t DIP_GetSwitchState(uint8_t i);
void DIP_ScanTask(void);
#endif

View File

@@ -1,72 +0,0 @@
#ifndef _EEPROM_H_
#define _EEPROM_H_
#include "includes.h"
#include "apt32f102.h"
/*地址范围0x10000000~0x100007FF*/
#define EEPROM_MCUDevInfo_Address 0x10000000 //MCU 设备信息地址固定为0x10000000大小为0x40 此区域不可改动
#define EEPROM_PARA_SaveAddr 0x10000100
#define EEPROM_TOUCHPARA1_SaveAddr 0x10000200
#define EEPROM_TOUCHPARA2_SaveAddr 0x10000280
#define EEPROM_TOUCHPARA3_SaveAddr 0x10000300
/* EEPROM 保存数据格式:
* FLAG - 1Byte 保存标志位
* LEN - 2Byte 保存数据长度
* CHECK - 1Byte 保存数据校验
* DATA - nByte 保存数据内容
*
* */
#define EEPROM_SAVE_Flag 0xA5 //EEPROM保存标志位
//#define EEPROM_PARA_Size 50
#define EEPROM_Data_Offset 0x04
/*boot*/
#define EEPROM_Offset_SaveFlag 0x00
#define EEPROM_Offset_Datalen 0x01
#define EEPROM_Offset_Check 0x03
#define EEPROM_Offset_Data 0x04
#define EEPROM_SVAE_FLAG 0xAE
#define EEPROM_DATA_Size_Max 0x40 //目前保存数据内容最长为100Byte
#define EEPROM_PARA_Size 50
#define EEPROM_DEV_NAME_Size 32
#define EEPROM_WINDSTOP_OUT_Default 0 //0-10000mV
#define EEPROM_WINDLOW_OUT_Default 3000 //
#define EEPROM_WINDMID_OUT_Default 6000 //
#define EEPROM_WINDHIGH_OUT_Default 10000 //
#define EEPROM_Device_Addr_Default 0x01 //设备初始地址
typedef struct{
U8_T dev_addr; //设备地址
U8_T dev_type; //设备类型
U8_T dev_boot_ver; //设备Boot的软件版本号
U8_T dev_app_ver; //设备APP的软件版本号
U8_T dev_name_len; //设备名称的长度
U8_T dev_name[EEPROM_DEV_NAME_Size]; //设备名称
}E_MCU_DEV_INFO;
extern E_MCU_DEV_INFO g_mcu_dev;
void EEPROM_Init(void);
U8_T EEPROM_ReadPara(void);
U8_T EEPROM_WritePara(void);
void EEPROM_TouchPara_Printf();
/*boot*/
U8_T EEPROM_ReadMCUDevInfo(E_MCU_DEV_INFO *info);
U8_T EEPROM_WriteMCUDevInfo(E_MCU_DEV_INFO *info);
void EEPROM_Default_MCUDevInfo(E_MCU_DEV_INFO *info);
void EEPROM_Validate_MCUDevInfo(E_MCU_DEV_INFO *info);
#endif

View File

@@ -1,175 +0,0 @@
#ifndef _UART_H_
#define _UART_H_
#include "apt32f102.h"
#include "apt32f102_uart.h"
#define Recv_2400_TimeOut 3 //ms
#define Recv_9600_TimeOut 3 //ms
#define Recv_115200_TimeOut 3 //ms
#define USART_BUFFER_NUM 3
#define USART_BUFFER_SIZE 70
#define USART_SEND_SIZE 128
#define UART_SEND_BUFFER_NUM 10
#define UART_SEND_BUFFER_SIZE 20
#define UART485_TX_PIN
#define UART485_RX_PIN 15 //PA0.15
#define UART485_DR_PIN 7 //PA0.7
#define READ_RX_LEVEL_STATE GPIO_Read_Status(GPIOA0,UART485_RX_PIN) //485总线RX引脚
#define WRITE_HIGH_DR GPIO_Write_High(GPIOA0,UART485_DR_PIN) //485 DR
#define WRITE_LOW_DR GPIO_Write_Low(GPIOA0,UART485_DR_PIN) //485 DR
#define REVERISE_DR GPIO_Reverse(GPIOA0,UART485_DR_PIN) //485 DR
#define LED_TX_PIN 0//PA0.0
#define LED_RX_PIN 1//PA0.1
#define LED_STATUS_PIN 4//PA0.4
#define TX_LED_ON GPIO_Write_Low(GPIOA0,LED_TX_PIN)
#define TX_LED_OFF GPIO_Write_High(GPIOA0,LED_TX_PIN)
#define RX_LED_ON GPIO_Write_Low(GPIOA0,LED_RX_PIN)
#define RX_LED_OFF GPIO_Write_High(GPIOA0,LED_RX_PIN)
#define STATUS_LED_ON GPIO_Write_Low(GPIOA0,LED_STATUS_PIN)
#define STATUS_LED_OFF GPIO_Write_High(GPIOA0,LED_STATUS_PIN)
#define REVERISE_STATUS GPIO_Reverse(GPIOA0,LED_STATUS_PIN)
#define UART_BUSBUSY 0x01 //总线繁忙
#define UART_BUSIDLE 0x00 //总线空闲
#define BUSSend_WaitTime1 300 //数据有效期:短按数据有效期
#define BUSSend_WaitTime2 3000 //数据有效期:
#define BUSSend_WaitTime3 60000 //数据有效期:
#define BUSSendCnt1 1 //点按数据上报次数
#define BUSSendCnt2 1//强电4弱电1 //长按按下数据上报次数
#define BUSSendCnt3 1//强电8弱电1 //长按松开数据上报次数
#define BUSSend_Tick 300 //数据发送间隔
/*调试信息相关定义*/
#ifndef DBG_LOG_EN
#define DBG_LOG_EN 0 //DEBUG LOG 输出总开关
#endif
/*调试信息初始状态*/
#define DBG_OPT_Debug_STATUS 0 //临时调试信息打印开关
#define DBG_OPT_DEVICE_STATUS 0 //设备驱动层打印调试信息打印开关
#define DBG_OPT_SYS_STATUS 1 //系统调试信息打印开关
/*调试信息输出控制位*/
#define DBG_BIT_Debug_STATUS 2
#define DBG_BIT_DEVICE_STATUS 1
#define DBG_BIT_SYS_STATUS 0
#if DBG_LOG_EN
#define DBG_SendByte(data) //UARTTxByte(UART2,data)
//#define DBG_Printf(data,len) UARTTransmit(UART2,data,len)
#define DBG_Printf(data,len) MCU485_SendData(data,len)
#else
#define DBG_SendByte(data)
#define DBG_Printf //MCU485_SendData(data,len)
#endif
typedef U8_T (*Uart_prt)(U8_T *,U16_T);
typedef enum
{
UART_0,
UART_1,
UART_2,
UART_3,
UART_MAX,
}UART_IDX;
typedef enum
{
BUSSEND_SUCC = 0x00, //等待发送机会
BUSSEND_WAIT, //发送成功
DATA_END, //数据有效期结束
RETRY_END, //重发结束
LEN_ERR, //长度错误
}BUSSEND_REV;
typedef struct{
U8_T RecvBuffer[USART_BUFFER_SIZE];
U8_T DealBuffer[USART_BUFFER_SIZE]; //数据处理缓冲
U8_T Receiving;
U16_T DealLen;
U16_T RecvLen;
U32_T RecvTimeout;
U32_T RecvIdleTiming;
Uart_prt processing_cf; //处理函数指针
}UART_t;
typedef struct{ //总线繁忙判断
U8_T SendBuffer[USART_SEND_SIZE]; //发送缓冲
U8_T BusState_Flag; //总线繁忙标记位, 0x01:总线繁忙0x00:总线空闲
U8_T HighBit_Flag; //串口RX高电平标记位,默认是高电平0x01.
U8_T BUSBUSY_LOCK; //锁定总线繁忙状态
U8_T SendState; //当前发送状态
U8_T ResendCnt; //当前发送次数
U8_T ASend_Flag; //主动上报发送标记
U8_T TotalCnt; //发送总次数
U8_T SetBaudFlag; //设置波特率
U8_T Jump_Flag; //跳转标志位
U16_T SendLen; //发送缓冲区数据长度
U32_T Bus_DelayTime; //总线繁忙转换到空闲状态的随机延时时间
U32_T DataWait_Time; //上报数据间隔
U32_T DataValid_Time; //上报数据有效期
U32_T BusState_Tick; //总线繁忙状态判断时间戳
U32_T ASend_Tick; //主动上报发送间隔判断时间戳
U32_T BusbusyTimeout; //上报数据有效期判断时间戳
}MULIT_t;
extern MULIT_t m_send;
extern UART_t g_uart;
extern U32_T Dbg_Switch;
extern volatile int RS485_Comm_Flag,RS485_Comm_Start,RS485_Comm_End,RS485_Comming;
void UARTx_Init(UART_IDX uart_id, Uart_prt prt_cf);
void UART0_RecvINT_Processing(char data);
void UART0_TASK(void);
void UART1_RecvINT_Processing(char data);
void UART1_TASK(void);
void UART2_RecvINT_Processing(char data);
void UART2_TASK(void);
void MCU485_SendData(U8_T *buff,U16_T len);
void Dbg_Print(int DbgOptBit, const char *cmd, ...);
void Dbg_Println(int DbgOptBit, const char *cmd, ...);
void Dbg_Print_Buff(int DbgOptBit, const char *cmd, U8_T *buff,U16_T len);
void BusIdle_Task(void);
void BusBusy_Task(void);
void BUS485Send_Task(void);
U8_T MultSend_Task(U8_T *buff,U16_T len,U8_T DatSd);
U8_T BUS485_Send(U8_T *buff,U16_T len);
void Set_GroupSend(U8_T *data,U16_T sled,U8_T SCnt,U32_T indate,U32_T tim_val);
void Clear_SendFlag(void);
void BUS485_Jump_Boot(U8_T jump);
#endif

View File

@@ -1,568 +0,0 @@
#include "includes.h"
#include <string.h>
#include <stdarg.h>
/**
* BLV_C8_PB 串口使用情况
* UART1 用与RCU进行双向通讯 115200 -> 对应设置 416
* UART0 用于PB数据发送没有接收 9600 -> 对应设置 5000
* */
UART_t g_uart; //空间不足,只能用一个串口
UART_t g_uart1; //空间不足,只能用一个串口
MULIT_t m_send;
void UARTx_Init(UART_IDX uart_id, Uart_prt prt_cf) {
switch((U8_T)uart_id){
case UART_0:
UART0_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART0,0); //use PA0.1->RXD0, PA0.0->TXD0
// UARTInit(UART0,5000,UART_PAR_NONE); //baudrate=sysclock 48M/1000=4800
UARTInitRxTxIntEn(UART0,5000,UART_PAR_NONE); //baudrate=sysclock 48M/1000=4800,tx rx int enabled
//UART0_Int_Enable();
break;
case UART_1:
memset(&g_uart1,0,sizeof(UART_t));
memset(&m_send,0,sizeof(MULIT_t));
g_uart1.RecvTimeout = Recv_9600_TimeOut;
g_uart1.processing_cf = prt_cf;
m_send.BusState_Tick = SysTick_1ms;
m_send.HighBit_Flag = 0x01;
//串口1-RX接收中断用于串口2的通讯总线繁忙状态判断2025-04-16
GPIO_PullHigh_Init(GPIOA0,15);
GPIO_IntGroup_Set(PA0,15,Selete_EXI_PIN15); //EXI0 set PB0.2
GPIOA0_EXI_Init(EXI15); //PB0.2 as input
EXTI_trigger_CMD(ENABLE,EXI_PIN15,_EXIFT); //ENABLE falling edge
EXTI_trigger_CMD(ENABLE,EXI_PIN15,_EXIRT);
EXTI_interrupt_CMD(ENABLE,EXI_PIN15); //enable EXI
GPIO_EXTI_interrupt(GPIOA0,0b1000000000000000); //enable GPIOB02 as EXI
EXI4_Int_Enable();
UART1_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART1,2); //use PA0.13->RXD1, PB0.0->TXD1
//UARTInit(UART1,416,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200
UARTInitRxTxIntEn(UART1,5000,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200 tx rx int enabled
UART1_Int_Enable();
GPIO_Init(GPIOA0,LED_TX_PIN,Output);
GPIO_Init(GPIOA0,LED_RX_PIN,Output);
GPIO_Init(GPIOA0,LED_STATUS_PIN,Output);
TX_LED_OFF;
RX_LED_OFF;
STATUS_LED_ON;
//485使能引脚初始化
GPIO_Init(GPIOA0,UART485_DR_PIN,Output);
GPIO_DriveStrength_EN(GPIOA0,UART485_DR_PIN);
WRITE_LOW_DR;
break;
case UART_2:
UART2_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART2,2); //use PB0.4->RXD1, PB0.5->TXD1
//UARTInit(UART2,416,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200
UARTInitRxTxIntEn(UART2,5000,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200 tx rx int enabled
//CSP_UART_SET_CTRL(UART2,UART_TX_DONE_INT);
UART2_Int_Enable();
// //485使能引脚初始化
// GPIO_Init(GPIOB0,3,Output);
// GPIO_DriveStrength_EN(GPIOB0,3);
// GPIO_Write_Low(GPIOB0,3);
break;
}
}
/*******************************************************************************
* Function Name : UART0_RecvINT_Processing
* Description : 串口0 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART0_RecvINT_Processing(char data){
if((g_uart.RecvLen + 1) >= USART_BUFFER_SIZE) g_uart.RecvLen = 0;
g_uart.RecvBuffer[g_uart.RecvLen++] = (U8_T)data;
g_uart.RecvIdleTiming = SysTick_1ms;
g_uart.Receiving = 0x01;
}
void UART0_TASK(void){
U8_T rev = 0xFF;
if(g_uart.Receiving == 0x01){
if(SysTick_1ms - g_uart.RecvIdleTiming > g_uart.RecvTimeout){
g_uart.RecvIdleTiming = SysTick_1ms;
Dbg_Println(DBG_BIT_SYS_STATUS, "UART0 recv Len %d", g_uart.RecvLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART0 buff",g_uart.RecvBuffer,g_uart.RecvLen);
if(g_uart.processing_cf != NULL){
rev = g_uart.processing_cf(g_uart.RecvBuffer,g_uart.RecvLen);
}
g_uart.RecvLen = 0;
g_uart.Receiving = 0;
}
}
}
/*******************************************************************************
* Function Name : UART1_RecvINT_Processing
* Description : 串口1 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART1_RecvINT_Processing(char data){
if((g_uart1.RecvLen + 1) >= USART_BUFFER_SIZE) g_uart1.RecvLen = 0;
g_uart1.RecvBuffer[g_uart1.RecvLen++] = (U8_T)data;
g_uart1.RecvIdleTiming = SysTick_1ms;
g_uart1.Receiving = 0x01;
RX_LED_ON;
}
void UART1_TASK(void){
U8_T rev = 0xFF;
if(g_uart1.Receiving == 0x01){
if(SysTick_1ms - g_uart1.RecvIdleTiming > g_uart1.RecvTimeout){
SYSCON_Int_Disable(); //2025-03-19,复制接收缓冲到数据处理缓冲内
g_uart1.RecvIdleTiming = SysTick_1ms;
memcpy(g_uart1.DealBuffer,g_uart1.RecvBuffer,g_uart1.RecvLen);
g_uart1.DealLen = g_uart1.RecvLen;
g_uart1.RecvLen = 0;
g_uart1.Receiving = 0;
SYSCON_Int_Enable();
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS, "UART1 recv Len %d", g_uart1.DealLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART1 buff",g_uart1.DealBuffer,g_uart1.DealLen);
#endif
if(g_uart1.processing_cf != NULL){
rev = g_uart1.processing_cf(g_uart1.DealBuffer,g_uart1.DealLen);
}
RX_LED_OFF;
memset(g_uart1.DealBuffer,0,USART_BUFFER_SIZE);
}
}
}
/*******************************************************************************
* Function Name : UART2_RecvINT_Processing
* Description : 串口2 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART2_RecvINT_Processing(char data){
if((g_uart.RecvLen + 1) >= USART_BUFFER_SIZE) g_uart.RecvLen = 0;
g_uart.RecvBuffer[g_uart.RecvLen++] = (U8_T)data;
g_uart.RecvIdleTiming = SysTick_1ms;
g_uart.Receiving = 0x01;
}
void UART2_TASK(void){
U8_T rev = 0xFF;
if(g_uart.Receiving == 0x01){
if(SysTick_1ms - g_uart.RecvIdleTiming > g_uart.RecvTimeout){
SYSCON_Int_Disable(); //2025-03-19,复制接收缓冲到数据处理缓冲内
g_uart.RecvIdleTiming = SysTick_1ms;
memcpy(g_uart.DealBuffer,g_uart.RecvBuffer,g_uart.RecvLen);
g_uart.DealLen = g_uart.RecvLen;
g_uart.RecvLen = 0;
g_uart.Receiving = 0;
SYSCON_Int_Enable();
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS, "UART2 recv Len %d", g_uart.DealLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART2 buff",g_uart.DealBuffer,g_uart.DealLen);
#endif
if(g_uart.processing_cf != NULL){
rev = g_uart.processing_cf(g_uart.DealBuffer,g_uart.DealLen);
}
memset(g_uart.DealBuffer,0,USART_BUFFER_SIZE);
}
}
}
/*因为开启了UART_TX_DONE_S 中断,发送完成需要清楚该中断标志位,因此每次调用串口输出后,需调用该函数,否则会在中断出不来
* 已取消
* */
void UART_Waiting_For_Send(CSP_UART_T *uart){
unsigned int Dataval = 0,delay_cnt = 0;
do{
Dataval = CSP_UART_GET_ISR(uart);
Dataval = Dataval & UART_TX_DONE_S;
delay_cnt ++;
if(delay_cnt >= 50000){
break;
}
}while(Dataval == 0x00); //发送完成
uart->ISR=UART_TX_DONE_S;
}
volatile int RS485_Comm_Flag = 0,RS485_Comm_Start = 0,RS485_Comm_End = 0,RS485_Comming = 0;
void MCU485_SendData(U8_T *buff,U16_T len){
unsigned int Dataval = 0,delay_cnt = 0;
//等待通讯发送完成
while(RS485_Comming == 0x01){
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
REVERISE_DR;//GPIO_Reverse(GPIOA0,7);
}
CK_CPU_DisAllNormalIrq();
WRITE_HIGH_DR; //GPIO_Write_High(GPIOA0,7);
RS485_Comm_Flag = 0x01;
RS485_Comm_Start = 0x00;
RS485_Comm_End = 0x00;
CK_CPU_EnAllNormalIrq();
UARTTransmit(UART1,buff,len);
do{
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
}while((RS485_Comm_Start < len) || (RS485_Comm_End < len)); //发送完成
CK_CPU_DisAllNormalIrq();
WRITE_LOW_DR; //GPIO_Write_Low(GPIOA0,7);
RS485_Comm_Flag = 0x00;
CK_CPU_EnAllNormalIrq();
}
/**********************************************************
* @brief 带总线状态判断的485发送
* buff:发送数据
* len数据长度
* @retval
* */
U8_T BUS485_Send(U8_T *buff,U16_T len)
{
unsigned int Dataval = 0,delay_cnt = 0;
//等待通讯发送完成
while(RS485_Comming == 0x01){
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
REVERISE_DR; //485_DR
}
if(m_send.BusState_Flag == UART_BUSIDLE){ //总线空闲
TX_LED_ON;
CK_CPU_DisAllNormalIrq();
WRITE_HIGH_DR; //485_DR
RS485_Comm_Flag = 0x01;
RS485_Comm_Start = 0x00;
RS485_Comm_End = 0x00;
m_send.BusState_Flag = UART_BUSBUSY;//发送前总线置位繁忙
m_send.BUSBUSY_LOCK = 0x01; //锁定总线状态
CK_CPU_EnAllNormalIrq();
UARTTransmit(UART1,buff,len);
do{
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
}while((RS485_Comm_Start < len) || (RS485_Comm_End < len)); //发送完成
CK_CPU_DisAllNormalIrq();
WRITE_LOW_DR; //485_DR
RS485_Comm_Flag = 0x00;
m_send.BusState_Tick = SysTick_1ms;
m_send.BUSBUSY_LOCK = 0x00; //解锁总线状态
CK_CPU_EnAllNormalIrq();
TX_LED_OFF;
return UART_BUSIDLE; //发送成功
}
else //总线繁忙
{
return UART_BUSBUSY; //发送失败
}
return 0x02; //传入状态无效
}
/**********************************************************
* @brief 重发、数据有效期、超时发送判断2025-03-25
* buff:发送数据
* len数据长度
* DatSd发送标记,0x00:无发送0x01有数据发送
*
* @retval 0x00:发送成功 0x01:等待发送 0x02:数据无效
* */
U8_T MultSend_Task(U8_T *buff,U16_T len,U8_T DatSd)
{
if( (len == 0)||(len > USART_SEND_SIZE) ) return LEN_ERR;
if(DatSd == 0x01)
{
if( m_send.ResendCnt < m_send.TotalCnt) //判断数据是否还在有效期,是否还有发送次数
{
if(SysTick_1ms - m_send.BusbusyTimeout < m_send.DataValid_Time)
{
if((m_send.ResendCnt == 0x00)||(SysTick_1ms - m_send.ASend_Tick >= m_send.DataWait_Time)){//数据发送间隔
if(BUS485_Send(buff,len) == UART_BUSIDLE){ //发送数据
m_send.ASend_Tick = SysTick_1ms;
m_send.ResendCnt++;
Dbg_Println(DBG_BIT_Debug_STATUS,"SendCnt:%d success",m_send.ResendCnt);
return BUSSEND_SUCC;//数据发送成功
}
}
}else{
Dbg_Println(DBG_BIT_Debug_STATUS,"data end");
return DATA_END;//数据有效期结束
}
}else{
Dbg_Println(DBG_BIT_Debug_STATUS,"retry end,%d",m_send.ResendCnt );
return RETRY_END;//没有重发次数
}
}
return BUSSEND_WAIT;//等待
}
/**********************************************************
* @brief 设置发送标志、组包、选择数据有效期档位2025-03-25
* data : 发送数据
* sled 数据长度
* SCnt : 设置数据发送次数
* indate 设置数据有效期
* tim_val : 发送时间间隔
* @retval None
* */
void Set_GroupSend(U8_T *data,U16_T sled,U8_T SCnt,U32_T indate,U32_T tim_val)
{
if((sled == 0x00)|| (sled > USART_SEND_SIZE)) return;
memset(m_send.SendBuffer,0, USART_SEND_SIZE);
memcpy(m_send.SendBuffer,data,sled);
m_send.SendLen = sled;
m_send.DataValid_Time = indate;//数据有效期
m_send.TotalCnt = SCnt; //数据发送次数
m_send.DataWait_Time = tim_val;//发送数据间隔
m_send.ASend_Flag = 0x01;
m_send.SendState = BUSSEND_WAIT;
m_send.ResendCnt = 0x00;
m_send.BusbusyTimeout = SysTick_1ms;
}
//清除发送标志
void Clear_SendFlag(void)
{
m_send.ASend_Flag = 0x00;
m_send.SendState = BUSSEND_SUCC;
}
void BUS485_Jump_Boot(U8_T jump)
{
m_send.Jump_Flag = jump;
}
//485发送任务
void BUS485Send_Task(void) //2025-03-29
{
//空闲等待
if(m_send.ASend_Flag == 0x01)
{
m_send.SendState = MultSend_Task(m_send.SendBuffer,m_send.SendLen,m_send.ASend_Flag);
if( (m_send.SendState == DATA_END)||(m_send.SendState == RETRY_END) )//判断发送数据是否有效
{
Dbg_Println(DBG_BIT_Debug_STATUS,"send end");
m_send.ASend_Flag = 0x00; //清除发送标志位
}
}
}
//获取当前BUS485 发送状态,获取完状态后清除当前状态
U8_T Get_BUS485_Send_State(void)
{
U8_T rev_state = 0x0F;
if(m_send.ASend_Flag == 0x01){
rev_state |= 0x80;
}
rev_state |= (m_send.SendState & 0x0F);
return rev_state;
}
/**********************************************************
* @brief 2025-03-25检测总线空闲在定时器中断里调用
* @retval None
* */
void BusIdle_Task(void)
{
if((m_send.BusState_Flag != UART_BUSIDLE)&&(m_send.BUSBUSY_LOCK != 0x01))
{
CK_CPU_DisAllNormalIrq();
if( (m_send.HighBit_Flag == 0x01)&&(SysTick_1ms - m_send.BusState_Tick >= (6 + m_send.Bus_DelayTime)) )
{
m_send.BusState_Flag = UART_BUSIDLE;
}
CK_CPU_EnAllNormalIrq();
}
}
/*******************************************************************
* @brief 检测总线繁忙在串口接收RX引脚的外部中断服务函数里调用
* @retval None
* */
void BusBusy_Task(void)
{
CK_CPU_DisAllNormalIrq();
m_send.BusState_Flag = UART_BUSBUSY;
m_send.BusState_Tick = SysTick_1ms;
m_send.Bus_DelayTime = (SysTick_1ms - m_send.ASend_Tick)%10;//随机延时
if(READ_RX_LEVEL_STATE == 0x01){
m_send.HighBit_Flag = 0x01; //高电平标志置位
}else if(READ_RX_LEVEL_STATE == 0x00){
m_send.HighBit_Flag = 0x00; //低电平
}
CK_CPU_EnAllNormalIrq();
}
/*调试信息输出接口*/
U32_T Dbg_Switch = (DBG_OPT_Debug_STATUS << DBG_BIT_Debug_STATUS)
+ (DBG_OPT_DEVICE_STATUS << DBG_BIT_DEVICE_STATUS)
+ (DBG_OPT_SYS_STATUS << DBG_BIT_SYS_STATUS);
#if DBG_LOG_EN
char Dbg_Buffer[150] = {0};
U32_T SysTick_Now = 0, SysTick_Last = 0, SysTick_Diff = 0;
#endif
void Dbg_Print(int DbgOptBit, const char *cmd, ...){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer),"%8d [%6d]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
va_list args; //定义一个va_list类型的变量用来储存单个参数
va_start(args, cmd); //使args指向可变参数的第一个参数
str_offset = vsnprintf(Dbg_Buffer, sizeof(Dbg_Buffer) ,cmd, args); //必须用vprintf等带V的
va_end(args); //结束可变参数的获取
DBG_Printf(Dbg_Buffer,str_offset);
}
#endif
}
void Dbg_Println(int DbgOptBit, const char *cmd, ...){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%8ld [%6ld]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
va_list args; //定义一个va_list类型的变量用来储存单个参数
va_start(args, cmd); //使args指向可变参数的第一个参数
str_offset = vsnprintf(Dbg_Buffer, sizeof(Dbg_Buffer) ,cmd, args); //必须用vprintf等带V的
va_end(args); //结束可变参数的获取
DBG_Printf(Dbg_Buffer,str_offset);
DBG_Printf("\r\n",2);
}
#endif
}
void Dbg_Print_Buff(int DbgOptBit, const char *cmd, U8_T *buff,U16_T len){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%8ld [%6ld]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
for (uint32_t i = 0; i < len; i++) {
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%02X ", buff[i]);
DBG_Printf(Dbg_Buffer,str_offset);
}
DBG_Printf("\r\n",2);
}
#endif
}