www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]支持了位帶操作后,便可以使用普通的加載/儲(chǔ)存指令來(lái)對(duì)單一的比特進(jìn)行讀寫(xiě)操作了。簡(jiǎn)單而言,就是可以單獨(dú)的對(duì)一個(gè)比特位讀和寫(xiě)。在F103中,有兩個(gè)地方實(shí)現(xiàn)了位帶操作,其中一個(gè)是SRAM區(qū)的最低1MB范圍,第二個(gè)則是片

支持了位帶操作后,便可以使用普通的加載/儲(chǔ)存指令來(lái)對(duì)單一的比特進(jìn)行讀寫(xiě)操作了。簡(jiǎn)單而言,就是可以單獨(dú)的對(duì)一個(gè)比特位讀和寫(xiě)。在F103中,有兩個(gè)地方實(shí)現(xiàn)了位帶操作,其中一個(gè)是SRAM區(qū)的最低1MB范圍,第二個(gè)則是片內(nèi)外設(shè)區(qū)的最低1MB范圍。這兩個(gè)區(qū)中的地址除了可以像普通的RAM一樣使用外,它們還都有自己的“位帶別名區(qū)”,位帶別名區(qū)把每個(gè)比特膨脹成一個(gè)32位的字。當(dāng)你通過(guò)位帶別名區(qū)訪問(wèn)這些字時(shí),就可以達(dá)到訪問(wèn)原始比特的目的。


圖1.1位帶區(qū)與位帶別名區(qū)的膨脹對(duì)應(yīng)關(guān)系圖

支持位帶操作的兩個(gè)內(nèi)存區(qū)的范圍是:0x2000_0000‐0x200F_FFFF(SRAM區(qū)中的最低1MB);0x4000_0000‐0x400F_FFFF(片上外設(shè)區(qū)中的最低1MB)。外設(shè)位帶區(qū)經(jīng)過(guò)膨脹后的位帶別名區(qū)地址為:0X42000000~0X43FFFFFC,這部分地址空間為保留地址,沒(méi)有跟任何的外設(shè)地址重合。SRAM區(qū)經(jīng)過(guò)膨脹后的位帶別名區(qū)地址為:0X2200 0000~0X23FF FFFC,大小為32MB。

位帶區(qū)的一個(gè)比特位經(jīng)過(guò)膨脹之后,雖然變大到4個(gè)字節(jié),但是還是LSB才有效。有人會(huì)問(wèn)這不是浪費(fèi)空間嗎,要知道F103的系統(tǒng)總線是32位的,按照4個(gè)字節(jié)訪問(wèn)的時(shí)候是最快的,所以膨脹成4個(gè)字節(jié)來(lái)訪問(wèn)是最高效的。我們可以通過(guò)指針的形式訪問(wèn)位帶別名區(qū)地址從而達(dá)到操作位帶區(qū)比特位的效果。那這兩個(gè)地址直接如何轉(zhuǎn)換,下面簡(jiǎn)單地介紹一下。

一、對(duì)于片上外設(shè)位帶區(qū)的某個(gè)比特,記它所在字節(jié)的地址為A,位序號(hào)為n(0<=n<=7),則該比特在別名區(qū)的地址為:

1.AliasAddr==0x42000000+ (A-0x40000000)*8*4 +n*4

0X42000000是外設(shè)位帶別名區(qū)的起始地址,0x40000000是外設(shè)位帶區(qū)的起始地址,(A-0x40000000)表示該比特位前面有多少個(gè)字節(jié),一個(gè)字節(jié)有8位,所以*8,一個(gè)位膨脹后是4個(gè)字節(jié),所以*4,n表示該比特在A地址的序號(hào),因?yàn)橐粋€(gè)位經(jīng)過(guò)膨脹后是四個(gè)字節(jié),所以也*4。

二、對(duì)于SRAM位帶區(qū)的某個(gè)比特,記它所在字節(jié)的地址為A,位序號(hào)為n(0<=n<=7),則該比特在別名區(qū)的地址為:

1.AliasAddr==0x22000000+ (A-0x20000000)*8*4 +n*4

公式的分析同上所示

三、上面公式的統(tǒng)一:

為了方便操作,我們可以把這兩個(gè)公式合并成一個(gè)公式,把"位帶地址+位序號(hào)"轉(zhuǎn)換成別名區(qū)地址統(tǒng)一成一個(gè)宏。

//把"位帶地址+位序號(hào)"轉(zhuǎn)換成別名地址的宏

2 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr &

0x000FFFFF)<<5)+(bitnum<<2))
addr&0xF0000000是為了區(qū)別SRAM還是外設(shè),實(shí)際效果就是取出4或者2,如果是外設(shè),則取出的是4,+0X02000000之后就等于0X42000000,0X42000000是外設(shè)別名區(qū)的起始地址。如果是SRAM,則取出的是2,+0X02000000之后就等于0X22000000,0X22000000是SRAM別名區(qū)的起始地址。

addr & 0x00FFFFFF屏蔽了高三位,相當(dāng)于減去0X20000000或者0X40000000,但是為什么是屏蔽高三位?因?yàn)橥庠O(shè)的最高地址是:0X2010 0000,跟起始地址0X20000000相減的時(shí)候,總是低5位才有效,所以干脆就把高三位屏蔽掉來(lái)達(dá)到減去起始地址的效果,具體屏蔽掉多少位跟最高地址有關(guān)。SRAM同理分析即可。<<5相當(dāng)于前面公式中的*8*4,<<2相當(dāng)于*4。

最后我們就可以通過(guò)指針的形式操作這些位帶別名區(qū)地址,最終實(shí)現(xiàn)位帶區(qū)的比特位操作。

//把一個(gè)地址轉(zhuǎn)換成一個(gè)指針
#defineMEM_ADDR(addr)*((volatileunsignedlong*)(addr))
//把位帶別名區(qū)地址轉(zhuǎn)換成指針
#defineBIT_ADDR(addr,bitnum)MEM_ADDR(BITBAND(addr,bitnum))
(后文有附上對(duì)*((volatileunsignedlong*)的理解)。

從手冊(cè)中我們可以知道ODR和IDR這兩個(gè)寄存器對(duì)應(yīng)GPIO基址的偏移是20和16,我們先實(shí)現(xiàn)這兩個(gè)寄存器的地址映射,其中GPIOx_BASE在庫(kù)函數(shù)里面有定義。接著根據(jù)下圖便可理解GPIO ODR和IDR寄存器映射代碼。



圖1.2寄存器起始地址

//IO口地址映射

#define GPIOA_ODR_Addr(GPIOA_BASE+12) //0x4001080C

#define GPIOB_ODR_Addr(GPIOB_BASE+12) //0x40010C0C

#define GPIOC_ODR_Addr(GPIOC_BASE+12) //0x4001100C

#define GPIOD_ODR_Addr(GPIOD_BASE+12) //0x4001140C

#define GPIOE_ODR_Addr(GPIOE_BASE+12) //0x4001180C

#define GPIOF_ODR_Addr(GPIOF_BASE+12) //0x40011A0C

#define GPIOG_ODR_Addr(GPIOG_BASE+12) //0x40011E0C

#define GPIOA_IDR_Addr(GPIOA_BASE+8) //0x40010808

#define GPIOB_IDR_Addr(GPIOB_BASE+8) //0x40010C08

#define GPIOC_IDR_Addr(GPIOC_BASE+8) //0x40011008

#define GPIOD_IDR_Addr(GPIOD_BASE+8) //0x40011408

#define GPIOE_IDR_Addr(GPIOE_BASE+8) //0x40011808

#define GPIOF_IDR_Addr(GPIOF_BASE+8) //0x40011A08

#define GPIOG_IDR_Addr(GPIOG_BASE+8) //0x40011E08

其中:

#define GPIOA_BASE(APB2PERIPH_BASE + 0x0800)

#define GPIOB_BASE(APB2PERIPH_BASE + 0x0C00)

#define GPIOC_BASE(APB2PERIPH_BASE + 0x1000)

#define GPIOD_BASE(APB2PERIPH_BASE + 0x1400)

#define GPIOE_BASE(APB2PERIPH_BASE + 0x1800)

#define GPIOF_BASE(APB2PERIPH_BASE + 0x1C00)

#define GPIOG_BASE(APB2PERIPH_BASE + 0x2000)

#define APB2PERIPH_BASE(PERIPH_BASE + 0x10000)

#define PERIPH_BASE((uint32_t)0x40000000)

//GPIO輸入輸出位操作

#define PAout(n)BIT_ADDR(GPIOA_ODR_Addr,n)//輸出

#define PAin(n)BIT_ADDR(GPIOA_IDR_Addr,n)//輸入

#define PBout(n)BIT_ADDR(GPIOB_ODR_Addr,n)//輸出

#define PBin(n)BIT_ADDR(GPIOB_IDR_Addr,n)//輸入

#define PCout(n)BIT_ADDR(GPIOC_ODR_Addr,n)//輸出

#define PCin(n)BIT_ADDR(GPIOC_IDR_Addr,n)//輸入

#define PDout(n)BIT_ADDR(GPIOD_ODR_Addr,n)//輸出

#define PDin(n)BIT_ADDR(GPIOD_IDR_Addr,n)//輸入

#define PEout(n)BIT_ADDR(GPIOE_ODR_Addr,n)//輸出

#define PEin(n)BIT_ADDR(GPIOE_IDR_Addr,n)//輸入

#define PFout(n)BIT_ADDR(GPIOF_ODR_Addr,n)//輸出

#define PFin(n)BIT_ADDR(GPIOF_IDR_Addr,n)//輸入

#define PGout(n)BIT_ADDR(GPIOG_ODR_Addr,n)//輸出

#define PGin(n)BIT_ADDR(GPIOG_IDR_Addr,n)//輸入

附:對(duì)*((volatile unsigned long*)的理解:

對(duì)于不同的計(jì)算機(jī)體系結(jié)構(gòu),設(shè)備可能是端口映射,也可能是內(nèi)存映射的。如果系統(tǒng)結(jié)構(gòu)支持獨(dú)立的IO地址空間,并且是端口映射,就必須使用匯編語(yǔ)言完成實(shí)際對(duì)設(shè)備的控制,因?yàn)镃語(yǔ)言并沒(méi)有提供真正的“端口”的概念。如果是內(nèi)存映射,那就方便的多了。

以#define IOPIN(*((volatile unsigned long *) 0xE0028000))為例:作為一個(gè)宏定義語(yǔ)句,define是定義一個(gè)變量或常量的偽指令。首先(volatile unsigned long *)的意思是將后面的那個(gè)地址強(qiáng)制轉(zhuǎn)換成volatile unsigned long *,unsigned long *是無(wú)符號(hào)長(zhǎng)整形,volatile是一個(gè)類(lèi)型限定符,如const一樣,當(dāng)使用volatile限定時(shí),表示這個(gè)變量是依賴(lài)系統(tǒng)實(shí)現(xiàn)的,以為著這個(gè)變量會(huì)被其他程序或者計(jì)算機(jī)硬件修改,由于地址依賴(lài)于硬件,volatile就表示他的值會(huì)依賴(lài)于硬件。

volatile類(lèi)型是這樣的,其數(shù)據(jù)確實(shí)可能在未知的情況下發(fā)生變化。比如,硬件設(shè)備的終端更改了它,現(xiàn)在硬件設(shè)備往往也有自己的私有內(nèi)存地址,比如顯存,他們一般是通過(guò)映象的方式,反映到一段特定的內(nèi)存地址當(dāng)中,這樣,在某些條件下,程序就可以直接訪問(wèn)這些私有內(nèi)存了。另外,比如共享的內(nèi)存地址,多個(gè)程序都對(duì)它操作的時(shí)候。你的程序并不知道,這個(gè)內(nèi)存何時(shí)被改變了。如果不加這個(gè)voliatile修飾,程序是利用catch當(dāng)中的數(shù)據(jù),那個(gè)可能是過(guò)時(shí)的了,加了voliatile,就在需要用的時(shí)候,程序重新去那個(gè)地址去提取,保證是最新的。歸納起來(lái)如下:

1. volatile變量可變?cè)试S除了程序之外的比如硬件來(lái)修改他的內(nèi)容2.訪問(wèn)該數(shù)據(jù)任何時(shí)候都會(huì)直接訪問(wèn)該地址處內(nèi)容,即通過(guò)cache提高訪問(wèn)速度的優(yōu)化被取消。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉