idr暫存器 實驗 使用暫存器點亮LED

2021-10-14 14:51:25 字數 3818 閱讀 3505

埠配置高暫存器後面的英文就是暫存器名稱可參考參考手冊,然後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...