作者|釜薪君
公众号|嵌入式杂牌军
文章目录
- 前言
- 一、这种意识的来源
- 二、实现源码分析
- 1.函数调用
- 2.宏定义部分
- 3.函数实现
- 4.宏替换后的函数调用
- 总结
前言
今天带小伙伴们分析一段不错的代码,学习一下关于宏封装的一种意识,希望对大家有所帮助哈,阅读过程中如果有什么问题,可以后台留言哈!
一、这种意识的来源
此代码来源于RT1052官方的SDK源码,不管是什么芯片,只要有类似的操作都可以这样去使用,代码的功能是对RT1052的GPIO进行配置的,下面我就带小伙伴们追本溯源一下,一起培养一下这个意识。
二、实现源码分析
1.函数调用
看到下面的函数调用你可能感觉没啥!这就是函数调用嘛!继续往下看吧!
IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U);
2.宏定义部分
看到这里你会发现,这个宏怎么一大串用逗号隔开的数据。再往下看看函数定义吧!
#define IOMUXC_GPIO_EMC_00_SEMC_DATA00 0x401F8014U, 0x0U, 0, 0, 0x401F8204U
#define IOMUXC_GPIO_EMC_01_SEMC_DATA01 0x401F8018U, 0x0U, 0, 0, 0x401F8208U
#define IOMUXC_GPIO_EMC_02_SEMC_DATA02 0x401F801CU, 0x0U, 0, 0, 0x401F820CU
#define IOMUXC_GPIO_EMC_03_SEMC_DATA03 0x401F8020U, 0x0U, 0, 0, 0x401F8210U
3.函数实现
代码实现如下,不需要理解其意思看形式就行。
static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
uint32_t muxMode,
uint32_t inputRegister,
uint32_t inputDaisy,
uint32_t configRegister,
uint32_t inputOnfield)
{
*((volatile uint32_t *)muxRegister) =
IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
if (inputRegister)
{
*((volatile uint32_t *)inputRegister) = inputDaisy;
}
}
我们可以看到参数经过了处理,地址赋值等操作。
我们同时可以发现,一些参数就是另一些参数的处理后的配置值,这个意识get到了吧?
4.宏替换后的函数调用
既然是宏我们手动去替换一下,然后去追本溯源看看它到底是个啥吧!
IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U);
IOMUXC_SetPinMux(0x401F8014U, 0x0U, 0, 0, 0x401F8204U, 0U);
我们到芯片手册去追本溯源一下吧!
401F8014这个十六进制数据,在芯片手册用“_”隔开才能找到,即你需要搜索401F_8014,得到的结果如下。
找到,再去寄存器部分看看就知道这个地址对应的寄存器都进行了啥配置了,它是个引脚复用寄存器,用于设置输入是否软件可读,引脚复用的功能。
第二个参数0x0U,是设置复用模式的编号,用作复用模式0,即ALT0,它的功能时将此引脚用作SEMC_DATA00,即SEMC控制的SDRAM的数据引脚0。
下面的三个0具体没用过,跳过啦。
401F8204是另一寄存器的地址值,当然是需要转换为地址的,到芯片手册去搜下401F_8204,结果如下。
看芯片可以知道这是对此引脚的速度、压摆率、内部上下拉、滞回等引脚相关的配置。
分析到最后我们可以知道这个函数是如何进行GPIO引脚功能的配置了,比较特殊的是,NXP官方将所有GPIO的引脚功能(包括各种复用)都整成了一个宏,如IOMUXC_GPIO_EMC_00_SEMC_DATA00,它是见名知意的你用那个引脚的什么功能就去找到这个宏用函数进行配置即可。
它也留了一个可以配置的参数inputOnfield,它可以配置输入是否软件可读。即把固定的内容用宏封装好,根据功能进行调用,将不固定的内容,设为独立的参数。
总结
以上就是今天的分享,大家不要局限于对上面内容的理解,get到上面的意识是最重要的。
以后你在编程中可以将相关的操作用宏进行整体功能封装,前期可能耗时,但后期好维护。
提醒一下:数组赋值也可以用宏进行封装哈,它也是用逗号隔开的,大家试着去迁移一下吧!
欢迎关注公众号~
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)