二、在拿到ST公司官方的IAP 程序后 我们要思考几点: 1.ST 官方IAP是什么针对什么芯片型号的,我们要用的又是什么芯片型号; 2.我们要用官方IAP适合我们芯片的程序升级使用,要在原有的基础上做那些改变; (我的资源里有官方IAP源码:http://download.csdn.NET/detail/yx_l128125/6445811) 初略看了一下IAP源码后,现在我们可以回答一下上面的2个问题了: 1.官网刚下载的IAP针对的是stm32f103c8芯片的,所以他的启动代码文件选择的是 startup_stm32f10x_md.s,而我的芯片是stm32f100cb,所以我的启动代码文件选择的是 startup_stm32f10x_md_lv.s
2 .第二个问题就是今天我们要做详细分析才能回答的问题了; (1).知道了IAP官方源码的芯片和我们要用芯片的差异,首先我们要在源码的基础上做芯片级的改动; A.首先改变编译器keil的芯片型号上我们要改成我们的芯片类型---STM32F100CB; B.在keil的options for targer 选项C/C++/PREPROMCESSOR symbols的Define栏里定义,把有关STM32F10X_MD的宏定义改成:STM32F10X_MD_VL 也可以在STM32F10X.H里用宏定义
[plain] view plain copy
- /* Uncomment the line below according to the target STM32 device used in your
- application
- */
-
- #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
- /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
- /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
- /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
- #define STM32F10X_MD_VL /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
- /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
- /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */
- /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */
- /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
- #endif
上面代码说的是如果没有定义 STM32F10X_MD_VL, 则宏定义 STM32F10X_MD_VL C.外部时钟问价在stm32f10x.h 依据实际修改,原文是 说如果没有宏定义外部时钟HES_VALUE的值,但是宏定义了stm32f10x_cl 则外部时钟设置为25MHZ, 否则外部时钟都设置为8MHZ; 我用的外部晶振是8MHZ的所以不必修改这部分代码; [plain] view plain copy
- #if !defined HSE_VALUE
- #ifdef STM32F10X_CL
- #define HSE_VALUE ((uint32_t)25000000) // Value of the External oscillator in Hz <pre name="code" class="plain"> #else </pre> #define HSE_VALUE ((uint32_t)8000000) //Value of the External oscillator in Hz #endif /* STM32F10X_CL */#endif /* HSE_VALUE */
D.做系统主频时钟的更改 system_stm32f10x.c的系统主频率,依实际情况修改 ;我用的芯片主频时钟是24MHZ;
[plain] view plain copy
-
- #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
- /* #define SYSCLK_FREQ_HSE HSE_VALUE */
- #define SYSCLK_FREQ_24MHz 24000000
- #else
- /* #define SYSCLK_FREQ_HSE HSE_VALUE */
- #define SYSCLK_FREQ_24MHz 24000000
- /* #define SYSCLK_FREQ_36MHz 36000000 */
- /* #define SYSCLK_FREQ_48MHz 48000000 */
- /* #define SYSCLK_FREQ_56MHz 56000000 */
- /*#define SYSCLK_FREQ_72MHz 72000000*/
- #endif
E.下面是关键部分操作了,在说这部分操作前我们先来说一下内存映射:
下图在stm32f100芯片手册的29页,我们只截取关键部分
从上图我们看出几个关键部分: 1.内部flash 是从0x0800 0000开始 到0x0801 FFFF 结束, 0x0801FFFF-0x0800 0000= 0x20000 =128k 128也就是flash的大小; 2.SRAM的开始地址是 0x2000 0000 ; 我们要把我们的在线升级程序IAP放到FLASH里以0x0800 0000 开始的位置, 应用程序放APP放到以0x08003000开始的位置,中断向量表也放在0x0800 3000开始的位置;如图
所以我们需要先查看一下misc.h文件中的中断向量表的初始位置宏定义为 NVIC_VectTab_Flash 0x0800 0000 那么要就要设置编译器keil 中的 options for target 的target选项中的 IROM1地址 为0x0800 0000 大小为 0x20000即128K; IRAM1地址为0x2000 0000 大小为0x2000; (提示:这一项IROM1 地址 即为当前程序下载到flash的地址的起始位置)
|