K20引脚众多,几乎每个引脚都有复用功能,芯片上电复位后,大多数引脚处于Disable状态,必须进行相关配置选择特定功能才可使用。由于K20绝大多数寄存器是32位的,所以直接读写寄存器很痛苦,道理很简单,要进行设置往往只有那么几位,其他无关位的值绝对不能修改的,这样就很麻烦,既要修改目标值,又要保持其他值不表。还好飞思卡尔公司发布的K20头文件—MK20DX256VLL.h中有大量的宏帮助开发人员完成这项繁琐的工作。举个例子说明一下,大家看这样一条语句
PORTC_PCR5=PORT_PCR_MUX(0x1); //PTC5的第1功能
使用鼠标右键的 go to definition 功能,一个一个搜索,首先是
PORTC_PCR5,可以看到:
#define PORTC_PCR5 PORT_PCR_REG(PORTC_BASE_PTR,5)
PORTC_PCR5 是一个宏,再次使用go to definition 功能,查看
PORT_PCR_REG,可以看到:
#define PORT_PCR_REG(base,index) ((base)->PCR[index])
这是一个带参数的宏,将参数替换可知PORTC_PCR5等同于:
PORTC_BASE_PTR->PCR[5],最终指向的是端口C(PORTC)第5引脚的
PCR 寄存器(PCR,PinControlRegister,引脚控制寄存器),这是一个
32 位的寄存器,负责选择引脚的复用功能。再看等号右侧的语句
PORT_PCR_MUX(0x1),这也是一个宏:
#define PORT_PCR_MUX(x)
(((uint32_t)(((uint32_t)(x))<<PORT_PCR_MUX_SHIFT))&PORT_PCR_MUX_MASK)
后面两个也是宏:
#define PORT_PCR_MUX_MASK 0x700u
#define PORT_PCR_MUX_SHIFT 8
将参数替换等效于(((uint32_t)(((uint32_t)(0x1))<<8))&0x700u)
其中0x700u中的u是unsigned的意思,和0x700等效,(uint32_t)
是强制类型转换,这样理顺一下,原先的语句就划归成这样:
PORTC_BASE_PTR->PCR[5]=
(((uint32_t)(((uint32_t)(0x1))<<8))&0x700u);
等号右侧的操作是这样的,先把0x1变成32位数据(因为寄存器是
32位的),左移8位之后再变成32位数据(此处是防止数据溢出的保
险措施), 最后和0x700 进行按位相与(按位与&和按位或|是实现单
独改写某位而不影响其他位的一种方法,至于为什么可以这样做 ,自
己算算吧!)。 这样一系列操作的结果就是把端口C第5引脚的PCR
寄存器的第8、9、10位改写成001,其他配置不变,大家注意看手
册:
PCR寄存器的8、9、10位就是负责设定引脚功能的MUX
从表中可以看到第1功能是PTC5,也就是最基本的输入输出功能。
希望大家用心体会上面讲的方法,灵活使用go to definition功能,
戒骄戒躁,一句一句用心研究。读硬件程序是一件枯燥又有趣的事情,
个中滋味深入其中才能有所体会。
言归正传,下面的讲解中将不会再对具体的语句进行解释,重点
将放在模块关键属性的设置上,希望大家举一反三,自己研读例程序,
分析思考,汲取养分。
|