/********************************************************************************************************* * 模块名称:Main.c * 摘 要:主文件,包含软硬件初始化函数和main函数 * 当前版本:1.0.0 * 作 者:Leyutek(COPYRIGHT 2018 - 2021 Leyutek. All rights reserved.) * 完成日期:2021年07月01日 * 内 容: * 注 意:注意勾选Options for Target 'Target1'->Code Generation->Use MicroLIB,否则printf无法使用 ********************************************************************************************************** * 取代版本: * 作 者: * 完成日期: * 修改内容: * 修改文件: *********************************************************************************************************/ /********************************************************************************************************* * 包含头文件 *********************************************************************************************************/ #include "Main.h" #include "gd32e230x_conf.h" #include "string.h" #include "NVIC.h" #include "SysTick.h" #include "Rcu.h" #include "Timer.h" #include "Led.h" #include "Key.h" #include "Relay.h" #include "Uart1.h" #include "mb.h" #include "Hlw8110.h" #include "Config.h" //#include "Wwdgt.h" #include "At24cxx.h" #include "I2c.h" #include "ReadEeprom.h" #include "Sn74lvc573.h" #include "Fwdgt.h" #include "key_io.h" /********************************************************************************************************* * 宏定义 *********************************************************************************************************/ /********************************************************************************************************* * 枚举结构体 *********************************************************************************************************/ /********************************************************************************************************* * 内部变量定义 *********************************************************************************************************/ static unsigned char RelaySlaveAddress=0x00; static unsigned int Uart0_Baud=115200; static unsigned char channel=0; unsigned long int Delay_Ms_1=0; static unsigned char Delay_End_flag=0; unsigned short int Devid_ChalNum = ACSingCurrid*256+RelaySlaveChaNum;//设备类型和通道数 //测试EEPROM使用 //static unsigned char pBuffer1[] = {0xff}; //static unsigned int buf_qua=0; //static unsigned char pBuffer2[] = "hello MCU!"; //static unsigned char pBuffer3[sizeof(pBuffer1)] = {}; ACDC_Delay_struct_WriteReg ACDC_Delay_WriteReg[RelaySlaveChaNum]; AC_Ele_struct_ReadReg AC_Ele_ReadReg[RelaySlaveChaNum]; ACDC_State_struct_WriteReg ACDC_State_WriteReg[RelaySlaveChaNum]; ACDC_ThresVal_struct_WriteReg ACDC_ThresVal_WriteReg[RelaySlaveChaNum]; ACDC_Coef_struct_WriteReg ACDC_Coef_WriteReg[RelaySlaveChaNum]; EE_ACDC_Delay_struct_ReadReg_On EE_ACDC_Delay_ReadReg_On[RelaySlaveChaNum]; EE_ACDC_Delay_struct_ReadReg_Off EE_ACDC_Delay_ReadReg_Off[RelaySlaveChaNum]; EE_ACDC_State_struct_ReadReg EE_ACDC_State_ReadReg[RelaySlaveChaNum]; EE_ACDC_State_struct_ReadRegTrue EE_ACDC_State_ReadRegTrue[RelaySlaveChaNum]; EE_ACDC_ThresVal_struct_ReadReg EE_ACDC_ThresVal_ReadReg[RelaySlaveChaNum]; EE_ACDC_Coef_struct_ReadReg EE_ACDC_Coef_ReadReg[RelaySlaveChaNum]; EE_ACDC_Total_Consumption EE_ACDC_Total_Consum_Read_Reg[RelaySlaveChaNum]; ACDC_Consumer_Clear EE_ACDC_Consumer_Clear[RelaySlaveChaNum] = {0}; ACDC_Over_Func_WriteReg ACDC_Over_WriteReg[RelaySlaveChaNum]; //float hlw8110_store[RelaySlaveChaNum] = {0.0}; //uint8_t kwh_1s_read_flag = 0; ACDC_All_Chn_Consumption ACDC_Total_All_Chn_Read_Reg; EE_ACDC_ThresVal_struct_ReadReg EE_ACDC_All_ThrVal; ACDC_Over_Func_WriteReg ACDC_Over_AllWriteReg; ACDC_Wann_Read_Reg_t ACDC_Wann_All = {0}; EE_ACDC_State_All_Reg_En_t EE_ACDC_State_All_en; AC_Ele_struct_ReadReg AC_Ele_ReadReg_All; uint8_t over_Func_flag[RelaySlaveChaNum] = {0}; uint8_t over_func_all_flag = 0; uint32_t read_Total_Consumer[RelaySlaveChaNum] = {0}; //uint32_t hlw8100_flash_backup[RelaySlaveChaNum] = {0}; //uint32_t Hlw8110_Flash_value[RelaySlaveChaNum] = {0}; float Hlw8110_Restore[RelaySlaveChaNum]={0.0}; uint32_t write_2_minute_flag = 0; //uint8_t read_kWh_flag = 0; uint16_t detection_value = 0; #if SUPPORT_SELF_LOCK uint8_t handle_k_1_status = 1; uint8_t handle_k_2_status = 1; uint8_t handle_k_3_status = 1; uint8_t handle_k_4_status = 1; bool key_1 = 0; bool key_2 = 0; bool key_3 = 0; bool key_4 = 0; #endif unsigned short int Sort_Onbuf[RelaySlaveChaNum]; unsigned short int Sort_Offbuf[RelaySlaveChaNum]; unsigned long int AC_V_Total; //交流电压总结果 unsigned long int AC_LINE_Freq_Total; //交流电流总结果 unsigned int Start_Read_Flag; //开始读取数据标志 unsigned char Jlink_Sta_Flag = 0; //Jlink 是否在线的标志位 unsigned int StaticCur = 50; //设置每个通道的静态电流 unsigned char No_Load[RelaySlaveChaNum]={0}; unsigned char test1; extern float F_AC_V; // 电压有效值 extern float F_AC_I; // A通道电流 extern float F_AC_P; // A通道有功功率 extern float F_AC_LINE_Freq; // 市电线性频率 extern float F_AC_E; // A通道有功电能(量) extern float F_AC_PF; // 功率因素,A通道和B通道只能选其一 /********************************************************************************************************* * 内部函数声明 *********************************************************************************************************/ static void InitSoftware(void); //初始化软件相关的模块 static void InitHardware(void); //初始化硬件相关的模块 static void Proc2msTask_Start(void); //2ms处理任务 static void Proc1SecTask(void); //1s处理任务 static void over_RelayState(void); static void over_RelayState_ch(uint8_t channel); static void all_over_RelayState(void); void switch_recode(); #if SUPPORT_SWITCH_REMENBER bool handle_status[RelaySlaveChaNum] = {0}; #if ((RelaySlaveChaNum == 6) || (SUPPORT_2_DETECTION && RelaySlaveChaNum == 8)) uint8_t handle_detection[2] = {1,1}; #else uint8_t handle_detection[1] = {1}; #endif #endif uint8_t consumer_clear_flag = 0; uint32_t all_val = 0; /********************************************************************************************************* * 内部函数实现 *********************************************************************************************************/ /********************************************************************************************************* * 函数名称:InitSoftware * 函数功能:所有的软件相关的模块初始化函数都放在此函数中 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ static void InitSoftware(void) { eMBInit(MB_RTU, RelaySlaveAddress, 0, Uart0_Baud, MB_PAR_NONE); // 初始化modbus为RTU方式,地址RelaySlaveAddress, 波特率Uart0_Baud,无校验 eMBEnable(); // 使能modbus协议栈 } void check_channel_reset() { if(consumer_clear_flag){ for(int i = 0; i < RelaySlaveChaNum;i++) { if(EE_ACDC_Consumer_Clear[i].flag) { if(EE_ACDC_Consumer_Clear[i].value) { int temp = i << 2; uint8_t buff[4] = {0}; //AT24CxxWrite(Eepr_AC_Sing_Total_Consumer_addr+temp, buff,4); read_Total_Consumer[i] = 0; Hlw8110_Restore[i] = 0.0; // channel_reset(i); EE_ACDC_Consumer_Clear[i].value = 0; } EE_ACDC_Consumer_Clear[i].flag = 0; } } consumer_clear_flag = 0; } } /********************************************************************************************************* * 函数名称:Proc100msTask * 函数功能:100ms处理任务 循环读取电能计量芯片的数据 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:进行通道之间的轮询读取数据 * 注 意:真值表 * XEN# YEN# SEL2 SEL1 SEL0 AX AY 串口通道 实际通道 channel RELAY RELAY * 0 0 0 0 0 选择A0X 选择A0Y TR4 4 3 4 * 0 0 0 0 1 选择A1X 选择A1Y TR3 3 2 3 * 0 0 0 1 0 选择A2X 选择A2Y TR2 2 1 2 * 0 0 0 1 1 选择A3X 选择A3Y RT1 1 0 1 靠电压互感器那边(8通道小电流) * 0 0 1 0 0 选择A4X 选择A4Y TR8 8 7 8 1 * 0 0 1 0 1 选择A5X 选择A5Y TR7 7 6 7 2 * 0 0 1 1 0 选择A6X 选择A6Y TR6 6 5 6 3 * 0 0 1 1 1 选择A7X 选择A7Y TR5 5 4 5 4靠电压互感器那边(4通道大电流) * 1 1 X X X 全部断开 全部断开 *********************************************************************************************************/ static void Proc100msTask(void) { unsigned int chal_num=0; if(Get100msFlag()) //判断100ms标志状态 { #if SUPPORT_TWIN_FIRE uint32_t voltage = 0; uint32_t current = 0; uint32_t power = 0; uint32_t consumer = 0; uint32_t fac = 0; uint32_t freq = 0; uint32_t data_v = 0; uint32_t data_i = 0; if((Start_Read_Flag)&&(channel==0x00)) //只有读完数据之后且现在轮询到通道0才会继续更新电压和频率值 { Start_Read_Flag = 0; } select_channel(channel); Calculate_HLW8110_MeterData(); data_v = (F_AC_V*EE_ACDC_Coef_ReadReg[channel].ACDC_V_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_V_b/1000); data_i = (F_AC_I*EE_ACDC_Coef_ReadReg[channel].ACDC_I_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_I_b/1000); voltage = data_v; current = data_i; power = F_AC_P*1000; freq = F_AC_LINE_Freq*1000; Hlw8110_Restore[channel] += F_AC_E; fac = F_AC_PF*1000; select_channel(channel + 4); Calculate_HLW8110_MeterData(); data_v = (F_AC_V*EE_ACDC_Coef_ReadReg[channel].ACDC_V_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_V_b/1000); data_i = (F_AC_I*EE_ACDC_Coef_ReadReg[channel].ACDC_I_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_I_b/1000); voltage = data_v > voltage ? data_v : voltage; current += data_i; power += (F_AC_P*1000); Hlw8110_Restore[channel] += F_AC_E; consumer = Hlw8110_Restore[channel]*1000 + read_Total_Consumer[channel]; fac = fac > (F_AC_PF*1000) ? fac : (F_AC_PF*1000); if(voltage <=1000) { current = 0; freq = 0; fac = 0; power = 0; } AC_Ele_ReadReg[channel].AC_V = voltage*(1.732); AC_Ele_ReadReg[channel].AC_I = current; AC_Ele_ReadReg[channel].AC_LINE_Freq = freq; AC_Ele_ReadReg[channel].AC_P = power; AC_Ele_ReadReg[channel].AC_PF =fac; AC_Ele_ReadReg[channel].AC_E = consumer; #else select_channel(channel); Calculate_HLW8110_MeterData(); //AC_Ele_ReadReg[0].AC_V=(F_AC_V*EE_ACDC_Coef_ReadReg[0].ACDC_V_k)+(EE_ACDC_Coef_ReadReg[0].ACDC_V_b/1000); if((Start_Read_Flag)&&(channel==0x00)) //只有读完数据之后且现在轮询到通道0才会继续更新电压和频率值 { Start_Read_Flag = 0; } AC_Ele_ReadReg[channel].AC_V=(F_AC_V*EE_ACDC_Coef_ReadReg[0].ACDC_V_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_V_b/1000);//实际的电压放大1000倍,实际的K,B值要缩小1000倍 AC_Ele_ReadReg_All.AC_V = AC_Ele_ReadReg[0].AC_V; if(AC_Ele_ReadReg[channel].AC_V <= 10000) //小于10V频率为0 { AC_Ele_ReadReg[channel].AC_LINE_Freq=0; AC_Ele_ReadReg[channel].AC_V = 0; } else { AC_Ele_ReadReg[channel].AC_LINE_Freq=F_AC_LINE_Freq*1000; } AC_Ele_ReadReg[channel].AC_I=(F_AC_I*EE_ACDC_Coef_ReadReg[channel].ACDC_I_k)+(EE_ACDC_Coef_ReadReg[channel].ACDC_I_b/1000);//实际的电流放大1000倍,实际的K,B值要缩小1000倍 if((AC_Ele_ReadReg[channel].AC_I)<=No_Load[channel]) { AC_Ele_ReadReg[channel].AC_I = 0; } if((AC_Ele_ReadReg[channel].AC_I)<=No_Load[channel]) AC_Ele_ReadReg[channel].AC_P=0; //有功功率 else AC_Ele_ReadReg[channel].AC_P=F_AC_P*1000; //有功功率 Hlw8110_Restore[channel] += F_AC_E; AC_Ele_ReadReg[channel].AC_E=(Hlw8110_Restore[channel]*1000 + read_Total_Consumer[channel]); //电能 AC_Ele_ReadReg[channel].AC_PF=F_AC_PF*1000; //功率因素 #endif // AC_Ele_ReadReg_All.AC_V = AC_Ele_ReadReg[0].AC_V; // AC_Ele_ReadReg_All.AC_I += AC_Ele_ReadReg[channel].AC_I; //all current // AC_Ele_ReadReg_All.AC_P += AC_Ele_ReadReg[channel].AC_P; // AC_Ele_ReadReg_All.AC_LINE_Freq = AC_Ele_ReadReg[0].AC_LINE_Freq; // AC_Ele_ReadReg_All.AC_PF= AC_Ele_ReadReg[channel].AC_PF; EE_ACDC_Total_Consum_Read_Reg[channel].ACDC_Consumption = AC_Ele_ReadReg[channel].AC_E; //total consumer // ACDC_Total_All_Chn_Read_Reg.ACDC_All_Consumption += EE_ACDC_Total_Consum_Read_Reg[channel].ACDC_Consumption; all_val += EE_ACDC_Total_Consum_Read_Reg[channel].ACDC_Consumption; // AC_Ele_ReadReg_All.AC_E += EE_ACDC_Total_Consum_Read_Reg[channel].ACDC_Consumption; WarnState_ch(channel); //更新状态寄存器的告警阈值 //over_RelayState(); over_RelayState_ch(channel); channel=channel+1; if(channel>=RelaySlaveChaNum){ // ACDC_Total_All_Chn_Read_Reg.ACDC_All_Consumption = all_val; // AC_Ele_ReadReg_All.AC_E = all_val; // all_val = 0; // jugement all // All_Warn_State(); // all_over_RelayState(); channel=0; // AC_Ele_ReadReg_All.AC_I = 0; //AC_Ele_ReadReg_All.AC_E = 0; // AC_Ele_ReadReg_All.AC_P = 0; } // Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2);//测试使用,看是否和电能计量芯片是否通信成功,成功串口接收到10 00 48 Clr100msFlag(); //清除100ms标志 } } void set_channel_status(uint8_t channel,uint8_t status) { if(status) { EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State = true; }else { EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State = false; } } /********************************************************************************************************* * 函数名称:InitHardware * 函数功能:所有的硬件相关的模块初始化函数都放在此函数中 * 输入参数:void * 输出参数:void * 返 回 值:void米皮米mimMMDAAADFADAdadafadfyang * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ static void InitHardware(void) { unsigned int i; //SystemInit(); //系统初始化,函数里面默认是配置为内部晶振 // InitRCU(); //初始化RCC模块,使用外部晶振则需要打开此函数 ViewRcuClock(); //在线调试查看系统时钟频率 InitNVIC(); //初始化NVIC模块 for(i=0;i=RelaySlaveChaNum){ channel=0; break; } } InitAT24Cxx(); //初始化24C64模块 #if SURPPORT_2_2 solid_on(); BUFF; LOCK; #endif ReadEeprom(); Delay_Ms_1 = 0; #if SUPPORT_DETECTION detection_value = get_detection(); #endif switch_recode(); #if SUPPORT_SELF_LOCK key_1 = get_key_io_1(); key_2 = get_key_io_2(); key_3 = get_key_io_3(); key_4 = get_key_io_4(); #if (RelaySlaveChaNum >= 1) if(key_1 == false) { handle_k_1_status = 0; set_channel_status(0,0); } #endif #if (RelaySlaveChaNum >= 2) if(key_2 == false) { handle_k_2_status = 0; set_channel_status(1,0); } #endif #if (RelaySlaveChaNum >= 3) if(key_3 == false) { handle_k_3_status = 0; set_channel_status(2,0); } #endif #if (RelaySlaveChaNum >= 4) if(key_4 == false) { handle_k_4_status = 0; set_channel_status(3,0); } #endif #endif while(1) { eMBPoll(); //Proc100msTask(); //100ms处理任务 //Proc1SecTask(); //1s处理任务 // if((gpio_input_bit_get(LOCK_LE_CH_RCU,LOCK_CHECK))||(Jlink_Sta_Flag==0x01)) //如果有jlink接入,则不会动作继电器,直接跳出进入主函数 // { // //补上电平,让IO输出电平,有一个起始状态,但不会动作,锁存器起作用 // RelayState(); // Delay_Ms_1 = 0; // Delay_End_flag = 0; // Jlink_Sta_Flag = 0; // timer_disable(TIMER14); // break; // } Proc2msTask_Start(); //2ms处理任务完成后才初始化modbus。 if(Delay_End_flag) { timer_disable(TIMER14); Delay_Ms_1 = 0; Delay_End_flag = 0; break; } } } void switch_recode() { #if SUPPORT_DETECTION #if SUPPORT_SWITCH_REMENBER #if ((RelaySlaveChaNum == 6) || ((RelaySlaveChaNum == 8) && SUPPORT_2_DETECTION)) if((detection_value & 1) == 0) { if(handle_detection[0] == 1) { for(uint8_t k = 0; k < (RelaySlaveChaNum/2);k++) handle_status[k] = EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State; } handle_detection[0] = 0; for(uint8_t k = 0; k < (RelaySlaveChaNum/2);k++) EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State=false; for(uint8_t k = 0; k < (RelaySlaveChaNum/2);k++) RelayState_ch(k); }else { if(handle_detection[0] == 0) { handle_detection[0] = 1; for(uint8_t k = 0; k < (RelaySlaveChaNum/2);k++) EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State=handle_status[k]; for(uint8_t k = 0; k < (RelaySlaveChaNum/2);k++) RelayState_ch(k); } } if((detection_value & 2) == 0) { if(handle_detection[1] == 1) { for(uint8_t k = (RelaySlaveChaNum/2); k < RelaySlaveChaNum;k++) handle_status[k] = EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State; } handle_detection[1] = 0; for(uint8_t k = (RelaySlaveChaNum/2); k < RelaySlaveChaNum;k++) EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State=false; for(uint8_t k = (RelaySlaveChaNum/2); k < RelaySlaveChaNum;k++) RelayState_ch(k); }else { if(handle_detection[1] == 0) { handle_detection[1] = 1; for(uint8_t k = (RelaySlaveChaNum/2); k < RelaySlaveChaNum;k++) EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State=handle_status[k]; for(uint8_t k = (RelaySlaveChaNum/2); k < RelaySlaveChaNum;k++) RelayState_ch(k); } } #elif (SUPPORT_TWIN_FIRE) if((detection_value & 0x3) != 0x3) { if(handle_detection[0] == 1) { for(int i = 0;i < RelaySlaveChaNum;i++) handle_status[i] = EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State; } handle_detection[0] = 0; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_Off_State=true; for(int i = 0;i < RelaySlaveChaNum;i++) EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = false; RelayState(); }else { if(handle_detection[0] == 0) { handle_detection[0] = 1; for(int i = 0;i < RelaySlaveChaNum;i++) EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State=handle_status[i]; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_On_State=true; All_On_Flag = 1; //全开标志置1 All_Off_Flag = 0; Delay_Ms_2 = 0; timer_enable(TIMER14); //RelayState(); } } #else if(detection_value == 0) { if(handle_detection[0] == 1) { for(int i = 0;i < RelaySlaveChaNum;i++) handle_status[i] = EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State; } handle_detection[0] = 0; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_Off_State=true; for(int i = 0;i < RelaySlaveChaNum;i++) EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = false; RelayState(); }else { if(handle_detection[0] == 0) { handle_detection[0] = 1; for(int i = 0;i < RelaySlaveChaNum;i++) EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State=handle_status[i]; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_On_State=true; All_On_Flag = 1; //全开标志置1 All_Off_Flag = 0; Delay_Ms_2 = 0; timer_enable(TIMER14); //RelayState(); } } #endif #else #if (RelaySlaveChaNum == 6 || ((RelaySlaveChaNum == 8) && SUPPORT_2_DETECTION)) if((detection_value & 1) == 0) { for(int i = 0; i < (RelaySlaveChaNum)/2;i++) { set_channel_status(i,0); } RelayState(); } if((detection_value & 2) == 0) { for(int i = (RelaySlaveChaNum)/2; i < RelaySlaveChaNum;i++) { set_channel_status(i,0); } RelayState(); } #elif (SUPPORT_TWIN_FIRE) if((detection_value & 0x3) != 0x3) { for(int i = 0; i < (RelaySlaveChaNum)/2;i++) { set_channel_status(i,0); } RelayState(); } #else if(detection_value == 0) { for(int i = 0; i < RelaySlaveChaNum;i++) { set_channel_status(i,0); } RelayState(); } #endif #endif #endif } /********************************************************************************************************* * 函数名称:Proc20msTask_Start * 函数功能:2ms处理任务开机根据延时开启继电器 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:需要对应读取关系 *********************************************************************************************************/ static void Proc2msTask_Start(void) { if(Get2msFlag()) //判断2ms标志状态 { #if SUPPORT_DETECTION if(detection_value == 0) { Delay_End_flag = 1; Clr2msFlag(); return; } //#if ((RelaySlaveChaNum == 6) || ((RelaySlaveChaNum == 8) && SUPPORT_2_DETECTION)) // if((detection_value & 0x1) == 0) // { // uint8_t k = 0; // for(k=0;k <(RelaySlaveChaNum)/2;k++) // EE_ACDC_State_ReadReg[k].ACDC_Cha_On_Off_State = false; // } // if((detection_value & 0x2) == 0) // { // uint8_t k = 0; // for(k=(RelaySlaveChaNum)/2;k = 1) if((EE_ACDC_Delay_ReadReg_On[0].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[0].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[0].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay1State(); LOCK; } #endif #if (RelaySlaveChaNum >= 2) if((EE_ACDC_Delay_ReadReg_On[1].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[1].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[1].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay2State(); LOCK; } #endif #if (RelaySlaveChaNum >= 3) if((EE_ACDC_Delay_ReadReg_On[2].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[2].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[2].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay3State(); LOCK; } #endif #if (RelaySlaveChaNum >= 4) if((EE_ACDC_Delay_ReadReg_On[3].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[3].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[3].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay4State(); LOCK; } #endif #if (RelaySlaveChaNum >= 5) if((EE_ACDC_Delay_ReadReg_On[4].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[4].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[4].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay5State(); LOCK; } #endif #if (RelaySlaveChaNum >= 6) if((EE_ACDC_Delay_ReadReg_On[5].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[5].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[5].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay6State(); LOCK; } #endif #if (RelaySlaveChaNum >= 7) if((EE_ACDC_Delay_ReadReg_On[6].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[6].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[6].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay7State(); LOCK; } #endif #if (RelaySlaveChaNum >= 8) if((EE_ACDC_Delay_ReadReg_On[7].ACDC_Delay==Delay_Ms_1)||(EE_ACDC_Delay_ReadReg_On[7].ACDC_Delay==0xffff)||(EE_ACDC_Delay_ReadReg_On[7].ACDC_Delay==0))//确保这里的和读取电能参数的顺序是一致的 { BUFF; Relay8State(); LOCK; } #endif if((Sort_Onbuf[RelaySlaveChaNum-1]==Delay_Ms_1)||(Sort_Onbuf[RelaySlaveChaNum-1]==0xffff)||(Sort_Onbuf[RelaySlaveChaNum-1]==0)) //当达到最大延时时间后退出当前循环 Delay_End_flag = 1; //这里还需要排序,然后才能生效 Clr2msFlag(); //清除2ms标志 } } /********************************************************************************************************* * 函数名称:Proc1SecTask * 函数功能:1s处理任务 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:开启闪烁LED的功能 *********************************************************************************************************/ static void Proc1SecTask(void) { //detection_value = get_detection(); if(Get1SecFlag()) //判断1s标志状态 { LEDFlicker2(); Clr1SecFlag(); //清除1s标志 #if SUPPORT_DETECTION detection_value = get_detection(); #endif #if SUPPORT_SELF_LOCK key_1 = get_key_io_1(); key_2 = get_key_io_2(); key_3 = get_key_io_3(); key_4 = get_key_io_4(); #endif } } static void all_over_RelayState(void) { //all if(over_func_all_flag) { for(int i = 0 ; i < RelaySlaveChaNum;i++) set_channel_status(i,0); RelayState(); } return; } static void over_RelayState(void) { for(int i = 0; i < RelaySlaveChaNum;i++) { if(over_Func_flag[i]) { set_channel_status(i,0); RelayState_ch(i); over_Func_flag[i] = 0; } } } static void over_RelayState_ch(uint8_t channel) { if(over_Func_flag[channel]) { set_channel_status(channel,0); RelayState_ch(channel); over_Func_flag[channel] = 0; } } #if SUPPORT_ALL_ON_OFF void check_or_controll_all() { bool rst = false; bool test = false; rst = get_rst(); test = get_test(); if(detection_value != 0) { if(rst != test) { uint8_t buff[20]= {0}; timer_disable(TIMER14); if(rst) { // while(All_On_Flag == 1) // DelayNms(5); All_Off_Flag = 1; //全关标志置1 All_On_Flag = 0; Delay_Ms_2 = 0; EE_ACDC_State_ReadReg[0].ACDC_Cha_On_Off_State=false; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_Off_State=true; for(int i =0; i < RelaySlaveChaNum;i++){ EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = false; } } else { // while(All_Off_Flag == 1) // DelayNms(5); All_Off_Flag =0; All_On_Flag = 1; //全关标志置1 EE_ACDC_State_ReadReg[0].ACDC_Cha_On_Off_State=true; EE_ACDC_State_ReadReg[0].ACDC_ALLCha_On_State=true; for(int i =0; i < RelaySlaveChaNum;i++) EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = true; Delay_Ms_2 = 0; } memcpy(&buff,&EE_ACDC_State_ReadReg,RelaySlaveChaNum*2); AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr,buff,RelaySlaveChaNum*2); timer_enable(TIMER14); } }else { for(int i =0; i < RelaySlaveChaNum;i++){ EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = false; set_channel_status(i,0); } RelayState(); } } #endif #if SUPPORT_SELF_LOCK void sub_control() { if(detection_value == 0) //all close { for(int i = 0; i < RelaySlaveChaNum;i++){ EE_ACDC_State_ReadReg[i].ACDC_Cha_On_Off_State = false; set_channel_status(i,0); } RelayState(); if(key_1 == false) { handle_k_1_status = 0; } if(key_2 == false) { handle_k_2_status = 0; } if(key_3 == false) { handle_k_3_status = 0; } if(key_4 == false) { handle_k_4_status = 0; } }else { #if (RelaySlaveChaNum >= 1) if(key_1 == false) //not in line { if(handle_k_1_status == 1) { set_channel_status(0,0); Relay1State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr,(uint8_t*)&(EE_ACDC_State_ReadReg[0]),2); handle_k_1_status = 0; } }else { if(handle_k_1_status == 0) { handle_k_1_status = 1; set_channel_status(0,1); Relay1State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr,(uint8_t*)&(EE_ACDC_State_ReadReg[0]),2); } } #endif #if (RelaySlaveChaNum >= 2) if(key_2 == false) { if(handle_k_2_status == 1) { set_channel_status(1,0); Relay2State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+2,(uint8_t*)&(EE_ACDC_State_ReadReg[1]),2); handle_k_2_status = 0; } }else { if(handle_k_2_status == 0) { handle_k_2_status = 1; set_channel_status(1,1); Relay2State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+2,(uint8_t*)&(EE_ACDC_State_ReadReg[1]),2); } } #endif #if (RelaySlaveChaNum >= 3) if(key_3 == false) { if(handle_k_3_status == 1) { set_channel_status(2,0); Relay3State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+4,(uint8_t*)&(EE_ACDC_State_ReadReg[2]),2); handle_k_3_status = 0; } }else { if(handle_k_3_status == 0) { handle_k_3_status = 1; set_channel_status(2,1); Relay3State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+4,(uint8_t*)&(EE_ACDC_State_ReadReg[2]),2); } } #endif #if (RelaySlaveChaNum >= 4) if(key_4 == false) { if(handle_k_4_status == 1) { set_channel_status(3,0); Relay4State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+6,(uint8_t*)&(EE_ACDC_State_ReadReg[3]),2); } handle_k_4_status = 0; }else { if(handle_k_4_status == 0) { handle_k_4_status = 1; set_channel_status(3,1); Relay4State(); BUFF; LOCK; AT24CxxWrite(Eepr_AC_Sing_State_SmaWAddr+6,(uint8_t*)&(EE_ACDC_State_ReadReg[3]),2); } } #endif } } #endif /********************************************************************************************************* * 函数名称:main * 函数功能:主函数 * 输入参数:void * 输出参数:void * 返 回 值:int * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ int main(void) { InitHardware(); //初始化硬件相关函数 Fwdgt_Init(); //watch dog while(1) { eMBPoll(); Proc100msTask(); //100ms处理任务 check_channel_reset(); Proc1SecTask(); //1s处理任务 Fwdgt_reload(); switch_recode(); #if SUPPORT_ALL_ON_OFF check_or_controll_all(); #endif #if SUPPORT_SELF_LOCK sub_control(); #endif if(write_2_minute_flag == 1) { write_2_minute_flag = 0; uint8_t buff[4*RelaySlaveChaNum] = {0}; for(int i = 0 ; i < RelaySlaveChaNum;i++) { int temp = i << 2; buff[temp + 0] = EE_ACDC_Total_Consum_Read_Reg[i].ACDC_Consumption >> 24; buff[temp + 1] = EE_ACDC_Total_Consum_Read_Reg[i].ACDC_Consumption >> 16; buff[temp + 2] = EE_ACDC_Total_Consum_Read_Reg[i].ACDC_Consumption >> 8; buff[temp + 3] = EE_ACDC_Total_Consum_Read_Reg[i].ACDC_Consumption >> 0; } AT24CxxWrite(Eepr_AC_Sing_Total_Consumer_addr, buff,4*RelaySlaveChaNum); } } } /*freemodbus作者使用了assert,故增加如下代码,同时 *options for target 对话框,target页面,勾选Use MicroLib */ #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #else void __aeabi_assert(const char * x1, const char * x2, int x3) { (void)x3; } #endif