stm32中cpu是32位的。最方便快捷的方法是直接操作32位的位址,對某個位址直接賦值是最快的操作,只需要乙個指令。
【附錄1】
在32位的系統中
1字(word) = 4位元組(byte)
1位元組(byte) = 8位(bit)
1b = 8bit
1kb = 1024b = 2^10b
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb
計算機中乙個二進位制位就是乙個bit,8個bit組成乙個位元組(byte)。乙個儲存單元可以儲存乙個位元組,也就是8個二進位制位。計算機的儲存器是以位元組b為最小單元來計算的。因此記憶體往往是1kb、1mb、1gb、1tb這樣描述的
儲存器有多少個位元組就是有多少個儲存單元,每個儲存單元都是從0開始順序編號,如乙個儲存器有1kb大小,那麼它就有1024個儲存單元,編號為0~1023。
儲存位址就是乙個編號,代表乙個儲存單元,也就是乙個位(8個位元組)
32位的cpu最多支援4g的記憶體空間,也就是2^32個儲存單元,如果用十進位制來對所有的儲存單元編號需要0~4,294,967,295,所以為了使用方便就用十六進製制來對記憶體單元編號0000 0000~ffff ffff(因為2^32 = fff ffff,)。為了混淆十進位制與十六進製制就在十六進製制的序列編號前面加上0x,或者在最後加上乙個h
由此,引出乙個重要的cpu原件暫存器,暫存器的作用有三個,我們只需要了解前兩個:
1.可將暫存器內的資料執行算術及邏輯運算
2.存於暫存器內的位址可用來指向記憶體的某個位置,即定址
操作暫存器,可以找到相應的記憶體單元,再對記憶體單元進行操作。在stm32中,有232個儲存單元,也就有232個記憶體位址。而每個暫存器占用4個位元組(32位)
【附錄2】
cpu:32位;即32位計算機的cpu一次最多能處理32位資料。32位處理器每次處理 4個位元組(4byte),最多支援4g的記憶體空間
位帶區(bit_band region):以位為單位,每1個位元組(8位)有個位址
別名區(alias region):以字為單位,乙個字等於4個位元組(32位)
別名區乙個單位(字)對應位帶區乙個單位(位),所以相當於將位帶區膨脹32倍才是別名區的大小,所以上面1mb的繫結區,對應到別名區為32m
(1)位帶本質上是一塊位址區(例如每一位位址位對應乙個暫存器)對映到另一片位址區(實現每一位位址位對應乙個暫存器中的一位),該區域就叫做位帶別名區,將每一位膨脹成乙個32位的字。
(2)位帶區的4個位元組對應實際暫存器或記憶體區的乙個位,雖然變大到4個位元組,但實際上只有最低位有效(代表0或1)
如下圖:
如上圖:
位帶區0x2000 0000的第0位對應到別名區0x22000000~0x2200 0003這4個位元組。需要指出的是0x2200 0001、0x2200 0002、0x2200 0003這樣的位址是不能直接被訪問的,只有0x2200 0000、0x2200 0004、0x2200 0008…這樣的起始位址(其實是4的倍數)才能被訪問,其實我們所說的別名區的位址對映就是計算這樣的起始位址。理解這一點也有助於後面位址計算公式的掌握。
好了,上面是理解的基礎,下面才是具體的別名區起始位址的計算。首先我們要有乙個概念是,一般計算應用關於定址的計算都這樣的:
要計算的位址=基位址+偏移量
a就是要進行對映的暫存器的位址,n 的取值範圍是0~7
官方給出的公式:
bit_word_addr = bit_band_base + (byte_offset32) +(bit_number4)
bit_word_addr:對映在位帶別名區的新位址(即為所求的位址)
bit_band_base:是別名區的起始位址
byte_offset:該位元組相對於位帶區起始位址的偏移。
bit_number:是目標位所在的位的位置(0-7)
sram區所對應的起始位址為 0x2200 0000
片上外設區所對應的起始位址為 0x4200 0000
這兩項都是一種規定,記住就行
在sram位帶區的偏移量為:(a-0x2000 0000),a為包含目標位位元組的位址
在片上外設區所對應的偏移量為:(a-0x4000 0000),a為包含目標位位元組的位址
byte_offset32:是因為位帶區的乙個位要擴張到別名區的32個位,同樣,乙個位帶區的位址也會擴張到別名區的32個位址。byte_offset32表示前面已經占用的位址。
bit_number4是因為 1bit位要占用四個位址單元(四個位元組,32 位)
實這個公式還有乙個變異形式,也是有助於理解這一公式的:
it_word_addr = bit_band_base + ((byte_offset8) + bit_number)4
由於位帶區每乙個位址是8個位,所以(byte_offset8)+ bit_number相當計算出了乙個以位元組為單位的偏移,再乘以4就是以字為單位的偏移了。
很明顯,不管是哪個公式,都是基位址+偏移
位帶別名區把每個位元(1bit)膨脹成乙個 32 位(4個位元組)。當你通過位帶別名區訪問這些字時,就可以達到訪問原始位元的目的。1mb位帶區對應32mb位帶別名區(1byte=8bit對映成8*4byte=32byte)。
位帶區和位帶別名區的對映如下圖:
位帶區:支援位帶操作的位址區
位帶別名:對別名位址的訪問最終作用到位帶區的訪問上(這中途有乙個位址對映過程)
對映過程舉例如下:
要設定0x2000 0000這個位元組的第二個位bit2為1,使用位帶操作的步驟有:1、將1寫入位 帶別名區對應的對映位址(即0x22000008,因為1bit對應4個byte);2、將0x2000 0000的值 讀取到內部的緩衝區(這一步驟是核心完成的,屬於原子操作,不需要使用者操作);3、將bit2 置1,再把值寫 回到0x2000 0000(屬於原子操作,不需要使用者操作)。
對映過程總結:在位帶區中,每個位元都對映到別名位址區的4個位元組——且4個位元組只有最低位有效。當乙個別名位址被訪問時,會先把該位址變換成位帶位址。對於讀操作,讀取位帶位址中的4個位元組(因為資料匯流排是32位的,暫存器也是32位的,所以是讀4個位元組),再把需要的位右移到最低有效位,並把最低有效位返回(相當於將位帶區的值右移再做與操作)。對於寫操作,把需要寫的位左移至對應的位序號處(相當於把1(或0)左移n(n為該bit位所在的位置)位再和位帶區的值做與操作),然後執行乙個原子的「讀-改-寫」過程。
統一後的公式 :
( a & 0xf0000000)+0x2000000+(( a &0xfffff)<<5)+(n<<2))
( gpioa_odr_addr & 0xf0000000)+0x2000000+(( gpioa_odr_addr &0xfffff)<<5)+(n<<2))
指標 暫存器 位操作
define periph base unsigned int 0x40000000 define apb2periph base periph base 0x00010000 define gpiob base apb2periph base 0x0c00 unsigned int 的作用是強制轉...
8位暫存器
library ieee use ieee.std logic 1164.all use ieee.std logic unsigned.all entity test34 is port clk,oe instd logic d instd logic vector 7 downto 0 q ou...
暫存器標誌位
of overflow flag 溢位標誌 運算元超出機器能表示的範圍表示溢位,溢位時為1.sf sign flag 符號標誌 記錄運算結果的符號,結果負時為1.zf zero flag 零標誌 運算結果等於0時為1,否則為0.cf carry flag 進製標誌 最高有效位產生進製時為1,否則為0...