打印
[嵌入式linux]

树莓派底层编程-GPIO篇

[复制链接]
2079|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cedar_renjun|  楼主 | 2015-10-27 02:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
树莓派底层编程-GPIO篇0 前言
本来是准备写一篇用python控制GPIO的例子,结果发现太简单了,还是深入一些吧,多深入底层
接下来,我会按照下面的顺序来介绍:
1)GPIO控制器地址映射
2)GPIO主要控制寄存器介绍
3)GPIO操作流程
4)用C语言控制GPIO
6)用python来控制GPIO
1 概述
树莓派2B采用的CPU为BCM2836,外设部分和BCM2835完全一致,所以就可以参考BCM2835的寄存器手册
但是,这个寄存器手册笔误有点多,建议配合着wiki的勘误手册来看
CPU总共有54个IO,每个IO都可以复用,配置输入或者输出模式,单从GPIO部分来看,比较简单,无非是输入/输出,触法模式等,和一般的MCU没有太大差异
2 地址映射
BCM2835将BUS的地址空间,通过MMU映射到线性寻址空间,如下所示

这里,我们从左到右看,IO Peripherals的基地址为0x7E000000,然后映射后的基地址为0x20000000
也就是说外设的地址空间为0x20000000~0x20FFFFFF
接下来,在手册中,找到GPIO章节,查看寄存器地址,如下所示

比如GPFSEL0寄存器的BUS地址为0x7E200000,也就是说相对偏移为0x00200000,所以我们可以知道映射后的GPIO基地址为
0x20200000(0x20000000 + 0x00200000),其它寄存器的地址以此类推
3 寄存器介绍
解决了GPIO寄存器地址问题,下面就需要知道如何控制GPIO,大致浏览GPIO章节,发现相当简单,GPIO的主要功能有
  • 外设模式
  • GPIO模式
  • 输出/输出
  • 上拉/下拉
  • 事件监测(上升沿/下降沿/边缘变化/高电平/低电平)
下面简单介绍GPIO相关寄存器
  • GPFSELn(n=0/1/2/3/4)
    用于选择GPIO管脚的模式是IO输出还是输入或者是复用
  • GPSETn
    设置IO输出值,写1有效,表示置高对应管脚
  • GPCLRn
    设置IO输出值,写1有效,表示置低对应管脚
  • GPLEVn
    IO当前值,用于读入当前的电平值
  • GPEDSn
    也就是所谓的事件标志位,可以通过该位来检查是否有事件发生,写1清零
  • GPRENn/GPRENn/GPHENn/GPLENn
    用于设置IO的事件模式,比如上升沿/下降沿/跳变/高电平/低电平触发方式,触发事件后,会发送一个中断信号给CPU
    从而实现中断机制
  • GPPUD/GPPUDCLKn
    上拉/下拉配置寄存器,这个比较特殊,CPU不会保存这个配置状态,需要用户用软件来配置并保存,配置掉电不丢失,同时,
    系统只提供两个相关寄存器,所以配置时需要采用复用模式,并遵循特定的配置方式和延时,具体参见手册介绍
总共就这么多寄存器,介绍完毕,下面说一下操作流程
4 操作流程
对于普通的IO来说,无非就是输入或者输出,输入模式下,可以轮询或者中断;输出模式下,往对应管脚寄存器里写1/0即可
输出配置
  • 通过GPFSELn设置输出模式
  • 往GPSETn寄存器写1,表示在对应管脚输出高电平
  • 往GPCLRn寄存器写0,表示在对应管脚输出低电平
  • 可以通过GPLEVn来读取当前输出值
输入配置
  • 通过GPFSELn设置输入模式
  • 通过GPPUD/GPPUDCLKn设置上拉或者下拉模式
  • (可选)通过GPRENn/GPRENn/GPHENn/GPLEN设置事件模式
  • 可以通过GPLEVn来读取当前输出值
5 用C语言控制IO6 用python语言控制IO参考资料

相关帖子

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

本版积分规则

16

主题

150

帖子

5

粉丝