Freescale k60的GPIO的操作

来源:互联网 发布:淘宝手机主图视频制作 编辑:程序博客网 时间:2024/04/28 12:52

电子创新网提供的代码对于GPIO的操作有这样的一段,通过分析这句程序来确定对于K60GPIO的操作。

GPIOA_PDOR&=~GPIO_PDOR_PDO(GPIO_PIN(10));    //PTA10对应D12

1GPIO_PIN(10)

#define GPIO_PIN(x)              (((1)<<(x & GPIO_PIN_MASK)))

#define GPIO_PIN_MASK            0x1Fu

2GPIO_PDOR_PDO()

#define GPIO_PDOR_PDO(x)                         (((uint32_t)(((uint32_t)(x))<<GPIO_PDOR_PDO_SHIFT))&GPIO_PDOR_PDO_MASK)

#define GPIO_PDOR_PDO_MASK                       0xFFFFFFFFu

#define GPIO_PDOR_PDO_SHIFT                      0

3GPIOA_PDOR

/* 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)

 

4/* 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)

 

5/** GPIO - Peripheral register structure */

typedef struct GPIO_MemMap {
  uint32_t PDOR;                                   /**< Port Data Output Register, offset: 0x0 */
  uint32_t PSOR;                                   /**< Port Set Output Register, offset: 0x4 */
  uint32_t PCOR;                                   /**< Port Clear Output Register, offset: 0x8 */
  uint32_t PTOR;                                   /**< Port Toggle Output Register, offset: 0xC */
  uint32_t PDIR;                                   /**< Port Data Input Register, offset: 0x10 */
  uint32_t PDDR;                                   /**< Port Data Direction Register, offset: 0x14 */
} volatile *GPIO_MemMapPtr;

 

6/* 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)

结合(3~6)的内容,我们可以看到/* GPIO - Register instance definitions */实际上就是对GPIO相关的寄存器的一种例化,

GPIOA_PDOR 实际上就是指定到PTA所对应的寄存器Port Data Output Register

GPIOA_PDOR&=~GPIO_PDOR_PDO(GPIO_PIN(10));    //PTA10对应D12

所以上面的例程中的语句左边实际上是指定操作的寄存器,右边是对寄存器赋值。

下面我们重点学习一下K60  datasheet中对于GPIO寄存器的描述

GPIOx_PDORGPIOx_PSORGPIOx_PCORGPIOx_PDIRGPIOx_PDDR

详见datasheet的1743页

下面我们分析例程中的赋值部分:

GPIO_PDOR_PDO(GPIO_PIN(10))

1GPIO_PIN(10)

#define GPIO_PIN(x)              (((1)<<(x & GPIO_PIN_MASK)))

#define GPIO_PIN_MASK            0x1Fu

2GPIO_PDOR_PDO()

#define GPIO_PDOR_PDO(x)                         (((uint32_t)(((uint32_t)(x))<<GPIO_PDOR_PDO_SHIFT))&GPIO_PDOR_PDO_MASK)

#define GPIO_PDOR_PDO_MASK                       0xFFFFFFFFu

#define GPIO_PDOR_PDO_SHIFT                      0

 

GPIO_PIN_MASK的值为:31,所以x & GPIO_PIN_MASK的结果是对于x的值的限制,确保x小于等于31。

GPIO_PIN(x)的含义将1左移(x & GPIO_PIN_MASK)位,从而保证对应的要操作的寄存器的位为1,其他位为0.

之后

GPIO_PDOR_PDO(GPIO_PIN(x))再对上一步的结果移位限幅输出即可。

所以GPIOA_PDOR&=~GPIO_PDOR_PDO(GPIO_PIN(10)等号右侧含义是对于GPIO的32位寄存器的第10位先置1,其余位为0,之后整体取反得到等式右边的结果为:

32‘b 1111 1111 1111 1111 1111 1101 1111 1111,于是再将这样的一个32位的数据复制给等式右侧确定的GPIOA_PDOR,此即通过PTA10输出0,从而点亮D12.

 

/**
 * @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)

 

———————————————————————————————————————————

————————————————总                                结—————————————————

———————————————————————————————————————————

上面的理解过程中产生了一些理解上的误差只要是对左移和右移运算符不是特别的熟悉,

左移运算符和右移运算符的操作数均在左侧,GPIO_PIN(x)的定义中是对1进行左移操作。

 

原创粉丝点击