设为首页收藏本站

Discuz! Board

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 7123|回复: 1
打印 上一主题 下一主题

青风tm4c讲座第三讲:gpio的驱动,点亮led灯

[复制链接]

13

主题

24

帖子

184

积分

注册会员

Rank: 2

积分
184
跳转到指定楼层
楼主
wanqin_002 发表于 2013-9-24 11:11:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wanqin_002 于 2013-9-24 11:14 编辑

4.1 GPIO的驱动与开发
    4.11 原理分析:
        大家之前学习过51单片机,也使用过IO口。与51IO进行对比,Cortex M4IO配置有点区别。51不需要设置IO口为输入或者输出,除了做为输入捕获,基本就是作为输出端口进行使用了。而Cortex M4IO口有多种状态需要设置,那么下面我们就一一道来:
           I/O(Input/Output)接口是一颗微控制器必须具备的最基本外设功能。在TM4C系列ARM里,所有I/O都是通用的,称为GPIO(General Purpose Input/Output)。      GPIO模块由14个物理GPIO块组成,一块对应一个GPIO端口(PA、PB、PC、PD、PE、PF、PG、PHPJPKPLPMPNPP)。每个GPIO端口包含多个管脚,如PA端口是PA0~PA7。GPIO模块遵循FiRM(Foundation IP for Real-Time Microcontrollers)规范,并且支持多达105个可编程输入/输出管脚(具体取决于与GPIO复用的外设的使用情况)。
          下图给出了GPIO模块各个端口相应寄存器的结构图,大家看懂这个结构图,也就对GPIO口的操作有了整体的了解。
                     图1:数字/模拟IO结构图
         比如:port control寄存器控制端口输入和输出,Date control控制数据量。详细的说明大家参考datasheet。如果TI没有给出函数库,那么编写程序进行寄存器配置就是很重要的一环。
          在inc/tm4c123gh6pz.h文件中对tm4c123gh6pz(LM4F232)寄存器进行了全面的配置,TI的这个头文件采取的是一次列举的方式分配寄存器地址的。有的32ARM的头文件则采取的是结构体的方式分配地址的。
        那么谈到GPIO的使用,我们最重点注意的还是IO端口状态的配置。GPIO的寄存器配置常用的有:
        数据寄存器操作,数据方向操作,中断操作,端口模式操作 等等。
        如果大家直接操作响应寄存器是可以的,但是TI配备了完整的函数库,使用函数库进行操作就变的很简单了。这也是我们下面的软件编程中要详细介绍的。
        在TM4C系列ARM里,GPIO管脚可以被配置为多种工作模式,其中有3种比较常用:高阻输入、推挽输出、开漏输出。这三种模式,大家在模电数电中已经有过了解了:
    1. 高阻输入(Input)
如图2所示,为GPIO管脚在高阻输入模式下的等效结构示意图。这是一个管脚的情况,其它管脚的结构也是同样的。输入模式的结构比较简单,就是一个带有施密特触发输入(Schmitt-triggered input)的三态缓冲器(U1),并具有很高的输入等效阻抗。
                                                                              
                                  图2:高阻输入
   2.推挽输出(Output)
   如图3所示,为GPIO管脚在推挽输出模式下的等效结构示意图。U1是输出锁存器,执行GPIO管脚写操作时,在写脉冲(Write Pulse)的作用下,数据被锁存到Q和/Q。T1和T2构成CMOS反相器,T1导通或T2导通时都表现出较低的阻抗,但T1和T2不会同时导通或同时关闭,最后形成的是推挽输出。在Stellaris系列ARM里,T1和T2实际上是多组可编程选择的晶体管,驱动能力可配置为2mA、4mA、8mA,以及带转换速率(Slew Rate)控制的8mA驱动。
               
                                  图3:推挽输出
   3.开漏输出(OutputOD)
如图4所示,为GPIO管脚在开漏输出模式下的等效结构示意图。开漏输出和推挽输出相比结构基本相同,但只有下拉晶体管T1而没有上拉晶体管。同样,T1实际上也是多组可编程选择的晶体管。开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到GND(有一定内阻)。回读功能:读到的仍是输出锁存器的状态,而不是外部管脚Pin的状态。因此开漏输出模式是不能用来输入的。
                     
                                 图4:开漏输出
  当然Cortex  M4  TM4C123gh6pz(LM4F232)的寄存器要比51AVR的单片机寄存器多一些,他所需用的工作状态也要复杂的多,详细的寄存器配置大家可以查看数据手册,这里就不展开了。
4.12 硬件设计:
   实验硬件采用:青风 QF-Hanker  V2.0开发板. 开发板中,我们给出了一个用户LED灯。电路如图所示,通过PC7口进行控制
                                             

                                                        图5:硬件电路图
4.13软件设计:
        学会使用TI的函数库进行编程。我们过去编写51等单片机时是直接配置寄存器的,使用函数库这种方法对于越来越复杂的MCU是非常必须的。Cortex M4部的寄存器比较多,如果去慢慢了解寄存器需要花费大量的时间。而直接使用TI封装好的函数库能够大大减少入门时间,开发者可以集中精力于项目功能的实现,大大缩短了开发时间。当然有时间深入研究的朋友也可以编写自己的函数库,一句话,怎么方便怎么来。
       大家可以查看TI外设函数库驱动文档,对函数库进行详细了解。这里先介绍结构GPIO端口常用的函数:
1.GPIOPadConfigSet  设置指定管脚的配置。
  函数原型:  GPIOPadConfigSet(unsigned long ulPort,
unsigned char ucPins,
unsigned long ulStrength,
unsigned long ulPinType)
参数:
ulPort是GPIO端口的基址。
ucPins是特定管脚的位组合(bit-packed)表示。
ulStrength指定输出驱动强度。
ulPinType指定管脚类型。
描述:
这个函数设置所选GPIO端口指定管脚的驱动强度和类型。对于配置用作输入端口的管脚,端口按照要求配置,但是对输入唯一真正的影响是上拉或下拉终端的配置。
参数ulStrength可以是下面的一个值:
GPIO_STRENGTH_2MA;
GPIO_STRENGTH_4MA;
GPIO_STRENGTH_8MA;
GPIO_STRENGTH_8MA_SC。
在上面的值中,GPIO_STRENGTH_xMA指示2、4或8mA的输出驱动强度;而GPIO_OUT_STRENGTH_8MA_SC指定了带斜率控制(slew control)的8mA输出驱动。
参数ulPinType可以是下面的其中一个值:
GPIO_PIN_TYPE_STD;
GPIO_PIN_TYPE_STD_WPU;
GPIO_PIN_TYPE_STD_WPD;
GPIO_PIN_TYPE_OD;
GPIO_PIN_TYPE_OD_WPU;
GPIO_PIN_TYPE_OD_WPD;
GPIO_PIN_TYPE_ANALOG。
在上面的值中,GPIO_PIN_TYPE_STD*指定一个推挽管脚,GPIO_PIN_TYPE_OD*指定一个开漏管脚,*_WPU指定一个弱上拉,*_WPD指定一个弱下拉,GPIO_PIN_TYPE_ANALOG指定一个模拟输入(对于比较器来说)。管脚用一个位组合(bit-packed)的字节来指定,在这个字节中,置位的位用来识别被访问的管脚,字节的位0代表GPIO端口管脚0、位1代表GPIO端口管脚1等等。
2.GPIODirModeSet:设置指定管脚的方向和模式。
函数原型:void
GPIODirModeSet(unsigned long ulPort,
unsigned char ucPins,
unsigned long ulPinIO)
参数:
ulPort是GPIO端口的基址。
ucPins是管脚的位组合(bit-packed)。
ulPinIO是管脚方向“与/或”模式。
描述:
这个函数在软件控制下将所选GPIO端口的指定管脚设置成输入或输出,或者,也可以将管脚设置成由硬件来控制。
参数ulPinIO是一个枚举数据类型,它可以是下面的其中一个值:
GPIO_DIR_MODE_IN
GPIO_DIR_MODE_OUT
GPIO_DIR_MODE_HW
在上面的值中,GPIO_DIR_MODE_IN表明管脚将被编程用作一个软件控制的输入,GPIO_DIR_MODE_OUT表明管脚将被编程用作一个软件控制的输出,GPIO_DIR_MODE_HW表明管脚将被设置成由硬件进行控制。
管脚用一个位组合(bit-packed)的字节来指定,这里的每个字节,置位的位用来识别被访问的管脚,字节的位0代表GPIO端口管脚0、位1代表GPIO端口管脚1等等。
3.GPIOPinWrite向指定管脚写入一个值。
函数原型:
void
GPIOPinWrite(unsigned long ulPort,
unsigned char ucPins,
unsigned char ucVal)
参数:
ulPort是GPIO端口的基址。
ucPins是管脚的位组合(bit-packed)表示。
ucVal是写入到指定管脚的值。
描述:
将对应的位值写入ucPins指定的输出管脚。向配置用作输入的管脚写入一个值不会产生任何影响。
管脚用一个位组合(bit-packed)的字节来指定,在这个字节中,置位的位用来识别被访问的管脚,字节的位0代表GPIO端口管脚0、位1代表GPIO端口管脚1等等。
下面我们就来点亮其中led,并且不停闪烁,也就是把IO管脚定义为输出
点亮一个led的过程我们可以归纳如下:
   1:配置系统时钟和使能GPIO端口外设,也就是开GPIO功能。
   2:配置GPIO端口驱动电流大小和管脚模式
   3:设置管脚为输出管脚。
   4:设置管脚输出是高电平还是低电平。
那么下面我们开始编写程序:
首先建立工程项目目录如下图所示,具体的建立要求的方法见上一章的快速入门:
由于我们需要使用库函数,因此除了调用我们写的主函数,再就是需要添加封装好的driverlib.lib库函数,这样整个工程项目就建立好了,下面就是来编写主函数了。
       主函数要使用库函数内的函数定义,因此需要调用如下一些函数库头文件:
//-----------------------------------------------------------------------------
// 文件名    : led闪烁
// 作者      : 青风
// ARM内核   : Cortex-M4
// 使用芯片  : LM4F232H5QD/tm4c123gh6pz
// 开发环境  : KEIL
// 版本记录  :  2013-6-10  14:30
//函数功能说明:led不停的闪动
//-----------------------------------------------------------------------------
#include "inc/tm4c123gh6pz.h"  //可以不加
#include <stdint.h>            //定义字符内型
#include <stdbool.h>       //0/1的定义
#include "inc/hw_types.h"    //一些位带操作的宏定义
#include "inc/hw_memmap.h"   //外设基地址的定义
#include "driverlib/sysctl.h" //系统时钟
#include "driverlib/gpio.h"    //gpio定义
/**********************************************/
/* 函数功能;简单的延迟函数                   */
/* 入口参数:无                               */
/**********************************************/
void delay()
{
int i,j;
  for(i=0;i<1000;i++)
  {
for(j=0;j<1000;j++);
}
}
/**********************************************/
/* 函数功能;主函数                           */
/* 入口参数:无                               */
/**********************************************/
int main(void)
{
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ |   SYSCTL_OSC_MAIN);                         //系统时钟设置
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);       // 使能LED所在端口PC
GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_7);
//配置PN.7为led灯输出
    while(1)
   {
GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_7,0);         //灭灯
delay();//延迟
GPIOPinWrite(GPIO_PORTC_BASE,GPIO_PIN_7,GPIO_PIN_7);//亮灯
   delay(); //延迟      
    }
}
下载成功后:led灯开始闪动。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖
回复

使用道具 举报

Archiver|手机版|小黑屋|Comsenz Inc.   

GMT+8, 2024-4-20 08:41 , Processed in 0.188222 second(s), 29 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表