新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 位帶操作在stm32中的C語言實現

        位帶操作在stm32中的C語言實現

        作者: 時間:2016-11-19 來源:網絡 收藏
        首先:

        本文引用地址:http://www.104case.com/article/201611/318096.htm

        #define BITBAND(addr,bitnum) ((addr & 0xF0000000) + 0x2000000 + ((addr & 0xFFFFF) << 5) + (bitnum << 2))

        對上句程序的解釋:

        利用宏定義的方式將位帶地址的映射表示出來,該函數有兩個參數addr和bitnum,分別是原本的地址和在數據中的第幾位。我們知道兩個公式如下:

        0x2000_0000‐0x200F_FFFF地址空間:AliasAddr = 0x22000000 + (A – 0x20000000)*32 + n*4

        0x4000_0000‐0x400F_FFFF地址空間:AliasAddr = 0x42000000 + (A – 0x40000000)*32 + n*4

        仔細觀察我們可以發現,是有規律可尋的。兩個公式的基地址一個是0x22000000,一個是0x42000000,他們只是最高位不一樣,這個最高位和最原始的地址的最高位是一致的。所以我們通過 (addr & 0xF0000000) 來取最高位,再加上0x2000000就得到了公式中的基地址。我們知道兩個地址空間中地址的變換只是在低5位上,比如0x2000_0000 — 0x200F_FFFF(有5個F),利用(A – 0x20000000)的目的是得到地址addr和0x2000_0000之間的偏移,也就是低5位的內容,所以我們通過 (addr & 0xFFFFF)得到了低5位的數據,也即是偏移量。公式中的乘以32,我們使用效率更高的左移5位,同理,之后的乘以4也是通過移位操作來實現的。

        然后我們需要將上述地址轉換為一個指針,也就是,我們要告訴編譯器這是一個地址。

        #define MEM_ADDR(addr) *((volatile unsigned long *) (addr))

        其中使用到的volatile這個關鍵字是為了防止編譯器進行優化。這是必須的。

        完成上述兩步之后,我們就可以使用位帶操作了,比如我們要對GPIOA中的1管腳進行輸出控制,我們需要控制GPIOA的ODR寄存器,通過手冊我們知道它的地址是(GPIOA_BASE + 0x0C),所以我們定義:

        #define GPIOA_ODR_Addr (GPIOA_BASE + 0x0C)

        #define GPIOA(BitNum) MEM_ADDR( BITBAND(GPIOA_ODR_Addr,BitNum))

        將GPIOA的1管腳置高,就可以這樣寫:

        GPIOA(1) = 1;

        同理,我們可以得到其他管腳控制的方法,或者獲取其他管腳的輸入。

        以上,就是我對stm32的位帶操作的實現的理解,有什么理解不到位的地方,請大家指證,希望和大家多多交流。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 阜平县| 东乡县| 南江县| 高碑店市| 东乡| 武穴市| 三穗县| 敦化市| 阳信县| 平邑县| 渭源县| 都安| 师宗县| 海原县| 沙湾县| 镇巴县| 陆丰市| 弋阳县| 广宗县| 镇宁| 英山县| 漠河县| 易门县| 长兴县| 通道| 庐江县| 望都县| 渝北区| 建宁县| 茂名市| 镶黄旗| 丰顺县| 基隆市| 上虞市| 象州县| 淳化县| 马边| 永清县| 乌审旗| 怀宁县| 南丰县|