546 lines
12 KiB
C
546 lines
12 KiB
C
/**
|
|
******************************************************************************
|
|
* @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
|
|
}
|
|
}
|
|
|