//*************************************************************************************************** // Ver 1.0 // 2021.11.19 1、新建文件。 // 2、BQ76940调试完成。 // 2、通信协议待测试。 // 3、充电协议待调试。 // 2021.11.20 4、EEPROM驱动调试,R69/10K贴错成100K,WP引脚未连接到IO // 2021.11.22 5、EEPROM数据保存接口调试。 // 2021.11.23 6、调试串口协议。发现问题D6贴反。 // 2021.12.03 7、ALARM log数据保存功能完成,待测试。 // 8、均衡时间和低电压统计功能完成,待测试。 // 2021.12.29 9、更改协议的CRC算法为XMODEM。 // Ver 2.0 // 2022.01.19 10、增加调试信息部分读取数据指令。 // 2022.03.23 11、增加短路SWDIO到地进入测试模式,禁止休眠。 // 2022.03.28 12、增加关闭LDO后打开LED,加速余电的放电过程。 // Ver 3.0 // 2022.04.08 13、修正0x5指令返回的状态标志字节、警告标志4字节问题。 // Ver 4.0 // 2022.04.15 14、修改5V打开延时10秒关闭。 // Ver 5.0 // 2022.05.24 15、增加5V检测,5V关闭后,延迟2秒关闭MOS。 // 2022.06.02 16、增加开机、充电器插入后,清除5V检测标志,解决不能打开MOS的问题。 // Ver 6.0 // 2022.06.24 17、读取CTRL2寄存器数据,由CC_EN位判定是否按FLASH初值初始化寄存器 // 18、增加PWR5V存储到FLASH选项,根据FLASH存储的值来输出5V。 // Ver 7.0 // 2022.07.06 19、硬件版本变更为3,增加2次保护状态检测,充电MOS、放电MOS状态检测 // 20、WP驱动IO调整到P50。 // 21、增加二次保护信号输出检测。 // 22、增加充、放电MOS控制信号输出检测,及相关标志。 // 23、增加工厂模式,默认为打开充、放电MOS,不休眠,用于生产测试。 // 24、增加控制指令,切换工厂模式和用户模式。 // 2022.07.14 25、增加灯板按键关机退出工厂模式、测试模式。 // Ver 8.0 // 2022.07.16 26、修改过放电压为2.8V。 // 27、校准电流升级为32位数,修正校准电流不能大于32A问题。 // Ver 9.0 // 2022.07.28 26、修改状态标志和警告标志的设置、清除条件。 // 2022.08.03 27、修正时间戳计算。 // 28、修正警告信息存储顺序与协议文档对应上。 // Ver 10.0 // 2022.08.18 29、修正读取警告标志为0问题。 // 2022.08.19 30、修正充电器连接状态,清除充电温度标志。 // 31、去掉开机、关机记录条目。 // 2022.08.26 32、增加清除警告标志指令。 // 33、设置指令统一返回成功或不成功,不返回具体内容。 //*************************************************************************************************** #include "config.h" TASK_TYPE TASK_Sleep(void) { TASK_Start(); //RTC_BeiJinTimeToTimestamp(); WDT_Clr(); BATT_Sleep(); LED_D1On(); TASK_WaitX(101); //等待100ms LED_D1Off(); TASK_WaitX(901); //等待900ms TASK_End(); } TASK_TYPE TASK_Led(void) { TASK_Start(); //LED_Display(); //LED刷新 ADC_Conversion(); TASK_WaitX(11); //等待11ms TASK_End(); } TASK_TYPE TASK_Key(void) { TASK_Start(); KEY_Read(); TASK_WaitX(19); //等待20ms TASK_End(); } TASK_TYPE TASK_Afe(void) { TASK_Start(); BATT_ReadInfo(); //读取信息 BATT_AlarmCheck(); //电池警告检测 TASK_WaitX(101); //等待21ms TASK_End(); } TASK_TYPE TASK_Charger(void) { TASK_Start(); //CHARGER_Link(); //充电器连接 TASK_WaitX(501); //等待21ms TASK_End(); } TASK_TYPE TASK_Balance(void) { TASK_Start(); BATT_Balance(); BATT_StorageDischarge(); TASK_WaitX(5001); //等待1000ms if (BATT_FLAG_INIT == 0) { BATT_FLAG_INIT = 1; } TASK_End(); } TASK_TYPE TASK_Uart(void) { TASK_Start(); SCP_Process(UART0); TASK_WaitX(31); //等待100ms TASK_End(); } TASK_TYPE TASK_100mS(void) { TASK_Start(); BATT_SleepCount(); //休眠计数 BATT_P5vCount(); //5V延时关闭计数 SOC_CC(); //电量计算 LED_OnCount(); BATT_PFetCount(); BATT_CrgOffLineCount(); //充电器离线计数器 BATT_PwrReleaseCount(); //电源按键释放计数 TASK_WaitX(100); //等待10ms TASK_End(); } int main(void) { FLASH_BootVector(); WDT_Init(WDT_TIME_6S, WDT_EN_RST); //看门狗初始化 //GPIO_SWDFunction(DISABLE); // //SLEEP_NcPinInit(); //未使用的IO初始化 OSC_Init(); //时钟初始化 RTC_Init(); //RTC初始化 KEY_Init(); //按键初始化 LED_Init(); //LED初始化 BATT_Init(); //电池信息初始化 TASK_Init(); //任务调度器初始化 while(1) { TASK_Run(TASK_Key, TASK_ID_KEY); TASK_Run(TASK_Led, TASK_ID_LED); TASK_Run(TASK_Afe, TASK_ID_AFE); TASK_Run(TASK_100mS, TASK_ID_100MS); TASK_Run(TASK_Uart, TASK_ID_UART); TASK_Run(TASK_Sleep, TASK_ID_SLEEP); TASK_Run(TASK_Balance, TASK_ID_BALANCE); TASK_Run(TASK_Charger, TASK_ID_CHARGE); } } //看门狗没有中断号,指向NMI void NMI_Handler(void) { WDT_Clr(); } /*********************************************************************************************************************** * Function Name: HardFault_Handler * Description : Hard Fault handler to report stacked register values * Arguments : None * Return Value : None ***********************************************************************************************************************/ // Hard Fault handler in C, with stack frame location and LR value // extracted from the assembly wrapper as input parameters void hard_fault_handler_c(unsigned int *hardfault_args, unsigned lr_value) { unsigned int stacked_r0; unsigned int stacked_r1; unsigned int stacked_r2; unsigned int stacked_r3; unsigned int stacked_r12; unsigned int stacked_lr; unsigned int stacked_pc; unsigned int stacked_psr; stacked_r0 = ((unsigned long) hardfault_args[0]); stacked_r1 = ((unsigned long) hardfault_args[1]); stacked_r2 = ((unsigned long) hardfault_args[2]); stacked_r3 = ((unsigned long) hardfault_args[3]); stacked_r12 = ((unsigned long) hardfault_args[4]); stacked_lr = ((unsigned long) hardfault_args[5]); stacked_pc = ((unsigned long) hardfault_args[6]); stacked_psr = ((unsigned long) hardfault_args[7]); printf ("[Hard fault handler]\r\n"); printf ("R0 = %x\r\n", stacked_r0); printf ("R1 = %x\r\n", stacked_r1); printf ("R2 = %x\r\n", stacked_r2); printf ("R3 = %x\r\n", stacked_r3); printf ("R12 = %x\r\n", stacked_r12); printf ("Stacked LR = %x\r\n", stacked_lr); printf ("Stacked PC = %x\r\n", stacked_pc); printf ("Stacked PSR = %x\r\n", stacked_psr); printf ("Current LR = %x\r\n", lr_value); while(1); // endless loop } /*********************************************************************************************************************** * Function Name: HardFault_Handler * Description : Assembly wrapper using Embedded Assembler in Keil MDK * Arguments : None * Return Value : None ***********************************************************************************************************************/ // Hard Fault handler wrapper in assembly // It extracts the location of stack frame and passes it to handler // in C as a pointer. We also extract the LR value as second // parameter. __asm void HardFault_Handler(void) { MOVS r0, #4 MOV r1, LR TST r0, r1 BEQ stacking_used_MSP MRS R0, PSP ;first parameter - stacking was using PSP B get_LR_and_branch stacking_used_MSP MRS R0, MSP ; first parameter - stacking was using MSP get_LR_and_branch MOV R1, LR ; second parameter is LR current value LDR R2, = __cpp(hard_fault_handler_c) BX R2 }