STM32系列基于專為要求高性能、低成本、低功耗的嵌入式應(yīng)用專門設(shè)計(jì)的ARM Cortex-M3內(nèi)核(ST‘s product portfolio contains a comprehensive range of microcontrollers, from robust, low-cost 8-bit MCUs up to 32-bit ARM-based Cortex?-M0 and M0+, Cortex?-M3, Cortex?-M4 Flash microcontrollers with a great choice of peripherals. ST has also extended this range to include an ultra-low-power MCU platform)[1] 。按內(nèi)核架構(gòu)分為不同產(chǎn)品:
其中STM32F系列有:
STM32F103“增強(qiáng)型”系列
STM32F101“基本型”系列
STM32F105、STM32F107“互聯(lián)型”系列
增強(qiáng)型系列時(shí)鐘頻率達(dá)到72MHz,是同類產(chǎn)品中性能最高的產(chǎn)品;基本型時(shí)鐘頻率為36MHz,以16位產(chǎn)品的價(jià)格得到比16位產(chǎn)品大幅提升的性能,是32位產(chǎn)品用戶的最佳選擇。兩個(gè)系列都內(nèi)置32K到128K的閃存,不同的是SRAM的最大容量和外設(shè)接口的組合。時(shí)鐘頻率72MHz時(shí),從閃存執(zhí)行代碼,STM32功耗36mA,相當(dāng)于0.5mA/MHz。
在CM3中,有兩個(gè)區(qū)中實(shí)現(xiàn)了位帶。其中一個(gè)是 SRAM 區(qū)的最低 1MB 范圍,第二個(gè)則是片內(nèi)外設(shè)區(qū)的最低 1MB 范圍。這兩個(gè)區(qū)中的地址除了可以像普通的 RAM 一樣使用外,它們還都有自己的“位帶別名區(qū)”,位帶別名區(qū)把每個(gè)比特膨脹成一個(gè) 32 位的字。當(dāng)你通過位帶別名區(qū)訪問這些字時(shí),就可以達(dá)到訪問原始比特的目的。
在位帶區(qū)中,每個(gè)比特都映射到別名地址區(qū)的一個(gè)字(這是只有 LSB 有效的字)。當(dāng)一個(gè)別名地址被訪問時(shí),會(huì)先把該地址變換成位帶地址。對(duì)于讀操作,讀取位帶地址中的一個(gè)字,再把需要的位右移到 LSB,并把 LSB 返回。對(duì)于寫操作,把需要寫的位左移至對(duì)應(yīng)的位序號(hào)處,然后執(zhí)行一個(gè)原子的“讀-改-寫”過程。
支持位帶操作的兩個(gè)內(nèi)存區(qū)的范圍是:
0x2000_0000‐0x200F_FFFF(SRAM 區(qū)中的最低1MB) 0x4000_0000‐0x400F_FFFF(片上外設(shè)區(qū)中的最低 1MB) 位帶(Bit-band)操作是Cortex-M3提供的特殊操作:位帶區(qū)的每個(gè)位都有位帶別名區(qū)的一個(gè)字與之對(duì)應(yīng)。Bit-band區(qū)域的存儲(chǔ)器以32位方式進(jìn)行訪問,其中有效的僅僅是BIT0位,只有BIT0的值才對(duì)應(yīng)到相應(yīng)的普通區(qū)域的比特位上,其他位無效。STM32F系列芯片為所有外設(shè)寄存器和SRAM提供相對(duì)應(yīng)的Bit-band區(qū)域,以簡(jiǎn)化對(duì)外設(shè)寄存器和SRAM的操作位帶操作最重要的一環(huán)就是尋址,即為需要操作的“目標(biāo)位”找到位帶別名區(qū)相對(duì)應(yīng)的地址:
位帶別名區(qū)首地址+(操作字節(jié)的偏移量*32) +(操作位的偏移量*4) 內(nèi)置SRAM區(qū)的位帶別名區(qū)首地址 = 0x2200,0000 外設(shè)寄存器區(qū)的位帶別名區(qū)首地址 = 0x4200,0000
例如:GPIOA的端口輸出數(shù)據(jù)寄存器地址0x4001080c(stm32f1xx系列),對(duì)于PA.0來說控制其輸出電平的比特位的位帶操作地址為:
0x42000000+(0x1080c*32)+(0*4) = 0x42021018 以stm32f207為例,介紹stm32的位帶操作。
在《ARM Cortex M3權(quán)威指南》92頁(yè)介紹了如何在C語(yǔ)言中使用位帶操作。個(gè)人在使用位帶操作過程中將其大致總結(jié)為三種:
?、?查找需要定義的位所在的地址,將地址強(qiáng)制轉(zhuǎn)換為指針,通過取指針內(nèi)容的方式使用。
例如:
#define PD12 ((volatile unsigned long *)(0x424182b0))
//0x424182b0為GPIOD_Pin12引腳對(duì)應(yīng)的映射地址
*PD12=0x01; //PD12引腳置高
?、?直接使用地址進(jìn)行操作
(*((u32*)0x424182b0))=0x01; //PD12引腳置高 當(dāng)然也可以通過如下定義使用 例如:
#define PD12 *((volatile unsigned long *)(0x424182b0))
//0x424182b0為GPIOD_Pin12引腳對(duì)應(yīng)的映射地址
PD12=0x01; //PD12引腳置高
?、墼诙鄠€(gè)引腳需要定義時(shí),顯然上面兩種方法都比較繁瑣。為簡(jiǎn)化位帶操作,也可以定義一些宏。比如,我們可以建立一個(gè)把“位帶地址+位序號(hào)”換成別名地址的宏,再建立一個(gè)把別名地址轉(zhuǎn)換成指針類型的宏。
例如
#define GPIOD_ODR_Addr ((uint32_t)(GPIOD_BASE+0x14)) // GPIOD_BASE已經(jīng)定義過 #define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)《《5)+(bitnum《《2)) #define MEM_ADDR(addr) (*((volatile unsigned long *)(addr)) ) #define BIT_ADDR(addr, bitnum) MEM_ADDR( BITBAND(addr, bitnum) ) #define PD12 BIT_ADDR(GPIOD_ODR_Addr, 12) //12為GPIOD對(duì)應(yīng)的引腳號(hào) #define PD12 BIT_ADDR(GPIOD_ODR_Addr, 13) //13為GPIOD對(duì)應(yīng)的引腳號(hào) PD12=0x01; //PD12引腳置高 PD13=0x01; //PD13引腳置高
說明:GPIOD_BASE已經(jīng)在庫(kù)文件stm32f2xx.h中定義過,直接使用即可,對(duì)應(yīng)地址是GPIOD的基地址,0x14是ODR的偏移地址。第二條語(yǔ)句是把“位帶地址+序號(hào)”轉(zhuǎn)換為對(duì)應(yīng)的位帶別名區(qū)地址。第三條語(yǔ)句MEM_ADDR(addr)代表的是(addr)地址中的內(nèi)容。volatile必須使用,原因如下。
volatile 是易變的、不穩(wěn)定的意思。用它修飾的變量表示可以被某些編譯器未知的因素更改,比如操作系統(tǒng)、硬件或者其它線程等。遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對(duì)訪問該變量的代碼就不再進(jìn)行優(yōu)化,從而可以提供對(duì)特殊地址的穩(wěn)定訪問。
先看看下面的例子: int i=10; int j = i;//(1)語(yǔ)句 int k = i;//(2)語(yǔ)句
這時(shí)候編譯器對(duì)代碼進(jìn)行優(yōu)化,因?yàn)樵冢?)、(2)兩條語(yǔ)句中,i 沒有被用作左值。這時(shí)候編譯器認(rèn)為 i 的值沒有發(fā)生改變,所以在(1)語(yǔ)句時(shí)從內(nèi)存中取出 i 的值賦給 j 之后,這個(gè)值并沒有被丟掉,而是在(2)語(yǔ)句時(shí)繼續(xù)用這個(gè)值給 k 賦值。編譯器不會(huì)生成出匯編代碼重新從內(nèi)存里取 i 的值,這樣提高了效率。但要注意:(1)、(2)語(yǔ)句之間 i 沒有被用作左值才行。
再看另一個(gè)例子: volatile int i=10; int j = i;//(3)語(yǔ)句 int k = i;//(4)語(yǔ)句
volatile 關(guān)鍵字告訴編譯器 i 是隨時(shí)可能發(fā)生變化的,每次使用它的時(shí)候必須從內(nèi)存中取出 i的值,因而編譯器生成的匯編代碼會(huì)重新從 i 的地址處讀取數(shù)據(jù)放在 k 中。這樣看來,如果 i 是一個(gè)寄存器變量或者表示一個(gè)端口數(shù)據(jù)或者是多個(gè)線程的共享數(shù)據(jù),就容易出錯(cuò),所以說 volatile 可以保證對(duì)特殊地址的穩(wěn)定訪問。
評(píng)論