打印
[开发资料]

GPIO位输出操作的几种方法

[复制链接]
33|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mikewalpole|  楼主 | 2025-7-24 22:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、端口位设置/清除

   可对BSRR、BRR寄存器相应的位置1,以实现置位和清零操作,如:

  GPIOA->BSRR = (1<<3);          // 设置端口A的位3为1

  GPIOA->BRR  = (1<<3);          // 清除端口A的位3为0




2、端口直接输出

   可对ODR寄存器相应的位置1或0,以实现置位和清零操作,如:  

  GPIOA->ODR |=  (1<<3);        // 端口A的位3输出1

  GPIOA->ODR &= ~(1<<3);        // 端口A的位3输出0




3、端口位带输出

  参考《Cortex-M3 权威指南》第五章,第5小节 位带操作(87页~92页)。

  为简化位带操作,可以定义一些宏。比如,我们可以建立一个把“位带地址+位序号”转换成别名地址的宏, 再建立一个把别名地址转换成指针类型的宏。  


  //1):把“位带地址+位序号”转换成别名地址的宏

  #define     BITBAND(addr, bitnum)    ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))

  //2):把该地址转换成一个指针

  #define     MEM_ADDR(addr)        *((volatile unsigned long *) (addr))

  //3):使用位带别名地址访问

  #define     BIT_ADDR(addr, bitnum)    MEM_ADDR(BITBAND(addr, bitnum))


  应用如下:



  #define  PAout(n)  BIT_ADDR((uint32_t)&GPIOA->ODR, n)

    

  PAout(3) = 1;    //端口A的位3输出1

  PAout(3) = 0;    //端口A的位3输出0




4、端口位域输出

  定义一个端口位域  


  #pragma  anon_unions    //以便结构体或共用体无需另起名字

  

  typedef union{

    uint32_t WORDS;

    struct{

      int    bit00    :1;

      int    bit01    :1;

      int    bit02    :1;

      int    bit03    :1;

      int    bit04    :1;

      int    bit05    :1;

      int    bit06    :1;

      int    bit07    :1;

      int    bit08    :1;

      int    bit09    :1;

      int    bit10    :1;

      int    bit11    :1;

      int    bit12    :1;

      int    bit13    :1;

      int    bit14    :1;

      int    bit15    :1;

      int    bit16    :1;

      int    bit17    :1;

      int    bit18    :1;

      int    bit19    :1;

      int    bit20    :1;

      int    bit21    :1;

      int    bit22    :1;

      int    bit23    :1;

      int    bit24    :1;

      int    bit25    :1;

      int    bit26    :1;

      int    bit27    :1;

      int    bit28    :1;

      int    bit29    :1;

      int    bit30    :1;

      int    bit31    :1;

      };

  }PORT;



  应用如下:



  #define  PAout03  (((PORT *)(&GPIOA->ODR))->bit03)

  PAout03 = 1;    //端口A的位3输出1
  PAout03 = 0;    //端口A的位3输出0



5、综述

  以上4种方法,1、2两种较为多见;方法3为位带操作,速度最快,但只对具备位带的U有效;方法4是一种新颖的通用方法,只要找到输入或输出寄存器即可,对任意U有效!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

1687

帖子

0

粉丝