埠配置高暫存器後面的英文就是暫存器名稱可參考參考手冊,然後x可以為a~e也就是適用gpuoa-gpioe埠這樣的乙個暫存器。
位址偏移,就是本暫存器相對這個外設基位址的偏移
暫存器位表:表示0-31位名稱及許可權,表上方的數字位編號,中間位位名稱,下方位讀寫許可權,w表示寫,r表示讀
位功能,如表所描述相同
led的亮滅是從3個led的陽極引出連線到3.3v電源,陰極各經過1各限流電阻引入至stm32的3各gpio引腳,所以我們只要控制這三個引腳的輸出高低電平,即可控制led的亮滅
啟動檔案:建立c語言環境的檔案,功能如下:
1. 初始化堆疊指標sp
2. 初始化程式計數器指標pc
3. 設定堆,棧的大小
4. 初始化中斷向量表
5. 配置外部sram作為資料儲存器
6. 呼叫systemini()函式配置stm32的系統時鐘
7. 設定c庫的分支入口「—main」呼叫main函式
**清單7-4 復位後執行的程式
;reset handler//程式注釋,彙編裡注釋適用;相當於c語言的//
reset_handler proc//定義了乙個子程式:reset_handler,這裡就相當於c語言定義了個函式名
export reset_handler [weak]//裡面的export表示子程式呼叫其它模組,[weak]表示弱定義,
import systeminit//鏈結在其他檔案中,從其它檔案引入呼叫宣告
import _main //鏈結在其他檔案中,從其它檔案引入呼叫宣告
ldr r0,=systeminit//把systeminit位址載入到暫存器r0
blx r0//程式跳轉到r0中的位址執行程式,即執行systeminit函式
ldr r0,=_main//_main的位址載入到暫存器r0
bx r0//程式跳轉到r0中的位址執行程式,執行_main函式,執行完畢就進入我們熟悉的c語言,進行main函式
了解到這些函式後,外部定義乙個systeminit函式設定stm32時鐘,stm32上電後,會執行systeminit函式,最後執行c語言main函式
寫完啟動檔案,如何控制暫存器?
rcc外設作用用來設定時鐘的。
**清單7-5
#define periph_base ((unsigned int)0x40000000)//#define 是巨集定義,字串periph_base 皆用((unsigned int)0x40000000)替代。
/匯流排基位址,gpio都掛載到apb2上/
/gpio暫存器位址,強制換成指標/
#define gpiob_crl *(unsigned int*)(gpiob_base+0x00)
#define gpiob_crh *(unsigned int*)(gpiob_base+0x04)
#define gpiob_idr *(unsigned int*)(gpiob_base+0x08)
#define gpiob_odr *(unsigned int*)(gpiob_base+0x0c)
#define gpiob_bsrr *(unsigned int*)(gpiob_base+0x10)
#define gpiob_brr *(unsigned int*)(gpiob_base+0x14)
#define gpiob_lckr *(unsigned int*)(gpiob_base+0x14)
如下圖所示,原理如上圖所示
main檔案
神奇的騙招
//函式為空,目的是為了騙過編譯器
void systeminit(void)
編譯就不會報錯,完美執行,還有一種辦法就是把啟動檔案有關systeminit的**注釋掉
**清單7-6注釋掉啟動檔案中呼叫systeminit的**(跟**清單7-4相同)
;reset handler//程式注釋,彙編裡注釋適用;相當於c語言的//
reset_handler proc//定義了乙個子程式:reset_handler,這裡就相當於c語言定義了個函式名
export reset_handler [weak]//裡面的export表示子程式呼叫其它模組,[weak]表示弱定義,
import systeminit//鏈結在其他檔案中,從其它檔案引入呼叫宣告
import _main //鏈結在其他檔案中,從其它檔案引入呼叫宣告
ldr r0,=systeminit//把systeminit位址載入到暫存器r0
blx r0//程式跳轉到r0中的位址執行程式,即執行systeminit函式
ldr r0,=_main//_main的位址載入到暫存器r0
bx r0//程式跳轉到r0中的位址執行程式,執行_main函式,執行完畢就進入我們熟悉的c語言,進行main函式
接下來點亮led功能
1.gpio模式
首先連線到led的gpio引腳pb0配置成輸出模式,即配置gpio的埠配置低暫存器crl。crl包含0-7號引腳,每個引腳占用4個暫存器位。mode配置輸出速度,cnf用來配置各種輸入輸出模式,在這裡我們把pb0配置為通用推挽輸出,輸出速度為10m
**清單7-7 配置輸出模式
//清空控制pb0的埠位
gpiob_crl &=~(0x0f<
//配置pb0為通用推挽輸出,速度為10m
gpio_crl |=(1<<4*0)
採用&=~和|=為了避免影響暫存器中的其它位,因為暫存器不能按位寫
2.控制引腳輸出電平
輸出模式時,對埠位設定/清除暫存器bsrr暫存器,埠位清除暫存器brr和odr暫存器寫入引數即可控制引腳的電平狀態,其中操作bsrr和brr最終影響odr暫存器,通過odr暫存器輸出來控制gpio
**清單7-8控制引腳輸出電平
1. //pbo輸出低電平
2. gpiob_odr|=(0<<0)
3.開啟外設時鐘
設定完gpio引腳,控制了電平輸出,還差最後一步。由於外設很多,為了降低功耗,每個外設對應乙個時鐘,在晶元剛上的時候都是關的,如果想要外設工作,必須把相應的時鐘開啟。
stm32的所有外設的時鐘由乙個專門的外設來管理叫rcc
**清單7-9開啟埠時鐘
//開啟gpiob埠時鐘
rcc_apb2enr |=(1<3)
4.水到渠成
開啟時鐘,配置引腳模式,控制電平
crh暫存器 實驗 使用暫存器點亮LED
埠配置高暫存器後面的英文就是暫存器名稱可參考參考手冊,然後x可以為a e也就是適用gpuoa gpioe埠這樣的乙個暫存器。位址偏移,就是本暫存器相對這個外設基位址的偏移 暫存器位表 表示0 31位名稱及許可權,表上方的數字位編號,中間位位名稱,下方位讀寫許可權,w表示寫,r表示讀 位功能,如表所描...
idr暫存器 嘿哈 暫存器對映
上一次我們已經實現了如何直接操作暫存器位址來點亮一盞led燈,但是這樣實在是太麻煩,那麼這次要講的就是,如何實現暫存器對映,更加快捷的實現點燈 怎麼又是點燈?我們先來看一下上一次的 圖中的這些位址都是看著官方給出的文件算出來的,這樣做的缺點很明顯,就是每一次都要算,算每乙個暫存器的位置,實際上我們可...
暫存器(通用暫存器)
因為學習使用的是王爽的 組合語言 第3版 因此也只能提到8086cpo的暫存器。對於其他而言,原理都是相通的。對於8086暫存器,有14個暫存器,主要是 ax bx cx dx si di sp bp ip cs ss ds es psw。一 通用暫存器 8086的通用暫存器有ax bx cx dx...