/********************************************************************************************************* * 模块名称: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" /********************************************************************************************************* * 宏定义 *********************************************************************************************************/ /********************************************************************************************************* * 枚举结构体 *********************************************************************************************************/ /********************************************************************************************************* * 内部变量定义 *********************************************************************************************************/ 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; #ifndef ACSingPhSmaDouble unsigned short int Devid_ChalNum = ACSingCurrid*256+RelaySlaveChaNum;//设备类型和通道数 #else unsigned short int Devid_ChalNum = ACSingCurrid*256+Relay_4_CHANEL; #endif //测试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_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}; //float hlw8110_store[RelaySlaveChaNum] = {0.0}; //uint8_t kwh_1s_read_flag = 0; ACDC_All_Chn_Consumption ACDC_Total_All_Chn_Read_Reg; ACDC_Over_Func_WriteReg ACDC_Over_WriteReg[RelaySlaveChaNum] = {0}; uint8_t over_Func_flag[RelaySlaveChaNum] = {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; 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 = 30; //设置每个通道的静态电流 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(uint8_t); uint8_t consumer_clear_flag = 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){ #ifndef ACSingPhSmaDouble for(int i = 0; i < RelaySlaveChaNum;i++) #else for(int i = 0; i < Relay_4_CHANEL;i++) #endif { 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 ACSingPhSmaCurr if(channel==0x00) //011 { gpio_bit_reset(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x01) //010 { gpio_bit_reset(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x02) //001 { gpio_bit_reset(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x03) //000 { gpio_bit_reset(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } #ifndef ACSingPhSmaDouble else if(channel==0x04) //111 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x05) //110 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x06) //101 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x07) //100 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } #endif #endif #if ACSingPhHigCurr if(channel==0x00) //100 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x01) //101 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x02) //110 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); } else if(channel==0x03) //111 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); } #endif Calculate_HLW8110_MeterData(); if((Start_Read_Flag)&&(channel==0x00)) //只有读完数据之后且现在轮询到通道0才会继续更新电压和频率值 { // 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);//实际的电压放大1000倍,实际的K,B值要缩小1000倍 // if(AC_Ele_ReadReg[0].AC_V <= 10000) //小于10V频率为0 // { // AC_Ele_ReadReg[0].AC_LINE_Freq=0; // AC_Ele_ReadReg[0].AC_V = 0; // } // else // { // AC_Ele_ReadReg[0].AC_LINE_Freq=F_AC_LINE_Freq*1000; // } // for(chal_num=1;chal_num=RelaySlaveChaNum) #else if(channel>=Relay_4_CHANEL) #endif channel=0; // Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2);//测试使用,看是否和电能计量芯片是否通信成功,成功串口接收到10 00 48 Clr100msFlag(); //清除100ms标志 } } /********************************************************************************************************* * 函数名称:InitHardware * 函数功能:所有的硬件相关的模块初始化函数都放在此函数中 * 输入参数:void * 输出参数:void * 返 回 值:void米皮米mimMMDAAADFADAdadafadfyang * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ static void InitHardware(void) { unsigned int i; SystemInit(); //系统初始化,函数里面默认是配置为内部晶振 // InitRCU(); //初始化RCC模块,使用外部晶振则需要打开此函数 ViewRcuClock(); //在线调试查看系统时钟频率 InitNVIC(); //初始化NVIC模块 #ifndef ACSingPhSmaDouble for(i=0;i=RelaySlaveChaNum) #else if(channel>=Relay_4_CHANEL) //这里直接初始化8次,匹配时间 #endif { channel=0; break; } #endif #if ACSingPhHigCurr if(channel==0x00) //100 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); Init_HLW8110(); } else if(channel==0x01) //101 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); Init_HLW8110(); } else if(channel==0x02) //110 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); Init_HLW8110(); } else if(channel==0x03) //111 { gpio_bit_set(SEL_2_RCU, SEL2); gpio_bit_set(XYEN_SEL0_1_RCU, SEL1); gpio_bit_set(XYEN_SEL0_1_RCU, SEL0); Init_HLW8110(); } channel++; // if(channel>=RelaySlaveChaNum) if(channel>=4) //这里直接初始化4次,匹配时间 { channel=0; break; } #endif } InitAT24Cxx(); //初始化24C64模块 // while(1) //测试eeprom是否通信正常 // { // for(buf_qua=0;buf_qua<=1024;buf_qua++) // { // AT24CxxWrite(buf_qua, pBuffer1, 1); // if(buf_qua==1024) // break; // } // } //读出EEPROM中的数据,然后开始依次按照设置打开继电器 ReadEeprom(); Delay_Ms_1 = 0; while(1) { eMBPoll(); Proc100msTask(); //100ms处理任务 //ProcTaskNew(); //Proc1SecTask(); //1s处理任务 // test1 = gpio_input_bit_get(LOCK_LE_CH_RCU,LOCK_CHECK); // if(test1) //如果有jlink接入,则不会动作继电器,直接跳出进入主函数 if((gpio_input_bit_get(LOCK_LE_CH_RCU,LOCK_CHECK))||(Jlink_Sta_Flag==0x01)) //如果有jlink接入,则不会动作继电器,直接跳出进入主函数 { //补上电平,让IO输出电平,有一个起始状态,但不会动作,锁存器起作用 #if ACSingPhSmaCurr Relay1State(); Relay2State(); Relay3State(); Relay4State(); Relay5State(); Relay6State(); Relay7State(); Relay8State(); #endif #if ACSingPhHigCurr Relay1State(); Relay2State(); Relay3State(); Relay4State(); #endif 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; } } } /********************************************************************************************************* * 函数名称:Proc20msTask_Start * 函数功能:2ms处理任务开机根据延时开启继电器 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:需要对应读取关系 *********************************************************************************************************/ static void Proc2msTask_Start(void) { if(Get2msFlag()) //判断2ms标志状态 { Delay_Ms_1 = Delay_Ms_1 +1; if(RelaySlaveChaNum==8) { 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; } 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; } 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; } 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; } #ifndef ACSingPhSmaDouble 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; } 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; } 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; } 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 } else if(RelaySlaveChaNum==7) { 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; } 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; } 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; } 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; } 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; } 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; } 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; } } else if(RelaySlaveChaNum==6) { 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; } 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; } 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; } 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; } 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; } 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; } } else if(RelaySlaveChaNum==5) { 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; } 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; } 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; } 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; } 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; } } else if(RelaySlaveChaNum==4) { 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; } 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; } 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; } 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; } } else if(RelaySlaveChaNum==3) { 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; } 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; } 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; } } else if(RelaySlaveChaNum==2) { 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; } 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; } } else if(RelaySlaveChaNum==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; } } #ifndef ACSingPhSmaDouble if((Sort_Onbuf[RelaySlaveChaNum-1]==Delay_Ms_1)||(Sort_Onbuf[RelaySlaveChaNum-1]==0xffff)||(Sort_Onbuf[RelaySlaveChaNum-1]==0)) //当达到最大延时时间后退出当前循环 #else if((Sort_Onbuf[Relay_4_CHANEL-1]==Delay_Ms_1)||(Sort_Onbuf[Relay_4_CHANEL-1]==0xffff)||(Sort_Onbuf[Relay_4_CHANEL-1]==0)) #endif Delay_End_flag = 1; //这里还需要排序,然后才能生效 Clr2msFlag(); //清除2ms标志 } } /********************************************************************************************************* * 函数名称:Proc1SecTask * 函数功能:1s处理任务 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:开启闪烁LED的功能 *********************************************************************************************************/ static void Proc1SecTask(void) { if(Get1SecFlag()) //判断1s标志状态 { LEDFlicker2(); Clr1SecFlag(); //清除1s标志 } } static void over_RelayState(uint8_t channel) { #ifdef ACSingPhSmaDouble if(over_Func_flag[channel]) { if(EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State==true) { switch(channel) { case 0: RELAY_1_OFF; RELAY_5_OFF; break; case 1: RELAY_2_OFF; RELAY_6_OFF; break; case 2: RELAY_3_OFF; RELAY_7_OFF; break; case 3: RELAY_4_OFF; RELAY_8_OFF; break; default: return; } EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State = false; EE_ACDC_State_ReadRegTrue[channel].ACDC_Cha_On_Off_State = false; }else { EE_ACDC_State_ReadRegTrue[channel].ACDC_Cha_On_Off_State = false; } over_Func_flag[channel] = 0; } #else if(over_Func_flag[channel]) { if(EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State==true) { switch(channel) { case 0: RELAY_1_OFF; break; case 1: RELAY_2_OFF; break; case 2: RELAY_3_OFF; break; case 3: RELAY_4_OFF; break; case 4: RELAY_5_OFF; break; case 5: RELAY_6_OFF; break; case 6: RELAY_7_OFF; break; case 7: RELAY_8_OFF; break; default: return; } EE_ACDC_State_ReadReg[channel].ACDC_Cha_On_Off_State = false; EE_ACDC_State_ReadRegTrue[channel].ACDC_Cha_On_Off_State = false; }else { EE_ACDC_State_ReadRegTrue[channel].ACDC_Cha_On_Off_State = false; } over_Func_flag[channel] = 0; } #endif BUFF; LOCK; } /********************************************************************************************************* * 函数名称:main * 函数功能:主函数 * 输入参数:void * 输出参数:void * 返 回 值:int * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ int main(void) { InitHardware(); //初始化硬件相关函数 // RelaySlaveAddress=ReadKeyValue(); //读取从机的地址 // InitSoftware(); //初始化软件相关函数 //InitWwdgt(); //最后初始化WWDGT模块 Fwdgt_Init(); //watch dog while(1) { eMBPoll(); Proc100msTask(); //100ms处理任务 //ProcTaskNew(); detection_value = get_detection(); check_channel_reset(); Proc1SecTask(); //1s处理任务 Fwdgt_reload(); if(write_2_minute_flag == 1) { write_2_minute_flag = 0; uint8_t buff[4*RelaySlaveChaNum] = {0}; // buff[0] = EE_ACDC_Total_Consum_Read_Reg.ACDC_Consumption >> 24; // buff[1] = EE_ACDC_Total_Consum_Read_Reg.ACDC_Consumption >> 16; // buff[2] = EE_ACDC_Total_Consum_Read_Reg.ACDC_Consumption >> 8; // buff[3] = EE_ACDC_Total_Consum_Read_Reg.ACDC_Consumption >> 0; #ifndef ACSingPhSmaDouble for(int i = 0 ; i < RelaySlaveChaNum;i++) #else for(int i = 0 ; i < Relay_4_CHANEL;i++) #endif { 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