STM32F 系列单片机 调试记录
1、RTC 配置
调一个 RTC,刚开始运行都正常,设置的时间跟读出的时间一样。但是换了一个芯片出现读出的年不对的情况,调试才发现是RTC设置的时候有些参数漏掉没填导致的。
T_S32 DRIVER_RTC_Ioctl(T_S32 s32Cmd, T_VOID *pvData) { switch(s32Cmd) { case E_RTC_IOCTL_CMD_SET_WAKE_INT: { //T_U16 u16Cnt = *((T_U16 *)pvData); } break; case E_RTC_IOCTL_CMD_READ_TIME: { S_RtcIoctlRead *pstTime = (S_RtcIoctlRead *)pvData; RTC_DateTypeDef stDate; RTC_TimeTypeDef stTime; HAL_RTC_GetTime(&RtcHandle, &stTime, RTC_FORMAT_BCD); HAL_RTC_GetDate(&RtcHandle, &stDate, RTC_FORMAT_BCD); pstTime->u8Year = stDate.Year; pstTime->u8Month = stDate.Month; pstTime->u8Date = stDate.Date; pstTime->u8WeekDay = stDate.WeekDay; pstTime->u8Hours = stTime.Hours; pstTime->u8Minutes = stTime.Minutes; pstTime->u8Seconds = stTime.Seconds; } break; case E_RTC_IOCTL_CMD_WRITE_TIME: { S_RtcIoctlWrite *pstTime = (S_RtcIoctlWrite *)pvData; RTC_DateTypeDef stDate; RTC_TimeTypeDef stTime; stDate.Year = pstTime->u8Year; stDate.Month = pstTime->u8Month; stDate.Date = pstTime->u8Date; stDate.WeekDay = 0x01; //这个参数要设置下 避免不在 1-7的范围里面 stTime.Hours = pstTime->u8Hours; stTime.Minutes = pstTime->u8Minutes; stTime.Seconds = pstTime->u8Seconds; stTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; //这个参数要设置下 stTime.StoreOperation = RTC_STOREOPERATION_RESET; //这个参数要设置下 HAL_RTC_SetTime(&RtcHandle, &stTime, RTC_FORMAT_BCD); HAL_RTC_SetDate(&RtcHandle, &stDate, RTC_FORMAT_BCD); } break; } return RET_SUCCESS; } ———————————————— 版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
2、休眠启动
外设休眠后,启动时重新配置下
3、STM32F0系列 二级引导注意事项
STM32F0系列是M0的内核,没有VTOR的寄存器,所以在应用程序里面的配置还有些不一样
1)引导程序的KEIL配置
2)引导程序代码
/********************************************* * @Îļþ: main.c * @×÷Õß: cjx * @°æ±¾: v1.0.0 * @ʱ¼ä: 2018-06-22 * @µç»°: 18770053277 * @¸ÅÒª: *********************************************/ #include "ioctrl.h" //Soft Update Explain #define BOOT_SOFT_ADDR 0x08000000 #define APP_RUN_ADDR 0x08004000 #define FACTORY_BIN_ADDR 0x0800E800 #define VER_INFO_ADDR 0x0801B000 #define USER_INFO_ADDR 0x0801B800 #define EXT_APP_BIN_ADDR 0x00002000 #define APP_BIN_SIZE (50*1024) #define FACTORY_VER 1 #define VER_FLAG_NULL 0 #define VER_FLAG_FACTORY 1 #define VER_FLAG_EXT 2 typedef struct{ T_U32 u32Ver; T_U32 u32Flag; }S_VerInfo; S_VerInfo g_VerInfo; S_FlashRead g_FlashRead; S_FlashWrite g_FlashWrite; S_FlashErase g_FlashErase; S_ExtFlashRead g_ExtFlashRead; S_ExtFlashWrite g_ExtFlashWrite; S_ExtFlashErase g_ExtFlashErase; T_U8 g_u8Cache[2*1024]; void UpdateFromFactory(void) { T_U32 u32i = 0; //g_FlashErase.u32Addr = APP_RUN_ADDR; //g_FlashErase.u32Pages = 18;//APP_BIN_SIZE/FLASH_PAGE_SIZE; //DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase); print_msg("\nErase_Okay!\n"); for(u32i = 0; u32i < (36*1024); u32i += sizeof(g_u8Cache)) { g_FlashRead.u32Addr = FACTORY_BIN_ADDR + u32i; g_FlashRead.pu8Data = (T_U8 *)g_u8Cache; g_FlashRead.u32Len = sizeof(g_u8Cache); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead); g_FlashErase.u32Addr = APP_RUN_ADDR + u32i;; g_FlashErase.u32Pages = 1; DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase); g_FlashWrite.u32Addr = APP_RUN_ADDR + u32i; g_FlashWrite.pu8Data = (T_U8 *)&g_u8Cache; g_FlashWrite.u32Len = sizeof(g_u8Cache); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite); } print_msg("\nCopy_Factory_Okay!\n"); g_FlashErase.u32Addr = VER_INFO_ADDR; g_FlashErase.u32Pages = 1; DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase); g_VerInfo.u32Ver = FACTORY_VER; g_VerInfo.u32Flag = VER_FLAG_NULL; g_FlashWrite.u32Addr = VER_INFO_ADDR; g_FlashWrite.pu8Data = (T_U8 *)&g_VerInfo; g_FlashWrite.u32Len = sizeof(g_VerInfo); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite); print_msg("\nVer_Info_Write_Okay!\n"); } void UpdateFromExtFlash(void) { T_U32 u32i = 0; g_FlashErase.u32Addr = APP_RUN_ADDR; g_FlashErase.u32Pages = APP_BIN_SIZE/FLASH_PAGE_SIZE; DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashWrite); for(u32i = 0; u32i < APP_BIN_SIZE; u32i += sizeof(g_u8Cache)) { g_ExtFlashRead.u32Addr = EXT_APP_BIN_ADDR + u32i; g_ExtFlashRead.pu8Data = (T_U8 *)g_u8Cache; g_ExtFlashRead.u32Len = sizeof(g_u8Cache); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_ExtFlashRead); g_FlashWrite.u32Addr = APP_RUN_ADDR + u32i; g_FlashWrite.pu8Data = (T_U8 *)&g_u8Cache; g_FlashWrite.u32Len = sizeof(g_u8Cache); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite); } g_FlashRead.u32Addr = VER_INFO_ADDR; g_FlashRead.pu8Data = (T_U8 *)&g_VerInfo; g_FlashRead.u32Len = sizeof(g_VerInfo); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead); //g_VerInfo.u32Ver = FACTORY_VER; g_VerInfo.u32Flag = VER_FLAG_NULL; g_FlashWrite.u32Addr = VER_INFO_ADDR; g_FlashWrite.pu8Data = (T_U8 *)&g_VerInfo; g_FlashWrite.u32Len = sizeof(g_VerInfo); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite); } typedef void (*pFunction)(void); void Jump_Address(void) { if (((*(volatile u32*)APP_RUN_ADDR) & 0x2FFE0000 ) == 0x20000000) { T_U32 test,JumpAddress; pFunction Jump_To_Application; test = (*(volatile u32*)APP_RUN_ADDR); JumpAddress = *(volatile u32*) (APP_RUN_ADDR + 4); Jump_To_Application = (pFunction) JumpAddress; print_msg("\nGoto_App!=0x%4x\n", JumpAddress); __set_MSP(*(volatile u32*) APP_RUN_ADDR); Jump_To_Application(); print_msg("\nNULL\n"); } } int main(void) { DRIVER_SYS_Open(); DRIVER_FLASH_Open(); DRIVER_EXTFLASH_Open(); DRIVER_SYS_EnableInterrupt(); //while(1); T_U32 u32Delay = 1000000; while(u32Delay--); g_FlashRead.u32Addr = VER_INFO_ADDR; g_FlashRead.pu8Data = (T_U8 *)&g_VerInfo; g_FlashRead.u32Len = sizeof(g_VerInfo); DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead); print_msg("\nBoot_Start!\n"); if(100 == g_VerInfo.u32Flag){ }else if(VER_FLAG_FACTORY == g_VerInfo.u32Flag){ UpdateFromFactory(); }else if(VER_FLAG_EXT == g_VerInfo.u32Flag){ UpdateFromExtFlash(); }else{ UpdateFromFactory(); } Jump_Address(); while(1); return 0; } ———————————————— 版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
3)应用程序的配置
这里机的把RAM编译的起始地址也改下,预留前面一段用来存中断向量地址
4)应用程序代码
/********************************************* * @Îļþ: main.c * @×÷Õß: cjx * @°æ±¾: v1.0.0 * @ʱ¼ä: 2018-06-22 * @µç»°: 18770053277 * @¸ÅÒª: *********************************************/ #include "apll.h" #include "ioctrl.h" int main(void) { memcpy((uint32_t*)0x20000000, (uint32_t*)0x08004000, 48*4); RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; uint32_t tmpctrl; tmpctrl = SYSCFG->CFGR1; tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE); tmpctrl |= (uint32_t) 0x03; SYSCFG->CFGR1 |= tmpctrl; T_VOID *pvAllHandle = T_NULL; if(RET_SUCCESS != ALL_Init(&pvAllHandle)) { return -1; } ALL_Run(pvAllHandle); ALL_DeInit(pvAllHandle); } ———————————————— 版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
5)Keil生成bin
https://download.csdn.net/download/everbright6666/9961053
6)bin合并工具
https://download.csdn.net/download/cheng401733277/11504294
7)合并