在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的模式配置
最后希望能对大家有所帮助,受本人知识所限,难免有理解不当的地方,欢迎批评指正。