STM32 IAP+APP應(yīng)用
一、在進入主題之前我們先了解一些必要的基礎(chǔ)知識----stm32系列芯片的種類和型號:
startup_stm32f10x_cl.s 互聯(lián)型的器件,STM32F105xx,STM32F107xx
startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_hd_vl.s 大容量的STM32F100xx
startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_ld_vl.s 小容量的STM32F100xx
startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_md_vl.s 中容量的STM32F100xx(我項目中用的是此款芯片 stm32f100CB)
startup_stm32f10x_xl.s FLASH在512K到1024K字節(jié)的STM32F101xx,STM32F102xx,STM32F103xx
(例如:像stm32f103re 這個型號的 芯片flash是512k 的, 啟動文件用startup_stm32f10x_xl.s 或者startup_stm32f10x_hd.s 都可以;)
cl:互聯(lián)型產(chǎn)品,stm32f105/107系列
vl:超值型產(chǎn)品,stm32f100系列
xl:超高密度產(chǎn)品,stm32f101/103系列
ld:低密度產(chǎn)品,F(xiàn)LASH小于64K
md:中等密度產(chǎn)品,F(xiàn)LASH=64 or 128
hd:高密度產(chǎn)品,F(xiàn)LASH大于128
二、在拿到ST公司官方的IAP 程序后我們要思考幾點:
1.ST 官方IAP是什么針對什么芯片型號的,我們要用的又是什么芯片型號;
2.我們要用官方IAP適合我們芯片的程序升級使用,要在原有的基礎(chǔ)上做那些改變;
(我的資源里有官方IAP源碼:http://download.csdn.net/detail/yx_l128125/6445811)
初略看了一下IAP源碼后,現(xiàn)在我們可以回答一下上面的2個問題了:
1.官網(wǎng)剛下載的IAP針對的是stm32f103c8芯片的,所以他的啟動代碼文件選擇的是startup_stm32f10x_md.s,而我的芯片是stm32f100cb,所以我的啟動代碼文件選擇的是 startup_stm32f10x_md_lv.s
2 .第二個問題就是今天我們要做詳細分析才能回答的問題了;
(1).知道了IAP官方源碼的芯片和我們要用芯片的差異,首先我們要在源碼的基礎(chǔ)上做芯片級的改動;
A.首先改變編譯器keil的芯片型號上我們要改成我們的芯片類型---STM32F100CB;
B.在keil的options for targer 選項C/C++/PREPROMCESSOR symbols的Define欄里定義,把有關(guān)STM32F10X_MD的宏定義改成:STM32F10X_MD_VL
也可以在STM32F10X.H里用宏定義
[plain]view plaincopy
#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)
#defineSTM32F10X_MD_VL
#endif
上面代碼說的是如果沒有定義 STM32F10X_MD_VL, 則宏定義STM32F10X_MD_VL
C.外部時鐘問價在stm32f10x.h 依據(jù)實際修改,原文是說如果沒有宏定義外部時鐘HES_VALUE的值,但是宏定義了stm32f10x_cl 則外部時鐘設(shè)置為25MHZ, 否則外部時鐘都設(shè)置為8MHZ; 我用的外部晶振是8MHZ的所以不必修改這部分代碼;
[plain]view plaincopy
#if!definedHSE_VALUE
#ifdefSTM32F10X_CL
#defineHSE_VALUE((uint32_t)25000000)//ValueoftheExternaloscillatorinHz#else#defineHSE_VALUE((uint32_t)8000000)//ValueoftheExternaloscillatorinHz#endif#endif
D.做系統(tǒng)主頻時鐘的更改
system_stm32f10x.c的系統(tǒng)主頻率,依實際情況修改 ;我用的芯片主頻時鐘是24MHZ;
[plain]view plaincopy
#ifdefined(STM32F10X_LD_VL)||(definedSTM32F10X_MD_VL)||(definedSTM32F10X_HD_VL)
#defineSYSCLK_FREQ_24MHz24000000
#else
#defineSYSCLK_FREQ_24MHz24000000
#endif
E.下面是關(guān)鍵部分操作了,在說這部分操作前我們先來說一下內(nèi)存映射:
下圖在stm32f100芯片手冊的29頁,我們只截取關(guān)鍵部分
所以我們需要先查看一下misc.h文件中的中斷向量表的初始位置宏定義為 NVIC_VectTab_Flash 0x0800 0000
那么要就要設(shè)置編譯器keil 中的 options for target 的target選項中的 IROM1地址 為0x0800 0000 大小為 0x20000即128K;
IRAM1地址為0x2000 0000 大小為0x2000;
(提示:這一項IROM1 地址即為當(dāng)前程序下載到flash的地址的起始位置)
下面我們來分析一下修改后的IAP代碼:
[plain]view plaincopy
intmain(void)
{
//Flash解鎖
FLASH_Unlock();
//配置PA15管腳
KEY_Configuration();
//配置串口1
IAP_Init();
//PA15是否為低電平
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)==0x00)
{
//執(zhí)行IAP驅(qū)動程序更新Flash程序
SerialPutString("rn======================================================================");
SerialPutString("rn=(C)COPYRIGHT2011Lierda=");
SerialPutString("rn==");
SerialPutString("rn=In-ApplicationProgrammingApplication(Version1.0.0)=");
SerialPutString("rn==");
SerialPutString("rn=Bywuguoyan=");
SerialPutString("rn======================================================================");
SerialPutString("rn