/** ****************************************************************************** * @file main.c * @author BMS * @version V1.0.0 * @date 20-5-2022 * @brief Main program body. ****************************************************************************** * @attention * * Copyright (c) 2011 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "global.h" #include "rtc.h" #include "soe.h" /** @addtogroup STM32F10x_StdPeriph_Examples * @{ */ /** @addtogroup GPIO_IOToggle * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** * @brief Main program. * @param None * @retval None */ int main(void) { #if Key_PressLong POWER_Check(); #endif delay_ms(1000); //上电之后加1S延时,防止WK唤醒误动 //SCB->VTOR = FLASH_BASE | 0x1800; uf_GPIO_Init(); uf_EXTI_Init(); uf_TIM3_Init(); //10MS uf_I2C1_Init(); uf_SPI2_Init(); uf_CAN1_Init(); uf_ADC_Init(); uf_IWDG_Init(7,1250); //分频数=7,重载值=1250,溢出时间=((4*2^7)*1250)/40=16000ms=16s #if Key_PressLong LED_ALL_ON(); //按钮长按模式,需要先灭再常亮 #endif uf_FLASH_Init(); uf_GLOBAL_Init(); /*三选一模块*/ #if BLE_Conn BLE_Init(); //蓝牙初始化 BLE_IO_Init(); BLE_Open(); #endif #if WIFI_Conn WIFI_Init(); //WIFI初始化 WIFI_IO_Init(); WIFI_Open(); #endif #if LTE_Conn LTE_4G_Init(); //4G初始化 LTE_4G_IO_Init(); LTE_4G_Open(); #endif // BAL_Off(); //默认关闭外置主动均衡(钰泰) MODBUS_Init(); MODBUS1_Init(); AFE_VoltageProcess(); InitGasGauge(); MCU_TemperaProcess(); MODBUS_Poll_Init(); Screen_Init(); //[陶晶驰] if(uf_RTC_Init()==1) //RTC时钟初始化,超时说明晶振有问题 { LSEErrFlag=1; sleep_Moni_Count=SLEEP_MON_CNT; } else { RTC_Get(); } while (1) { //5*10ms if(TIMER_IsOut(tmrTemp[0],5)) { tmrTemp[0] = TIMER_Update(); /*三选一模块:蓝牙*/ #if BLE_Conn BLE_IQ_Update(); //更新数据 BLE_IQ_Transmit(); //发送数据,每0.05s执行一次 #endif } //10*10ms if(TIMER_IsOut(tmrTemp[1],10)) { tmrTemp[1] = TIMER_Update(); /*三选一模块:WIFI*/ #if WIFI_Conn WIFI_IQ_Update(); //更新数据 WIFI_IQ_Transmit(); //发送数据,每0.1s执行一次 #endif } //25*10ms if(TIMER_IsOut(tmrTemp[2],25)) { tmrTemp[2] = TIMER_Update(); AFE_CurrentProcess(); //1s读4次电流后取平均值 #if Key_PressLong if(OFF_confirm_flg == 1) //若确认关机,此时把所有灯灭掉,提醒松开就会关机 { LED_ALL_OFF(); } else if(RST_confirm_flg == 1) //若按键摁下执行复位,灯被接管闪烁 { LED_RST_Toggle(); } else if(ON_confirm_flg != 0) //虚地址运行灯快速闪烁 { if(sleep_flag == 0) { if(curLimitFlag == 0) { if(bmsMem.E2_485Addr > AddrMax) { LED_RUN_Toggle(); } } } } #endif /*三选一模块:4G*/ #if LTE_Conn if((LTE_WarmDelay == 0) && (LTE_ResendDelay == 0) && (LTE_WaitRxDelay == 0) && (LTE_PinRST_Flag == 0) && (LTE_sleep_flag == 0)) //不在等候+不在引脚重启+不在休眠 { if(MQTT_READY_flag == 0) //未通信MQTT { if(LTE_LINK_flag == 1) { LTE_4G_IQ_Update(); //更新数据 LTE_4G_IQ_Transmit(); //发送数据,每0.25s执行一次 } } else //已通信MQTT { if((pre_sleep_flag == 4) || (LTE_status == event_pub) || (LTE_status == srvc_pub) || (LTE_status == setPara_pub) || (LTE_status == getPara_pub)) { LTE_4G_IQ_Update(); //更新数据 LTE_4G_IQ_Transmit(); //发送数据,每0.25s执行一次 } else if(LTE_OTA_Flag == 1) { LTE_OTA_IQ_Update(); //更新数据 LTE_OTA_IQ_Transmit(); //发送数据,每0.25s执行一次 } } } #endif } CALI_CurrentProcess(); //收到校准指令后进行更新,并回复 //50*10ms if(TIMER_IsOut(tmrTemp[3],50)) { tmrTemp[3] = TIMER_Update(); //LED 运行灯 #if Key_PressLong if((ON_confirm_flg != 0) && (RST_confirm_flg != 1) && (OFF_confirm_flg != 1)) #endif { if(sleep_flag == 0) { if(curLimitFlag == 0) { if((bmsMem.E2_485Addr >= 1) && (bmsMem.E2_485Addr <= AddrMax)) { LED_RUN_Toggle(); //正常地址运行灯正常闪烁 } } else { LED_RUN_On(); //限流常亮灯 } } else { LED_RUN_Off(); //休眠不亮灯 } } //LED报警灯 #if Key_PressLong if((ON_confirm_flg != 0) && (RST_confirm_flg != 1) && (OFF_confirm_flg != 1)) #endif { if((bAlarmFlag == 0) && (((bmsMem.bStatus2 & 0x00e0) ==0) && ((bmsMem.temperaStatus & 0x0040) ==0))) //无保护 { if(((bmsMem.bStatus2 & 0xff00) != 0) || ((bmsMem.bStatus3 & 0x3A00) != 0) || ((bmsMem.temperaStatus & 0xf000) != 0)) //有报警(除了单体过压告警和总体过压告警) { if(sleep_flag == 0) LED_ALARM_Toggle(); else LED_ALARM_Off(); } else if((bmsMem.bStatus3 & 0x0500) != 0) //单体过压告警和总体过压告警 { if(bmsMem.soc<99) //在正常工作时,发生[过压保护],正常显示 { if(sleep_flag == 0) LED_ALARM_Toggle(); else LED_ALARM_Off(); } else { LED_ALARM_Off(); } } } } //主机轮询从机 #if Key_PressLong if(OFF_confirm_flg != 1) #endif { if(sleep_flag == 0) //休眠时,主从通信禁用 //确认关机后,停止通信 { //主机在3.4口向下通讯 if((bmsMem.E2_485Addr == 1) && (paraMem.PACK_NUM >= 2) && (PollStop_flag == 0)) { #if Addr_SetAuto //开机后地址可能从1变2,先等待2s if((paraMem.addr_FREE_Flg == 0) && (assignAddr_relay > 0)) { assignAddr_relay--; } else if((paraMem.addr_FREE_Flg == 0) && ((assignAddr_State == 0) || (assignAddr_State == 1))) { MODBUS_AddrAssign_Tx(); //(主机自动分配从机地址,结束了再进行下一操作) } else if((paraMem.addr_FREE_Flg == 0) && ((assignAddr_State == 2) && (assignAddr_WrIndex_Flg == 1))) { assignAddr_WrIndex_Flg = 0; MODBUS_WrIndex_Tx(); //主机广播队列标志数 } else #endif { if(sdwa_WrAddr_Flg == 1)//(主机屏幕写从机地址,结束了再进行下一操作) { MODBUS_Screen_WrSlaveAddr_Tx(); } else if((ConfigData_Index>=2) && (ConfigData_Index<=paraMem.PACK_NUM)) { MODBUS_Config_RdSlave_Tx();//(上位机持续读单一从机,上位机比屏幕优先级高) } else if((scr_RdData_Index>=2) && (scr_RdData_Index<=paraMem.PACK_NUM)) { MODBUS_Screen_RdSlave_Tx();//(屏幕持续读单一从机) } else { MODBUS_MASTER_Polling_Tx();//(轮询,是默认状态) } } } //主机暂停轮询在收不到之后的30s恢复 else if(PollStop_flag == 1) { PollStop_count++; if(PollStop_count > 30) { PollStop_count = 0; PollStop_flag = 0; } } } } } //100*10ms if(TIMER_IsOut(tmrTemp[4],100)) { tmrTemp[4] = TIMER_Update(); AFE_VoltageProcess(); AFE_TemperaProcess(); MCU_TemperaProcess(); AFE_ProtectProcess(); IWDG_Feed(); //程序运行正常,进行喂狗 #if Key_PressLong POWER_Ctrl(); #endif #if Key_PressLong if(OFF_confirm_flg == 1) { CTRL_Off(); //关闭充放MOS delay_ms(2); CHG_LIMIT_Off(); //关闭限流 curLimitFlag = 0; delay_ms(2); PCHG_Off(); //关闭预充 TSC_detectFlag = 0; PCHG_startFlag = 0; PCHG_Flag = 0; delay_ms(2); // BAL_Off(); //关闭均衡 // balancing = 0; } else #endif { // MCU_BalanceProcess(); CHG_LIMIT_Ctrl(); if(TSC_detectFlag == 1) { TSC_Detect(); //充接口开路或短路检测,开路检测 } else if(PCHG_startFlag == 0) { PCHG_StartCtrl(); //启动预充(约1s检测开短路) } else if(MOS_Close_Flg == 0) { AFE_Ctrl(); //正常(开放电MOS前开预充,并检测真短路) } } OCV_CaliSOC(); ParaChange(); GaugeManage(); canMem_refresh(); onlineMem_refresh(); #if Key_PressLong if(OFF_confirm_flg != 1) #endif { //当屏亮,而上位机在通过主机看从机,屏幕查看地址返回原值 if(ConfigData_Index != 1) { scr_RdData_Index = bmsMem.E2_485Addr; } //更新屏幕信息(息屏由[陶晶驰]自己做) if(sleep_flag == 0) Screen_IQ_Transmit(); //每1s更新1次屏幕数据 } //逆变器协议数据更新 if(bmsMem.E2_485Addr == 1) { #if Key_PressLong if(OFF_confirm_flg != 1) #endif { if(sleep_flag == 0) CAN_UpdateData(); if(sleep_flag == 0) MODBUS1_UpdateData(); } } if(LSEErrFlag!=1) { uf_RTC_Update(); //写时间或需要等待长时间,可能返回1,所以就不用这里来判断晶振了 RTC_Get(); //时间更新每1s执行1次,若时钟持续10次都不走,可以认为晶振有问题 } /*三选一模块:4G*/ #if LTE_Conn Check_eventChange(); //因为要加上时间,所以放在读时间后面 //开机等待or引脚重启等待 if(LTE_WarmDelay > 0) { LTE_WarmDelay--; } //延迟下次发送等待 else if(LTE_ResendDelay > 0) { LTE_ResendDelay--; } else if(LTE_WaitRxDelay > 0) { LTE_WaitRxDelay--; } //引脚重启 else if(LTE_PinRST_Flag != 0) { if(LTE_PinRST_Flag == 1) { LTE_PinRST_Flag = 2; LTE_4G_Close(); } else { LTE_PinRST_Flag = 0; LTE_4G_Init(); LTE_4G_Open(); } } //休眠 else if(LTE_sleep_flag != 0) { if(LTE_sleep_flag == 1) //1:准备休眠 { LTE_sleep_flag = 2; //2:正在休眠 LTE_4G_Close(); //关闭4G模块 } else if(LTE_sleep_flag == 0xAA) //0xAA:退出休眠,执行1次开机4G模块 { LTE_sleep_flag = 0; LTE_4G_Init(); LTE_4G_Open(); //启动4G模块 pre_sleep_flag = 0xA0; //上线后,上报退出休眠事件 sleepOff_time=timecount; } } //正常通信or休眠前置步骤 else { //休眠前置步骤执行倒计时 if((pre_sleep_flag >=2) && (pre_sleep_flag <= 5)) { pre_sleep_waitCnt++; if(pre_sleep_waitCnt > 60) { pre_sleep_waitCnt = 0; pre_sleep_flag = 0; LTE_sleep_flag = 1; //1min内前置一直卡住,直接执行休眠 } } else { pre_sleep_waitCnt = 0; } if(MQTT_READY_flag == 0) //未通信MQTT { if(LTE_LINK_flag == 0) { LTE_4G_IQ_Update(); //更新数据 LTE_4G_IQ_Transmit(); //发送数据,每1s执行一次 } } else //已通信MQTT { if((pre_sleep_flag != 4) && (LTE_OTA_Flag != 1) && (LTE_status != event_pub) && (LTE_status != srvc_pub) && (LTE_status != setPara_pub) && (LTE_status != getPara_pub)) { LTE_4G_IQ_Update(); //更新数据 LTE_4G_IQ_Transmit(); //发送数据,每1s执行一次 } } } #endif } //需要及时响应的动作,直接放入while主循环里 Addr_Set(); //地址写入 RTC_BackUp(); //因各种情况触发的时间备份 //屏幕接收 #if Key_PressLong if(OFF_confirm_flg != 1) { if(Screen_RevHandlerFlg == 1) { Screen_RevHandlerFlg = 0; Screen_IT_Update(); } } else { SCR_KeepLight0(); //判断关机时收到数据屏幕也不能维持灯0 } #else if(Screen_RevHandlerFlg == 1) { Screen_RevHandlerFlg = 0; Screen_IT_Update(); } #endif //485发送回复 #if Key_PressLong if(OFF_confirm_flg != 1) MODBUS_IQ_Transmit(); if(OFF_confirm_flg != 1) MODBUS1_IQ_Transmit(); #else MODBUS_IQ_Transmit(); MODBUS1_IQ_Transmit(); #endif } }