Cortex-M3中GPIO位输出操作的几种方法

1、端口位设置/清除

  在STM32F1xx系列芯片中,可对BSRR、BRR寄存器相应的位置1,以实现置位和清零操作,如:

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

  在LPC17xx系列芯片中,可对FIOSET、FIOCLR寄存器相应的位置1,以实现置位和清零操作,如:

  LPC_GPIO2->FIOSET = (1<<3);      // 设置端口2的位3为1
  LPC_GPIO2->FIOCLR = (1<<3);      // 清除端口2的位3为0

2、端口直接输出

  在STM32F1xx系列芯片中,可对ODR寄存器相应的位置1或0,以实现置位和清零操作,如:  

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

  在LPC17xx系列芯片中,可对FIOPIN寄存器相应的位置1或0,以实现置位和清零操作,如:

  LPC_GPIO2->FIOPIN |=  (1<<3);    // 端口2的位3输出1
  LPC_GPIO2->FIOPIN &= ~(1<<3);    // 端口2的位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))

  应用如下:

  STM32F1xx系列芯片:

  #define  PAout(n)  BIT_ADDR((uint32_t)&GPIOA->ODR, n)      PAout(3) = 1;    //端口A的位3输出1
  PAout(3) = 0;    //端口A的位3输出0

  LPC17xx系列芯片:  

  #define  P2out(n)  BIT_ADDR((uint32_t)&LPC_GPIO2->FIOPIN, n)

  P2out(3) = 1;    //端口2的位3输出1
  P2out(3) = 0;    //端口2的位3输出0

4、端口位域输出

  定义一个端口位域,端口为16位的就定义16位(STM32F1xx),端口为32位的就定义32位(LPC17xx)。  

  #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;

  应用如下:

  STM32F1xx系列芯片:

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

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

  LPC17xx系列芯片:  

  #define  P2out03  (((PORT *)(&LPC_GPIO2->FIOPIN))->bit03)

  P2out03 = 1;    //端口2的位3输出1  P2out03 = 0;    //端口2的位3输出0

  

5、综述

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

  

时间: 2024-10-13 12:00:26

Cortex-M3中GPIO位输出操作的几种方法的相关文章

Android中实现延时执行操作的几种方法

1.使用线程的休眠实现延时操作 new Thread() { @Override public void run() { super.run(); Thread.sleep(3000);//休眠3秒 /** * 要执行的操作 */ } }.start(); 2.使用TimerTask实现延时操作 TimerTask task = new TimerTask() { @Override public void run() { /** *要执行的操作 */ } }; Timer timer = ne

Python中文件的读写操作的几种方法

对文件的操作,步骤为:打开一个文件-->读取/写入内容-->保存文件 文件读写的3中模式 # 1.w 写模式,它是不能读的,如果用w模式打开一个已经存在的文件,会清空以前的文件内容,重新写# w+ 是读写内容,只要沾上w,肯定会清空原来的文件# 2.r 读模式,只能读,不能写,而且文件必须存在# r+ 是读写模式,只要沾上r,文件必须存在# 3.a 追加模式,也能写,在文件的末尾添加内容# 4.rb+.wb+.ab+,这种是二进制模式打开或者读取,一些音乐文件 test1.txt 如果无情的风

第13章 GPIO—位带操作

第13章     GPIO-位带操作 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料:<STM32F4xx 中文参考手册>存储器和总线构架章节.GPIO章节,<Cortex?-M4内核编程手册>2.2.5 Bit-banding.学习本章时,配套这些参考资料学习效果会更佳. 13.1 位带简介 位操作就是可以单独的对一个比特位读和写,这个在51单片机

PHP中获取文件扩展名的N种方法

PHP中获取文件扩展名的N种方法 从网上收罗的,基本上就以下这几种方式: 第1种方法: function get_extension($file) { substr(strrchr($file, '.'), 1); } 第2种方法: function get_extension($file) { return substr($file, strrpos($file, '.')+1); } 第3种方法: function get_extension($file) { return end(expl

Node.JS的表单提交及OnceIO中接受GET/POST数据的三种方法

OnceIO 是 OnceDoc 企业私有内容(文档)管理系统的底层Web框架,它可以实现模板文件.静态文件的全缓存,运行起来完全不需要I/O操作,并且支持客户端缓存优化,GZIP压缩等(只压缩一次),拥有非常好的性能,为您节约服务器成本.它的模块化功能,可以让你的Web进行分布式存储,在一个扩展包里即可包含前端.后端和数据库定义,只需通过添加/删除目录的方式就可实现功能删减,实现真正的模块化扩展.目前 OnceIO 已经开源,本文主要介绍node.js语言中的表单提交及OnceIO中接受GET

rman输出日志的几种方法(转)

在使用rman的时候经常会碰到以下两种场景,需要把rman的日志输出到文件中: 1.显示的日志太多,导致一个屏幕显示不完,影响了问题的诊断,这时候需要把rman的log输出到文本中,整个的诊断过程就相对容易了许多. 2.在使用自动备份的时候,需要把日志输出到文本中,便于第二天进行备份任务的检查: 一.简单的日志数据的脚本 rman target / log /usr/oracle/rman.log 该脚本直接把rman的日志写到/u01/,并命名为rman.log,但是使用这种方法的时候,屏幕不

在Java Web程序中使用监听器可以通过以下两种方法

之前学习了很多涉及servlet的内容,本小结我们说一下监听器,说起监听器,编过桌面程序和手机App的都不陌生,常见的套路都是拖一个控件,然后给它绑定一个监听器,即可以对该对象的事件进行监听以便发生响应,从本质上来说这些都是观察者模式的具体实现,在web程序中的监听器也不例外.在Java Web程序中使用监听器可以通过以下两种方法:通过注解@WebListener来标识一个自定义的监听器:[java] view plain copy@WebListener public class Custom

(转载)Java中如何遍历Map对象的4种方法

在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHashMap, Hashtable, 等等) 方法一 在for-each循环中使用entries来遍历 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer,

PHP中 获取文件扩展名的N种方法

PHP中获取文件扩展名的N种方法,有以下这几种方式:第1种方法:function get_extension($file){substr(strrchr($file, ‘.’), 1);} 第2种方法:function get_extension($file){return substr($file, strrpos($file, ‘.’)+1);} 第3种方法:function get_extension($file){return end(explode(‘.’, $file));} 第4种