STM32 IAP 在线升级详解
际修改,原文是 说如果没有宏定义外部时钟HES_VALUE的值,但是宏定义了stm32f10x_cl 则外部时钟设置为25MHZ, 否则外部时钟都设置为8MHZ; 我用的外部晶振是8MHZ的所以不必修改这部分代码;
[plain]view plaincopyprint?
- #if!definedHSE_VALUE
- #ifdefSTM32F10X_CL
- #defineHSE_VALUE((uint32_t)25)//ValueoftheExternaloscillatorinHz
#else#defineHSE_VALUE((uint32_t)8)//ValueoftheExternaloscillatorinHz#endif/*STM32F10X_CL*/#endif/*HSE_VALUE*/
#if !defined HSE_VALUE
#ifdef STM32F10X_CL
#define HSE_VALUE ((uint32_t)25) // Value of the External oscillator in Hz
[plain]view plaincopyprint?
1.#else
#else
#define HSE_VALUE ((uint32_t)8) //Value of the External oscillator in Hz #endif /* STM32F10X_CL */#endif /* HSE_VALUE */
D.做系统主频时钟的更改
system_stm32f10x.c的系统主频率,依实际情况修改 ;我用的芯片主频时钟是24MHZ;
[plain]view plaincopyprint?
- #ifdefined(STM32F10X_LD_VL)(definedSTM32F10X_MD_VL)(definedSTM32F10X_HD_VL)
- /*#defineSYSCLK_FREQ_HSEHSE_VALUE*/
- #defineSYSCLK_FREQ_24MHz24
- #else
- /*#defineSYSCLK_FREQ_HSEHSE_VALUE*/
- #defineSYSCLK_FREQ_24MHz24
- /*#defineSYSCLK_FREQ_36MHz36*/
- /*#defineSYSCLK_FREQ_48MHz48*/
10. /*#defineSYSCLK_FREQ_56MHz56*/
11. /*#defineSYSCLK_FREQ_72MHz72*/
12. #endif
#if defined (STM32F10X_LD_VL) (defined STM32F10X_MD_VL) (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24
/* #define SYSCLK_FREQ_36MHz 36 */
/* #define SYSCLK_FREQ_48MHz 48 */
/* #define SYSCLK_FREQ_56MHz 56 */
/*#define SYSCLK_FREQ_72MHz 72*/
#endif
E.下面是关键部分操作了,在说这部分操作前我们先来说一下内存映射:
下图在stm32f100芯片手册的29页,我们只截取关键部分
从上图我们看出几个关键部分:
1.内部flash 是从0x0800 0开始 到0x0801 FFFF 结束, 0x0801FFFF-0x0800 0= 0x20 =128k 128也就是flash的大小;
2.SRAM的开始地址是 0x2 0 ;
我们要把我们的在线升级程序IAP放到FLASH里以0x0800 0 开始的位置, 应用程序放APP放到以0x08003开始的位置,中断向量表也放在0x0800 3开始的位置;如图
所以我们需要先查看一下misc.h文件中的中断向量表的初始位置宏定义为 NVIC_VectTab_Flash 0x0800 0
那么要就要设置编译器keil 中的 options for target 的target选项中的 IROM1地址 为0x0800 0 大小为 0x20即128K;
IRAM1地址为0x2 0 大小为0x2;
(提示:这一项IROM1 地址 即为当前程序下载到flash的地址的起始位置)
下面我们来分析一下修改后的IAP代码:
[plain]view plaincopyprint?
- /*******************************************************************************
- *@函数名称main
- *@函数说明主函数
- *@输入参数无
- *@输出参数无
- *@返回参数无
- *******************************************************************************/
- intmain(void)
- {
- 10. //Flash解锁
- 11. FLASH_Unlock();
- 12.
- 13. //配置PA15管脚
- 14. KEY_Configuration();
- 15. //配置串口1
- 16. IAP_Init();
- 17. //PA15是否为低电平
- 18. if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)==0x00)
- 19. {
- 20.
- 21. //执行IAP驱动程序更新Flash程序
- 22.
- 23. SerialPutString("\r\n======================================================================");
- 24. SerialPutString("\r\n=(C)COPYRIGHT2011Lierda=");
- 25. SerialPutString("\r\n==");
- 26. SerialPutString("\r\n=In-ApplicationProgrammingApplication(Version1.0.0)=");
- 27. SerialPutString("\r\n==");
- 28. SerialPutString("\r\n=Bywuguoyan=");
- 29. SerialPutString("\r\n======================================================================");
- 30. SerialPutString("\r\n\r\n");
- 31. Main_Menu();
- 32. }
- 33. //否则执行用户程序
- 34. else
- 35. {
- 36. //判断用处是否已经下载了用户程序,因为正常情况下此地址是栈地址
- 37. //若没有这一句话,即使没有下载程序也会进入而导致跑飞。
- 38. if(((*(__IOuint32_t*)ApplicationAddress)&0x2FFE0)==0x20)
- 39. {
- 40. SerialPutString("ExecuteuserProgram\r\n\n");
- 41. //跳转至用户代码
- 42. JumpAddress=*(_
STM32IAP在线升 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)