在hw_types.h文件下可以找到這樣一段宏定義,然後在打開工程的函數是會發現幾乎所有的對寄存器的配置都是通過這幾
個定義實現的,這就是位帶操作,這種方法可以提高代碼執行效率。
HWREG(x) 定義一個32位無符號指針x,然後在取出它的值,最終得到的是x地址的值,下面的都類似
HWREGH(x) 定義的是16位無符號指針的值
HWREGB(x) 定義的是8位無符號指針的值
HWREGBITW(x,b) 表示獲取x的地址下第b爲的值
下面我將通過對GPIO的配置說明一下如何使用位帶操作對寄存器進行配置。
程序的初始化流程如圖:
先進行外設使能,然後GPIO管腳複用配置,然後管腳初始化,我們先來看看GPIOBankPinMuxDet()函數,打開函數看到如
圖的調用函數,隨便選擇一個,比如第一個繼續打開
然後就會看到函數的源碼如圖:
首先定義了一個 u32 savePinmux 變量,然後用HWREG(x)獲取目標地址下的值,
savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) &~(SYSCFG_PINMUX13_PINMUX13_15_12));
打開 SOC_SYSCFG_0_RGES 可以看到宏定義在soc_OMAPL138.h下,
表示DEV外設的基地址,從數據手冊中可以查到DEV外設主要功能有
1,可讀設備,芯片和芯片ID
2,引腳複用控制
3,總線訪問系統中不同總線主機的優先級
4,上電時捕獲復位芯片BOOT引腳值,並使其可用於軟件
5,控制DeepSleep電源管理功能
6,使能和選擇可編程引腳上拉和下拉
7,外設的特殊情況設置
鎖定PLL控制器設置
EDMA3傳輸控制器的默認發送大小
選擇eCAP模塊輸入捕捉的源
8,控制用於ARM和DSP之間的信號的片上處理器間中斷
9,選擇外設支持的仿真掛起信號源(來自ARM或DSP)
我們配置GPIO就是用到了第二條引腳複用控制
現在我們已經知道了目標設備的基地址,現在還需要知道它控制外設的地址偏移,也就是第二個參數SYSCFG0_PINMUX(13)
它代表在基地址基礎上的地址偏移,我們可以在hw_syscfg0_OMAPL138.h中找到所有的外設相對於基地址的偏移宏定義。
SYSCFG0_PINMUX(13) 在圖中可知偏移地址是( 0x120 + 13 * 4 )
已經找到了目標外設的地址,然後就是對每一位進行設置,已完成預期功能
savePinmux = 基地址的值&~(SYSCFG_PINMUX13_PINMUX13_15_12),
找到SYSCFG_PINMUX13_PINMUX13_15_12的宏定義 #define SYSCFG_PINMUX13_PINMUX13_15_12 (0x0000F000u)
現在我們就明白它的意思是對 SYSCFG_PINMUX13_PINMUX13_15_12 取反再與外設地址取與,
目的是對 savePinmux [15:12]位清0。
最終我們搞明白了
savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) &
~(SYSCFG_PINMUX13_PINMUX13_15_12));
的功能,就是對把 (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13) 的[15:12]清0
那麼繼續看下一句
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) =
(PINMUX13_GPIO6_12_ENABLE | savePinmux);
先看 PINMUX13_GPIO6_12_ENABLE 的宏定義
#define PINMUX13_GPIO6_12_ENABLE (SYSCFG_PINMUX13_PINMUX13_15_12_GPIO6_12 << \
SYSCFG_PINMUX13_PINMUX13_15_12_SHIFT)
可以知道改宏的值是
SYSCFG_PINMUX13_PINMUX13_15_12_GPIO6_12 << SYSCFG_PINMUX13_PINMUX13_15_12_SHIFT
如圖
從前面知道在 SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13) 這個寄存器下管理者PINMUX13 這一組的GPIO引腳控制
,當我們僅需要配置其中一個是,就需要用到改Pin相對有首地址的偏移 SYSCFG_PINMUX13_PINMUX13_15_12_SHIFT
(注意這個偏移是該寄存器內部bit位的偏移)
同時需要選擇該pin對應的控制寄存器爲的值來確定配置的功能,
在這裏我們選擇了 SYSCFG_PINMUX13_PINMUX13_15_12_GPIO6_12 功能
最後和清空的 savePinmux 取或 ,即完成了GPIO的模式配置
最後希望能對大家有所幫助,受本人知識所限,難免有理解不當的地方,歡迎批評指正。