娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年09月28日(星期六)

2019年09月28日 | 再造STM32---第十一部分:GPIO—位帶操作

發布者:科技思想家 來源: eefocus關鍵字:STM32  GPIO  位帶操作 手機看文章 掃描二維碼
隨時隨地手機看文章

       本章參考資料:《STM32F4xx 中文參考手冊》存儲器和總線構架章節、 GPIO 章節,《Cortex?-M4 內核編程手冊》 2.2.5 Bit-banding。學習本章時,配套這些參考資料學習效果會更佳。


11.1 位帶簡介:

       位操作就是可以單獨的對一個比特位讀和寫,這個在 51 單片機中非常常見。 51 單片機中通過關鍵字 sbit 來實現位定義, F429 中沒有這樣的關鍵字,而是通過訪問位帶別名區來實現。

       在 F429 中,有兩個地方實現了位帶,一個是 SRAM 區的最低 1MB 空間,另一個是外設區最低 1MB 空間。這兩個 1MB 的空間除了可以像正常的 RAM 一樣操作外,他們還有自己的位帶別名區,位帶別名區把這 1MB 的空間的每一個位膨脹成一個 32 位的字,當訪問位帶別名區的這些字時,就可以達到訪問位帶區某個比特位的目的。

11.1.1 外設位帶區:

      外設位帶區的地址為: 0X40000000~0X400F0000,大小為 1MB,這 1MB 的大小包含了 APB1/2 和 AHB1 上所以外設的寄存器, AHB2/3 總線上的寄存器沒有包括。 AHB2 總線上的外設地址范圍為: 0X50000000~0X50060BFF, AHB3 總線上的外設地址范圍為:0XA0000000~0XA0000FFF。外設位帶區經過膨脹后的位帶別名區地址為:0X42000000~0X43FFFFFF,這部分地址空間為保留地址,沒有跟任何的外設地址重合。


11.1.2 SRAM 位帶區:

      SRAM 的位帶區的地址為: 0X2000 0000~X200F 0000,大小為 1MB,經過膨脹后的位帶別名區地址為: 0X2200 0000~0X23FF FFFF,大小為 32MB。操作 SRAM 的比特位這個用得很少。


11.1.3 位帶區和位帶別名區地址轉換:

      位帶區的一個比特位經過膨脹之后,雖然變大到 4 個字節,但是還是 LSB 才有效。有人會問這不是浪費空間嗎,要知道 F429 的系統總線是 32 位的,按照 4 個字節訪問的時候是最快的,所以膨脹成 4 個字節來訪問是最高效的。


      我們可以通過指針的形式訪問位帶別名區地址從而達到操作位帶區比特位的效果。那這兩個地址直接如何轉換,我們簡單介紹一下。

1. 外設位帶別名區地址:

      對于片上外設位帶區的某個比特,記它所在字節的地址為 A,位序號為 n(0<=n<=7),則該比特在別名區的地址為:1 AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*40X42000000 是外設位帶別名區的起始地址, 0x40000000 是外設位帶區的起始地址,(A-0x40000000)表示該比特前面有多少個字節,一個字節有 8 位,所以*8,一個位膨脹后是 4 個字節,所以*4, n 表示該比特在 A 地址的序號,因為一個位經過膨脹后是四個字節,所以也*4。

2. SRAM 位帶別名區地址:

      對于 SRAM 位帶區的某個比特,記它所在字節的地址為 A,位序號為 n(0<=n<=7),則該比特在別名區的地址為:1 AliasAddr= =0x22000000+ (A-0x20000000)*8*4 +n*4公式分析同上。

3. 統一公式:

      為了方便操作,我們可以把這兩個公式合并成一個公式,把“位帶地址+位序號”轉換成別名區地址統一成一個宏。


// 把“位帶地址+位序號”轉換成別名地址的宏

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

      addr & 0xF0000000 是為了區別 SRAM 還是外設,實際效果就是取出 4 或者 2,如果是外設,則取出的是 4, +0X02000000 之后就等于 0X42000000, 0X42000000 是外設別名區的起始地址。如果是 SRAM,則取出的是 2, +0X02000000 之后就等于 0X22000000,0X22000000 是 SRAM 別名區的起始地址。

      addr & 0x00FFFFFF 屏蔽了高三位,相當于減去 0X20000000 或者 0X40000000,但是為什么是屏蔽高三位?因為外設的最高地址是: 0X2010 0000,跟起始地址 0X20000000 相減的時候,總是低 5 位才有效,所以干脆就把高三位屏蔽掉來達到減去起始地址的效果,具體屏蔽掉多少位跟最高地址有關。 SRAM 同理分析即可。 <<5 相當于*8*4, <<2 相當于*4,這兩個我們在上面分析過。

      最后我們就可以通過指針的形式操作這些位帶別名區地址,最終實現位帶區的比特位操作。


// 把一個地址轉換成一個指針

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

// 把位帶別名區地址轉換成指針

#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))

11.2 GPIO 位帶操作:

      外設的位帶區,覆蓋了全部的片上外設的寄存器,我們可以通過宏為每個寄存器的位都定義一個位帶別名地址,從而實現位操作。但這個在實際項目中不是很現實,也很少人會這么做,我們在這里僅僅演示下 GPIO 中 ODR 和 IDR 這兩個寄存器的位操作。

      從手冊中我們可以知道 ODR 和 IDR 這兩個寄存器對應 GPIO 基址的偏移是 20 和 16,我們先實現這兩個寄存器的地址映射, 其中 GPIOx_BASE 在庫函數里面有定義。

1. GPIO 寄存器映射:

代碼 9 GPIO ODR 和 IDR 寄存器映射


// GPIO ODR 和 IDR 寄存器地址映射

#define GPIOA_ODR_Addr (GPIOA_BASE+20)

#define GPIOB_ODR_Addr (GPIOB_BASE+20)

#define GPIOC_ODR_Addr (GPIOC_BASE+20)

#define GPIOD_ODR_Addr (GPIOD_BASE+20)

#define GPIOE_ODR_Addr (GPIOE_BASE+20)

#define GPIOF_ODR_Addr (GPIOF_BASE+20)

#define GPIOG_ODR_Addr (GPIOG_BASE+20)

#define GPIOH_ODR_Addr (GPIOH_BASE+20)

#define GPIOI_ODR_Addr (GPIOI_BASE+20)

#define GPIOJ_ODR_Addr (GPIOJ_BASE+20)

#define GPIOK_ODR_Addr (GPIOK_BASE+20)

#define GPIOA_IDR_Addr (GPIOA_BASE+16)

#define GPIOB_IDR_Addr (GPIOB_BASE+16)

#define GPIOC_IDR_Addr (GPIOC_BASE+16)

#define GPIOD_IDR_Addr (GPIOD_BASE+16)

#define GPIOE_IDR_Addr (GPIOE_BASE+16)

#define GPIOF_IDR_Addr (GPIOF_BASE+16)

#define GPIOG_IDR_Addr (GPIOG_BASE+16)

#define GPIOH_IDR_Addr (GPIOH_BASE+16)

#define GPIOI_IDR_Addr (GPIOI_BASE+16)

#define GPIOJ_IDR_Addr (GPIOJ_BASE+16)

#define GPIOK_IDR_Addr (GPIOK_BASE+16)

       現在我們就可以用位操作的方法來控制 GPIO 的輸入和輸出了,其中宏參數 n 表示具體是哪一個 IO 口, n(0,1,2...16)。這里面包含了端口 A~K ,并不是每個單片機型號都有這么多端口,使用這部分代碼時,要查看你的單片機型號,如果是 176pin 的則最多只能使用到 I 端口。

2. GPIO 位操作:

代碼 10 GPIO 輸入輸出位操作


// 單獨操作 GPIO 的某一個 IO 口, n(0,1,2...16),n 表示具體是哪一個 IO 口

#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) //輸入

#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //輸出

#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //輸入

#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //輸出

#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //輸入

#define PJout(n) BIT_ADDR(GPIOJ_ODR_Addr,n) //輸出

#define PJin(n) BIT_ADDR(GPIOJ_IDR_Addr,n) //輸入

#define PKout(n) BIT_ADDR(GPIOK_ODR_Addr,n) //輸出

#define PKin(n) BIT_ADDR(GPIOK_IDR_Addr,n) //輸入

3. 主函數:

        該工程我們直接從 LED-庫函數 操作移植過來,有關 LED GPIO 初始化和軟件延時等函數我們直接用,修改的是控制 GPIO 輸出的部分改成了位操作。該實驗我們讓相應的 IO口輸出高低電平來控制 LED 的亮滅,負邏輯點亮。具體使用哪一個 IO 和點亮方式由硬件平臺決定。

代碼 11 main 函數


int main(void)

{

/* LED 端口初始化 */

LED_GPIO_Config();

while (1) {

// PH10 = 0,點亮 LED

PHout(10)= 0;

SOFT_Delay(0x0FFFFF);

// PH10 = 1,熄滅 LED

PHout(10)= 1;

SOFT_Delay(0x0FFFFF);

}

}


關鍵字:STM32  GPIO  位帶操作 引用地址:再造STM32---第十一部分:GPIO—位帶操作

上一篇:再造STM32---第十二部分:啟動文件詳解
下一篇:再造STM32---第十部分:GPIO輸入—按鍵檢測

0

推薦閱讀

機器人手臂十幾秒能做出一杯香濃的拿鐵咖啡,人形機器人能與人自如對答,在人工智能技術的賦能下,機器正在變得越來越智能。正在上海舉行的2018世界人工智能大會以“人工智能賦能新時代”為主題,為人們展現出這些機器與人在未來實現交互的景象。?記者在現場看到,阿里巴巴、騰訊、商湯科技等數十家中國科技企業展示了包括人臉識別、自動駕駛技術、可視化...
本章參考資料:《STM32F4xx 中文參考手冊》系統配置控制器以及中斷和事件章節。上一章節我們已經詳細介紹了 NVIC,對 STM32F4xx 中斷管理系統有個全局的了解,我們這章的內容是 NVIC 的實例應用,也是 STM32F4xx 控制器非常重要的一個資源。 學習本章時,配合《STM32F4xx 中文參考手冊》系統配置控制器以及中斷和事件章節...
據上海發布公眾號消息,今日,上海市政府與華為公司深化戰略合作框架協議簽約暨華為青浦研發中心項目開工儀式舉行。市委副書記、市長龔正,華為公司董事長梁華出席。市委常委、副市長吳清,華為公司高級副總裁任樹錄代表雙方簽約。雙方還共同啟動了青浦研發中心項目,并察看了項目沙盤。根據框架協議,雙方將堅持“務實高效,合作共贏”的原則,在集成電路...
您的工人在不知不覺中是否暴露于有害氣體中,即使使用個人防護設備時也是如此?在為可能存在有毒氣體危害的環境中的工人推薦呼吸防護時,安全專業人員會考慮很多因素。但是,一個被忽視的因素是工人使用的有毒有害氣體檢測儀的測量范圍。為什么這么重要?NIOSH根據潛在的暴露量(百萬分之一)來建議使用不同級別的個人防護設備(PPE)。讓我們以氨(NH3)...

史海拾趣

問答坊 | AI 解惑

最新IPHONE周邊配件設計

本帖最后由 jameswangsynnex 于 2015-3-3 20:01 編輯 …

查看全部問答∨

編寫無錯C程序秘訣

[ 本帖最后由 daicheng 于 2009-3-3 10:14 編輯 ]…

查看全部問答∨

DOS下RS485雙機通訊

問題有三: DOS下232串口編程和485串口編程有區別否,能通用嗎? DOS下BC31寫485通訊需要注意些什么? 有好點的類庫推薦下嗎? 謝謝!PS:我的雙機是兩個PC104…

查看全部問答∨

求教:DS生成的中斷驅動程序

WIN2000下用DS編寫ISA卡的帶9號中斷的驅動程序 用SOFTICE進行調試 INTOBJ看見中斷39處是中斷服務程序 用idt 39 看不到中斷 服務程序 用GENINT 39軟件出發中斷,能過進入中斷服務程序 可是讓驅動程序運行后卻截獲不到任何關于9號中斷的信息 這 ...…

查看全部問答∨

LM3S9B96 能好買嗎?多少一片啊?

TI那里沒貨申請不到哦! 市場上現在好買嗎? 大概什么價格啊?…

查看全部問答∨

關于MSP430G2231晶振問題

用示波器測P1.0腳觀察ACLK輸出,發現波形不是方波,頻率一直在變從8HZ變到26K,難道是我芯片壞了嗎?用萬用表測試沒有燒,在線等求助…

查看全部問答∨

最近學習UART時老看到PSC,那PSC是什么東西呢?

最近學習UART是老是看到PSC如:UART_PSC、MCF_PSC_PSCSICR(channel) = MCF_PSC_PSCSICR_SIM_UART; 這個PSC是什么東西,我怎么在手冊上找不到啊,搜索好像也沒有什么號的解釋呢,求解,謝謝!…

查看全部問答∨

死循環的發生

在使用launchpad仿真時MSP430G2553時經常會出現變量參數溢出導致死循環,有沒有哪位兄弟出現過這種問題啊, 例如void delay(uchar num) { while(num) num--; } 經常進入這里導致死循環。大家討論下關于什么情況下會出現死循環吧…

查看全部問答∨

multisim 12的問題 急急急急急急急

下載12安裝后    進入      顯示無法連接 datebase  數據庫   ,problem :Accessing the datebase   有大牛能解決嗎?????? 而且卸載后重新安裝也不好使     & ...…

查看全部問答∨
小廣播
添点儿料...
无论热点新闻、行业分析、技术干货……
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 大石桥市| 抚松县| 霍邱县| 寿宁县| 邵阳市| 南丹县| 海安县| 滦南县| 高阳县| 宜宾市| 锦州市| 石泉县| 亳州市| 菏泽市| 两当县| 云浮市| 体育| 新化县| 时尚| 上杭县| 东兴市| 镇原县| 西藏| 乌海市| 平顶山市| 江川县| 麻栗坡县| 图木舒克市| 昆明市| 清丰县| 泸州市| 高清| 资阳市| 甘洛县| 江油市| 巴中市| 宝丰县| 清流县| 安庆市| 霍林郭勒市| 衡阳县|