在stm32微控制器的學習中,有乙個最大的特點就是你所編寫的stm32的程式操作,基本上都是匯流排的操作,比如gpiob->odr = 0x0001(或者直接等於1),這樣的操作必須要考慮整個暫存器的資料,但其實如果學過51微控制器的人都知道,我們除了對於匯流排操作外,我們還是經常會對單獨的位進行操作,比如
#include
sbit led1 = p0^0;
led1 =
1;
那我們要怎麼進行位帶操作呢,首先我們要理解位帶操作的原理。
首先位帶操作不是所有地方都可以用,一般只能用在sarm區和外設暫存器區。sarm的位帶區是從0x22000000開始的,而外設的位帶區是從0x42000000開始的,由於前面所提到的位帶區就是在我們的暫存器膨脹為32位,這樣就可以一一的進行操作,根據這個原理,我們就可以寫出公式,完成位帶區與位帶別名區的乙個轉化。
peripheral_addr = 0x4200_0000 + (a - 0x4000_0000)32 + n4
sarm_addr = 0x2200_0000 + (a - 0x4000_0000)32 + n4
其中a 為暫存器的位址,n**位號。
*這裡稍微的說明一下為什麼位帶別名區可以膨脹為位帶區的32位,這是因為在位帶區的一位,相當於是位帶別名區的4位元組。
再根據上面的兩算式,進行一下統一,就可以得到乙個統一的位帶區與位帶別名區的乙個轉化。
(addr & 0xf000_0000) + 0x2000_0000 + ((addr & 0x00ff_ffff) << 5)+(bitnum << 2)
這個公式比較難理解的就是((addr & 0x00ff_ffff) << 5)這塊,首先我們看addr & 0x00ff_ffff,這就是因為在前面(addr & 0xf000_0000) + 0x2000_0000 中,已經完成了前兩位的操作,所以我們只看後面的6位,不看前面的2位,所以是&0x00ff_ffff,之所以要再左移5位,是因為2^5 = 32 , 所以是對應了前面的*32。後面的左移兩位也就是同理了。
下面我就以gpio->odr暫存器為例,來**實現一下位帶操作。
//bit_band.h
#ifndef bit_band_h
#define bit_band_h
#include
"stm32f10x.h"
#define gpiob_odr_addr gpiob_base + 0x0c
#define led_out(bitnum) (gpiob_odr_addr & 0xf000_0000) + 0x2000_0000 + ((gpiob_odr_addr & 0x00ff_ffff) << 5)+(bitnum << 2)
void
led_output()
;#endif
/*bit_band_h*/
//bit_band.c
void
led_output
(void
)
//main函式
intmain
(void
)
這樣我們就可以用位帶操作來點亮乙個led燈,使我們的程式更加的可靠。 STM32F10x系列 中斷
概念問題 中斷與事件有什麼聯絡與區別?stm32之中斷與事件 中斷與事件的區別 簡單概括下。中斷 cpu單執行緒情況下只能處理單一任務,在有零時任務需要處理時,可以暫時放下當前任務,優先處理零時任務,再回過來處理之前的任務。多個中斷可以進行巢狀,比如產生了多個零時任務,那麼就可以按照優先順序處理這多...
STM32F429位帶操作
stm32的m3和m4晶元支援位帶操作。那什麼是位帶操作呢?位帶操作就是可以單獨的對乙個位 bit 進行讀寫操作。咦?這麼一說好像有種似曾相識的感覺,在 見過呢?沒錯,是c51。在c51中操作io口是不是很方便,直接操作某一位就ok了。而在stm32中我們往往需要操作的是整個暫存器,讀,修改,寫。繁...
STM32F10X入門 流水燈
2019 3 16 2019 3 19 core cm32.c stdin.h中定義了字元型 stm32f10x.h stm32f10x conf.h中定義了引用的外設標頭檔案 庫檔案之間的依賴呼叫關係 pngstm32f10x.h檢視位址對映 比如define gpioa base apb2per...