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

2021-10-14 00:13:58 字數 3890 閱讀 7155

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

開啟時鐘,配置引腳模式,控制電平

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

埠配置高暫存器後面的英文就是暫存器名稱可參考參考手冊,然後x可以為a e也就是適用gpuoa gpioe埠這樣的乙個暫存器。位址偏移,就是本暫存器相對這個外設基位址的偏移 暫存器位表 表示0 31位名稱及許可權,表上方的數字位編號,中間位位名稱,下方位讀寫許可權,w表示寫,r表示讀 位功能,如表所描...

暫存器(通用暫存器)

因為學習使用的是王爽的 組合語言 第3版 因此也只能提到8086cpo的暫存器。對於其他而言,原理都是相通的。對於8086暫存器,有14個暫存器,主要是 ax bx cx dx si di sp bp ip cs ss ds es psw。一 通用暫存器 8086的通用暫存器有ax bx cx dx...

暫存器,標誌暫存器

涉及硬體傳輸資料的,往往包含以下內容 1.資料傳輸引腳 資料放 2.控制引腳 怎麼控制 3.狀態引腳 結果如何 暫存器相當於cpu內部的儲存單元,可能是連續排列,相當於 c語言中的陣列。一 8個通用暫存器 16 bit accumulate axah alr0 count cxch clr1 dat...