在KE系列MCU中使用BME实现GPIO的位读写

Document created by J.h. Tong Employee on Sep 28, 2016
Version 1Show Document
  • View in full screen mode

在KE系列MCU中提供了多种寄存器用于实现GPIO的控制:

   -PDOR寄存器,用于写入或读取IO的输出状态

   -PSOR寄存器,用于置位IO口

   -PCOR寄存器,用于清零IO口

   -PTOR寄存器,用于翻转IO口

   -PDIR寄存器,用于读取IO口的输入状态

 

当我们想要将PTA0置1时,有多种方法可以选择:

   1. 直接操作寄存器,PDOR或PSOR都可以实现:

         GPIOA->PDOR |= 0x0001;

         GPIOA->PSOR |= 0x0001;

         直接操作寄存器的效率更高,但可读性较差。

   2. 使用官方的库函数操作

      GPIO_PinSet(GPIOA, GPIO_PTA0);

      库函数的可读性很好,但显得有些啰嗦,字符较多。

 

通过KE的BME来实现GPIO的操作能够很好的解决上面的问题,只用将附件中的头文件gpio_bitdef.h包含到工程里,再调用里边的宏定义就可以了。

对PTA0置位和清零可以使用下面的语句:

POUTA0 = -1;

POUTA0 = 0;

读取PTA0的输入状态则可以使用:

tmp = PINA0;

上面的语句是不是看上去简洁了很多呢。

 

实际上上面GPIO的读写指令,是通过BME的BFI(位域插入)和BFX(位域提取)指令来实现的。

-其中ADDR是存储空间内的地址,我们最终操作的还是GPIO的寄存器,因此在两个指令中分别取GPIOA的PDOR寄存器地址和PDIR寄存器地址。

-bit则表示需要插入或提取位域的起始位置,由于这里是PTA0,PTA0位于寄存器的最低位,因此这里填入了0。

-width则表示需要插入或提取位域的宽度,我们只对单个管脚进行操作,也就是单个位进行操作,宽度自然就是1了。

 

需要注意的是,BFI(位域插入)指令在插入时,是将对应位插入到目的地址。因此,如果直接为POUTxx赋值为1的话,有可能出现错误。

POUTA0 = 0x01;//正确

POUTA1 = 0x02;//正确

POUTA2 = 0x04;//正确

POUTA1 = 0x01;//错误

为了避免这种情况,我们可以在IO口需要置位时,直接将POUTxx赋值为-1,即0xFFFF FFFF,这样保证了每一位的值都为1。

 

#define BME_BFI(ADDR,bit,width)        (*(volatile uint32_t *)((((uint32_t)ADDR&0xFFFF))   \
                                  | (5 <<28)  \
                                  | ((bit)<<23) | ((width-1))<<19))

#define BME_BFX(ADDR,bit,width)        (*(volatile uint32_t *)(((uint32_t)ADDR&0xFFFF)    \
                                  | (5 <<28)  \
                                  | ((bit)<<23) | ((width-1))<<19)) 


#define POUTA0 BME_BFI(&GPIOA->PDOR,0,1)

#define PINA0 BME_BFX(&GPIOA->PDIR,0,1)

Attachments

Outcomes