搜索
bottom↓
回复: 11

MQX4.0:MK60DZ10.h头文件GPIO模块代码分析——转帖

[复制链接]

出0入0汤圆

发表于 2014-8-28 08:38:59 | 显示全部楼层 |阅读模式
/* ----------------------------------------------------------------------------
   -- GPIO
   ---------------------------------------------------------------------------- */
/**
* @addtogroup GPIO_Peripheral GPIO
* @{
*/
/** GPIO - Peripheral register structure */
typedef struct GPIO_MemMap {
&nbsp; uint32_t PDOR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Data Output Register, offset: 0x0 */
&nbsp; uint32_t PSOR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Set Output Register, offset: 0x4 */
&nbsp; uint32_t PCOR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Clear Output Register, offset: 0x8 */
&nbsp; uint32_t PTOR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Toggle Output Register, offset: 0xC */
&nbsp; uint32_t PDIR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Data Input Register, offset: 0x10 */
&nbsp; uint32_t PDDR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /**< Port Data Direction Register, offset: 0x14 */
} volatile *GPIO_MemMapPtr;
/* ----------------------------------------------------------------------------
   -- GPIO - Register accessor macros
   ---------------------------------------------------------------------------- */
/**
* @addtogroup GPIO_Register_Accessor_Macros GPIO - Register accessor macros
* @{
*/

/* GPIO - Register accessors */
#define GPIO_PDOR_REG(base)                      ((base)->PDOR)
#define GPIO_PSOR_REG(base)                      ((base)->PSOR)
#define GPIO_PCOR_REG(base)                      ((base)->PCOR)
#define GPIO_PTOR_REG(base)                      ((base)->PTOR)
#define GPIO_PDIR_REG(base)                      ((base)->PDIR)
#define GPIO_PDDR_REG(base)                      ((base)->PDDR)
/**
* @}
*/ /* end of group GPIO_Register_Accessor_Macros */

/* ----------------------------------------------------------------------------
   -- GPIO Register Masks
   ---------------------------------------------------------------------------- */
/**
* @addtogroup GPIO_Register_Masks GPIO Register Masks
* @{
*/
/* PDOR Bit Fields */
#define GPIO_PDOR_PDO_MASK                       0xFFFFFFFFu
#define GPIO_PDOR_PDO_SHIFT                      0
#define GPIO_PDOR_PDO(x)                         (((uint32_t)(((uint32_t)(x))<<GPIO_PDOR_PDO_SHIFT))&GPIO_PDOR_PDO_MASK)
/* PSOR Bit Fields */
#define GPIO_PSOR_PTSO_MASK                      0xFFFFFFFFu
#define GPIO_PSOR_PTSO_SHIFT                     0
#define GPIO_PSOR_PTSO(x)                        (((uint32_t)(((uint32_t)(x))<<GPIO_PSOR_PTSO_SHIFT))&GPIO_PSOR_PTSO_MASK)
/* PCOR Bit Fields */
#define GPIO_PCOR_PTCO_MASK                      0xFFFFFFFFu
#define GPIO_PCOR_PTCO_SHIFT                     0
#define GPIO_PCOR_PTCO(x)                        (((uint32_t)(((uint32_t)(x))<<GPIO_PCOR_PTCO_SHIFT))&GPIO_PCOR_PTCO_MASK)
/* PTOR Bit Fields */
#define GPIO_PTOR_PTTO_MASK                      0xFFFFFFFFu
#define GPIO_PTOR_PTTO_SHIFT                     0
#define GPIO_PTOR_PTTO(x)                        (((uint32_t)(((uint32_t)(x))<<GPIO_PTOR_PTTO_SHIFT))&GPIO_PTOR_PTTO_MASK)
/* PDIR Bit Fields */
#define GPIO_PDIR_PDI_MASK                       0xFFFFFFFFu
#define GPIO_PDIR_PDI_SHIFT                      0
#define GPIO_PDIR_PDI(x)                         (((uint32_t)(((uint32_t)(x))<<GPIO_PDIR_PDI_SHIFT))&GPIO_PDIR_PDI_MASK)
/* PDDR Bit Fields */
#define GPIO_PDDR_PDD_MASK                       0xFFFFFFFFu
#define GPIO_PDDR_PDD_SHIFT                      0
#define GPIO_PDDR_PDD(x)                         (((uint32_t)(((uint32_t)(x))<<GPIO_PDDR_PDD_SHIFT))&GPIO_PDDR_PDD_MASK)
/**
* @}
*/ /* end of group GPIO_Register_Masks */

/* GPIO - Peripheral instance base addresses */
/** Peripheral PTA base pointer */
#define PTA_BASE_PTR                             ((GPIO_MemMapPtr)0x400FF000u)
/** Peripheral PTB base pointer */
#define PTB_BASE_PTR                             ((GPIO_MemMapPtr)0x400FF040u)
/** Peripheral PTC base pointer */
#define PTC_BASE_PTR                             ((GPIO_MemMapPtr)0x400FF080u)
/** Peripheral PTD base pointer */
#define PTD_BASE_PTR                             ((GPIO_MemMapPtr)0x400FF0C0u)
/** Peripheral PTE base pointer */
#define PTE_BASE_PTR                             ((GPIO_MemMapPtr)0x400FF100u)
/* ----------------------------------------------------------------------------
   -- GPIO - Register accessor macros
   ---------------------------------------------------------------------------- */
/**
* @addtogroup GPIO_Register_Accessor_Macros GPIO - Register accessor macros
* @{
*/

/* GPIO - Register instance definitions */
/* PTA */
#define GPIOA_PDOR                               GPIO_PDOR_REG(PTA_BASE_PTR)
#define GPIOA_PSOR                               GPIO_PSOR_REG(PTA_BASE_PTR)
#define GPIOA_PCOR                               GPIO_PCOR_REG(PTA_BASE_PTR)
#define GPIOA_PTOR                               GPIO_PTOR_REG(PTA_BASE_PTR)
#define GPIOA_PDIR                               GPIO_PDIR_REG(PTA_BASE_PTR)
#define GPIOA_PDDR                               GPIO_PDDR_REG(PTA_BASE_PTR)
/* PTB */
#define GPIOB_PDOR                               GPIO_PDOR_REG(PTB_BASE_PTR)
#define GPIOB_PSOR                               GPIO_PSOR_REG(PTB_BASE_PTR)
#define GPIOB_PCOR                               GPIO_PCOR_REG(PTB_BASE_PTR)
#define GPIOB_PTOR                               GPIO_PTOR_REG(PTB_BASE_PTR)
#define GPIOB_PDIR                               GPIO_PDIR_REG(PTB_BASE_PTR)
#define GPIOB_PDDR                               GPIO_PDDR_REG(PTB_BASE_PTR)
/* PTC */
#define GPIOC_PDOR                               GPIO_PDOR_REG(PTC_BASE_PTR)
#define GPIOC_PSOR                               GPIO_PSOR_REG(PTC_BASE_PTR)
#define GPIOC_PCOR                               GPIO_PCOR_REG(PTC_BASE_PTR)
#define GPIOC_PTOR                               GPIO_PTOR_REG(PTC_BASE_PTR)
#define GPIOC_PDIR                               GPIO_PDIR_REG(PTC_BASE_PTR)
#define GPIOC_PDDR                               GPIO_PDDR_REG(PTC_BASE_PTR)
/* PTD */
#define GPIOD_PDOR                               GPIO_PDOR_REG(PTD_BASE_PTR)
#define GPIOD_PSOR                               GPIO_PSOR_REG(PTD_BASE_PTR)
#define GPIOD_PCOR                               GPIO_PCOR_REG(PTD_BASE_PTR)
#define GPIOD_PTOR                               GPIO_PTOR_REG(PTD_BASE_PTR)
#define GPIOD_PDIR                               GPIO_PDIR_REG(PTD_BASE_PTR)
#define GPIOD_PDDR                               GPIO_PDDR_REG(PTD_BASE_PTR)
/* PTE */
#define GPIOE_PDOR                               GPIO_PDOR_REG(PTE_BASE_PTR)
#define GPIOE_PSOR                               GPIO_PSOR_REG(PTE_BASE_PTR)
#define GPIOE_PCOR                               GPIO_PCOR_REG(PTE_BASE_PTR)
#define GPIOE_PTOR                               GPIO_PTOR_REG(PTE_BASE_PTR)
#define GPIOE_PDIR                               GPIO_PDIR_REG(PTE_BASE_PTR)
#define GPIOE_PDDR                               GPIO_PDDR_REG(PTE_BASE_PTR)
/**
* @}
*/ /* end of group GPIO_Register_Accessor_Macros */

/**
* @}
*/ /* end of group GPIO_Peripheral */&nbsp;
上述代码是K60芯片的GPIO模块相关头文件定义,这里结合硬件手册 K60P100M100SF2RM 对该部分代码进行简要分析。

软件结构分析:
        1、“struct GPIO_MemMap {  }”:GPIO模块内存映射结构体,该结构体定义了一系列“GPIO端口控制寄存器”的名称,利用结构体本身的“平坦特性”与GPIO模块中实际寄存器的相对地址一一对应,实现结构体内部变量操作对物理地址操作的映射(这里只实现了相对映射,完全映射需要有绝对地址,下面会看到),各寄存器含义可结合注释以及K60P100M100SF2RM 文件54.2 Memory map and register definition章节。
        2、“#define GPIO_PDOR_REG(base)     ((base)->PDOR)”:GPIO模块内部控制寄存器变量宏定义,该宏定义接收结构体指针,返回寄存器变量
        3、“#define GPIO_PDOR_PDO_MASK    0xFFFFFFFFu”:GPIO模块寄存器内部位域屏蔽码,根据硬件操作手册对端口各个寄存器的各个位域进行定义,详见K60P100M100SF2RM 文件54.2.1 Port Data Output Register(GPIOx_PDOR)章节。
        4、“#define PTA_BASE_PTR     ((GPIO_MemMapPtr)0x400FF000u)”:定义GPIO模块A端口的寄存器组基地址0x400FF000u,该CPU中对各个寄存器的配置本质上是对内存映射地址的配置。上面讲到逻辑操作对物理地址的映射问题时,只能实现相对映射,这里的绝对地址定义就是为实现地址绝对映射。GPIO_MemMapPtrr是GPIO寄存器组的强制类型转换,与结构体“structGPIO_MemMap {  }”共同作用,表示基地址和偏移地址,这样就能通过结构体变量来操控该寄存器组中的任意硬件寄存器,对于其他GPIO定义也是类似。
        5、“#define GPIOA_PDOR      GPIO_PDOR_REG(PTA_BASE_PTR)”:各个GPIO端口的内部寄存器变量定义,便于后期使用,与硬件手册相关。
硬件特性分析:
       1、关于各个寄存器的功能,可参见绿色注释和硬件手册。K60的GPIO模块与内核之间通过“零等待状态接口”来发挥引脚的最大性能,可以任意数据大小来操作GPIO寄存器。GPIOx_PDOR寄存器内容与引脚状态直接相关,如果想改变引脚状态可以给该寄存器赋值,但是K60的特殊之处在于并非直接操作该寄存器(它只是一个数据存放的场所而已),而是提供了“设置”、“清除”和“取反”三个寄存器,用来改变GPIOx_PDOR状态,这就是“零等待”的实现关键。通常情况下,设置寄存器位就要用到“位或”指令,清除寄存器位就要用到“位与”指令,该类指令的操作执行就需要消耗cpu时间(取数,位与,赋值),为了最大程度降低“操作延时”,直接通过“入口寄存器”操作数据(赋值),提高性能。
       2、GPIO端口的数据操作也是受时钟时序影响的,从微观角度讲,作为输入口时当外部引脚电平变化并不会“瞬间”影响到GPIO输入寄存器的数值,只有当GPIO模块时钟边沿到来时,该状态改变才能体现到寄存器中。虽然这个时间非常短暂,但是并不能忽视它的存在,对于输出口也是如此。
       3、关于GPIO操作还有很多选项需要配置,例如“端口上拉”、“滤波使能”、“滤波时钟”、“中断设置”、“端口复用”和“输出强度”等等,就需要设置SIM模块、中断模块、PORT模块等,共同实现GPIO的复杂功能。
       4、如果GPIO配置成输入,则必须要打开PORT模块和中断模块中的相关信息;如果不需要输入功能,可以关闭这两个模块中的GPIO相关设置信息,达到节能的目的。如果GPIO配置成输出,则PORT模块和中断模块中的相关信息不需要打开,就可以配置引脚状态。

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-8-28 09:06:05 | 显示全部楼层
了解了解,以前从不关注.h文件

出0入0汤圆

发表于 2014-8-28 11:04:09 | 显示全部楼层
嗯,把好帖子都转过来哈

出0入0汤圆

发表于 2014-8-28 13:26:54 | 显示全部楼层
再顶楼主

出0入0汤圆

 楼主| 发表于 2014-8-28 13:31:59 | 显示全部楼层
qinshiysb 发表于 2014-8-28 11:04
嗯,把好帖子都转过来哈

资源快利用光了············

出0入0汤圆

发表于 2014-8-28 20:47:25 | 显示全部楼层
谢谢分享,楼主厉害呀

出0入0汤圆

发表于 2014-8-29 00:10:21 | 显示全部楼层
感谢分享啊,好帖子

出0入0汤圆

发表于 2014-8-29 13:54:36 | 显示全部楼层
楼主很是厉害,注释比较详细哦

出0入0汤圆

发表于 2014-8-29 16:20:05 | 显示全部楼层
又见楼主转帖

出0入0汤圆

发表于 2014-8-29 16:22:14 | 显示全部楼层
谢谢分享,楼主厉害呀

出0入0汤圆

发表于 2014-8-29 16:36:14 | 显示全部楼层
期待楼主分享其他模块。。

出0入0汤圆

发表于 2014-9-4 16:19:23 | 显示全部楼层
mark                        
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 02:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表