STM32之暫存器訪問

2021-08-11 08:41:16 字數 2126 閱讀 8717

一般的暫存器訪問需要通過讀-改-寫三步曲位運算的清0置1來實現,但在stm32的程式設計中,通過利用它的一些優秀的特性如埠位設定/復位寄存bsrr、位繫結等,我們可以大大提公升暫存器的訪問速度和簡化暫存器的操作。

//一般暫存器操作:

gpiox->odr |=

0x10; //pin4置1

gpiox->odr &= ~0x10; //pin4清0

bsrr/brr暫存器

gpiox->bsrr //對bsrr的低16位寫1置位,對bsrr的高16位寫1清零

gpiox->brr //對brr的低16位寫1清零,brr的高16位保留

由此可見,通過bsrr/brr暫存器來操作odr暫存器, 不需要讀-改-寫三步曲, 僅通過就可一步到位,方便不少。

位繫結

當然了,stm32還有乙個更牛x的特性–位繫結,僅僅只要1個時鐘週期就能實現單獨的位操作。位繫結,是通過簡單的位址變換將暫存器中的某乙個位對映到記憶體中的某乙個儲存單元。這樣通過對乙個記憶體單元的讀寫就能間接訪問相應暫存器的某個位了,當然此時該32位的記憶體單元也只有最低位是有效的啦!

但是整個m3核心並沒有全部允許位繫結,只有兩個區有,分別是

sarm:0x20000000~0x2000ffff

1m大小

這個區繫結的位址是從0x22000000開始的;

peripherals:0x40000000~0x4000fffff

1m大小

這個區繫結的位址是從0x42000000開始的;

對應的位繫結公式為:

sram:aliasaddr = 0x22000000+((a-0x20000000)*32+n*4)

其中a:0x20000000~0x2000ffff n:0~31

peripherals: aliasaddr = 0x42000000+((a-0x40000000)*32+n*4)

其中a:0x40000000~0x4000fffff n:0~31

下面就可以通過位繫結來快速實現位操作

//addr&0xf0000000是為了區分sram還是peripherals

//addr&0xfffff相當於(a-0x20000000)或者(a-0x40000000)

//左移是為了實現快速的乘法操作:左移n位相當於乘以2^n

#define paout(n) bitbind(gpioa_odr_addr, n)

#define pain(n) bitbind(gpioa_idr_addr, n)

這樣就實現了類似51微控制器訪問i/o的操作方式

sbit p10 =p1^0

p10 = 0; 或 p10 = 1;

paout(3) = 1; 或 paout(3) = 0;

pretty cool, huh!

STM32之暫存器開發

首先克服心理作用,不要總是預設暫存器開發難,其實暫存器開發和庫函式開發所用的方法和難度是一樣的,並不難,下面用以stm32為例解釋。1.明確自己需要的功能 庫函式開發也需要 2.檢視手冊,找到功能對應的微控制器資源 3.找到功能所需暫存器 庫函式開發需要找到相應的功能函式 4.根據位址每位對應的功能...

STM32蜂鳴器 暫存器

這次實驗犯了個笑話,竟然在巨集定義後面加分號.就像這樣 define 大家千萬不要學我,結果報錯expected expression,還苦惱半天,想為啥操作不了暫存器了?我真愚蠢!剛開始我也不會寫這些東西,其實摸清套路就好,rcc時鐘使能 gpio初始化 相關暫存器初始化 延時函式 串列埠等初始化...

STM32暫存器對映

1.對映即將記憶體的某段位址與某一暫存器對應,微控制器對函式的操作底層是操作暫存器,而暫存器最終是操作記憶體上對應的單元,2.各個暫存器對應的位址都是在st定義的起始位址上層層偏移得到 3.想要實現某功能可直接對此段記憶體寫進相應的值,即可賦予某一功能 4.stm32底層實際是先定義出外設基位址,然...