Chinaunix首页 | 论坛 | 博客
  • 博客访问: 182426
  • 博文数量: 63
  • 博客积分: 725
  • 博客等级: 军士长
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-12 19:55
文章分类

全部博文(63)

文章存档

2012年(35)

2011年(28)

分类: 嵌入式

2011-05-27 19:00:44

一、什么是GPIO

 

GPIO,英文全称为General-Purpose IO ports,也就是通用IO口。嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。对这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制器芯片上一般都会提供一个通用可编程IO接口,即GPIO

 

接口至少有两个寄存器,即通用IO控制寄存器通用IO数据寄存器。数据寄存器的各位都直接引到芯片外部,而对这种寄存器中每一位的作用,即每一位的信号流通方向,则可以通过控制寄存器中对应位独立的加以设置。这样,有无GPIO接口也就成为微控制器区别于微处理器的一个特征。

 

    在实际的MCU中,GPIO是有多种形式的。比如,有的数据寄存器可以按照位寻址,有些却不能按照位寻址,这在编程时就要区分了。比如传统的8051系列,就区分成可位寻址和不可位寻址两种寄存器。另外,为了使用的方便,很多mcuglue logic等集成到芯片内部,增强了系统的稳定性能,比如GPIO接口除去两个标准寄存器必须具备外,还提供上拉寄存器,可以设置IO的输出模式是高阻,还是带上拉的电平输出,或者不带上拉的电平输出。这在电路设计中,外围电路就可以简化不少。

  

另外需要注意的是,对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的端口的概念。如果是内存映射,那就方便的多了。

举个例子,比如像寄存器A(地址假定为0x48000000)写入数据0x01,那么就可以这样设置了。

 #define A (*(volatile unsigned long *)0x48000000)
...
    A = 0x01;
...

    这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。上述表达式拆开来分析,首先(volatile unsigned long *)0x48000000的意思是把0x48000000强制转换成volatile unsigned long类型的指针,暂记为p,那么就是#define A *p,即AP指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作。

  

二、S3C2410GPIO的特点

   s3c2410GPIO117pin,下面应该到9 IO ports看看详细部分了。

The S3C2410X has 117 multi-functional input/output port pins. The ports are:
— Port A (GPA): 23-output port
— Port B (GPB): 11-input/output port
— Port C (GPC): 16-input/output port
— Port D (GPD): 16-input/output port
— Port E (GPE): 16-input/output port
— Port F (GPF): 8-input/output port
— Port G (GPG): 16-input/output port
— Port H (GPH): 11-input/output port 

    这么多的IO口,其实很多是复合功能的,既可以作为普通的IO口使用,也可以作为特殊外设接口。在程序设计时,要对整体的资源有所规划,初始化时就应该把所有资源安排合理。这样才会避免出现问题。 

    现在的8个端口,其寄存器是相似的。除了两个通用寄存器GPxCONGPxDAT外,还提供了GPxUP用于确定是否使用内部上拉电阻(其中xA-H,需要注意的是没有GPAUP)。应用的主要步骤就是: 

    ·设置GPIO控制寄存器GPxCON

    ·设置GPIO上拉寄存器GPxUP

初始化完成后,就可以通过对GPxDAT的操作来实现相应的应用了。其中,PORT APORT B-H在功能选择方面有所不同,GPACON的每一位对应一根引脚(共23pin有效)。当某位设为0,相应引脚为输出引脚,此时往GPADAT中写0/1,可以让引脚输出低电平/高电平;当某位设为1,则相应引脚为地址线,或者用于地址控制,此时GPADAT没有用了。

一般而言,GPACON通常全设为1,以便访问外部存储器件。PORT B-H在寄存器操作方面完全相同。

GPxCON中每两位控制一根引脚:00表示输入,01表示输出,10表示特殊功能,11保留。GPxDAT用于读/写引脚:当引脚设为输入时,读此寄存器可知相应引脚状态是高/低;当引脚设为输出时,写此寄存器相应位可以使相应引脚输出低电平或高电平。GPxUP:某位设为0,相应引脚无内部上拉;为1,相应引脚使用内部上拉。关于特殊功能,那就得结合特殊外设来进行设置了。

 

基本实验

实验18段数码管显示,共四位

 

我的开发板上没有多余的GPIO插头,只好利用液晶的显示的插口了,对应的引脚:

VD[07] 对应 GPC[815]     VD[823] 对应 GPD[015]

   四个共阴极的数码管,选择信号对应GPC[811]

   8段显示数据对应GPD[07]

这样一来就可以利用这四个数码管显示数字了

1)软件架构仿照了vivi,或者Linux Kernel。其实写这么小的程序用不到这么麻烦,但是可以训练这种架构,为写中型大型程序打好基础。

    2)注意C语言下实现寄存器读写的(*(volatile unsigned long *)(addr))。其实就是要掌握volatile和指针的用法。

    3)写c时,要注意头文件如何处理。写Makefile时,要注意是否采用隐含规则,如果不采用,就要自己定义明确规则,就像vivi里面的Rules.make。在这里,因为只是涉及到.s的编译不采用隐含规则,所以没有把Rules.make单独拿出,事实上可以单独写为Rules.make,然后在Makefile后加入include Rules.make就可以了。

    4)要调用C子程序,必须分配堆栈空间。因为子程序调用时,要进行入栈出栈处理。又因为从nand flash启动,而nand flashS3C2410下的特点规定堆栈不能超过4K

阅读(1230) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~