原创 S3C2440-GPIO口的学习与总结

2011-6-4 00:23 3607 4 5 分类: MCU/ 嵌入式


1         简介

1.1       IO的操作主要包括两个方面:

1. 设置引脚的功能(输入、输出、特殊功能);

2. 为引脚赋值、读数据或其他功能。

1.2       难点:

由于此ARM9不能对位进行操作(至少我目前没有发现类似51中的sbit功能的符号),所以我们必须准确的找到相应的位,相关内容会在后文重点论述。

1.3       IO口数量及特殊功能:

20110603085802001.jpg

IO口的特殊功能,请参考S3C2440datasheet.

2         寄存器(GPIOB为参考)

2.1       GPBCON

此寄存器用于配置B 的功能,例如第5口(LED1口)的配置情况如下:

20110603085803002.jpg

我们可以通过设置GPBCON的第[11:10]01,使GPB5口为输出口。

初始状态:0x0.

2.2       GPBDAT

此寄存器可以输出数据也可以读数据。

2.3       GPBUP

此寄存器控制相关的引脚是否加上拉电阻(默认加)。

1表示不加上拉电阻。

初始状态:0x0.

NOTE: 这些寄存器理解起来还是比较简单的,但因为无法直接对位进行操作,控制起来比不简单。

3         相关操作函数

在此之前,先介绍如何对寄存器特定位进行置1、置0操作。

一般一个寄存器都含有4个字节即32个位。寄存器的定义如下:

#define rGPBCON    (*(volatile unsigned *)0x56000010) //Port B control

首先,理解一下这个语句。在一般情况下,我们定义pointer

unsigned int *a; a是指向unsigned int类型数据的指针,它本身是一个内存地址。那么我们就可以理解上面的那个语句了。内存地址0x56000010中储存了unsigned类型的变量,而且这一变量的值是直接读取内存得到的。rGPBCON是内存地址为0x56000010中的数据,4个字节,32位。

      如果我们不知道此时这32位各存有什么数据,而我们又想将其中的第11位置0、第10位置1,应如何操作。

流程如下:

①.  0x3<<10将得:

20110603085803003.jpg

②.  ~0x3<<10

20110603085807004.jpg

这样我们就分离了[11:10]位。

③.  ~0x3<<10& rGPBCON

这样得到的数据中除[11:10]位为0外,其余的位依旧保持了原来的值。

④.  rGPBCON  = ( ( ~(0x3<<(PIN*2)) ) & rGPBCON ) | (0x1<<10);

(0x1<<10)的值是:

20110603085808005.jpg

或后,[11:10]=”01”,其它位保持原来的数据不变。

NOTE: 这是我目前想到的方法,如果大家有其它的好思路的话,请notice me.我一定会认真学习的。

 

  【下面的是后来又加的】

  【在我写完了,这片文档后,我总觉得自己的这种方法不是那么的直观,我总感觉我可以用指针或找到类似sbit的操作符。于是我看了以前自己用EasyARM1138写的程序,那里面有一项bit_bang技术,实现了对位的操作。里面介绍如下:

20110603085813006.jpg

20110603085815007.jpg

20110603085819008.jpg

3.1       设置引脚为输入类型

void GPIOPinTypeIn(U8 PORT, U8 PIN)

{

      if(PORT == GPIOB)

             rGPBCON =( ( ~(0x3<<(PIN*2)) ) & rGPBCON );

}

3.2       设置引脚为输出类型

void GPIOPinTypeOut(U8 PORT, U8 PIN)

{

      if(PORT == GPIOB)

             rGPBCON  = ( ( ~(0x3<<(PIN*2)) ) & rGPBCON ) | (0x1<<(PIN*2) );

}

3.3       写数据

void GPIOPinWrite(U8 PORT, U8 PIN, U8 data)

{

      if(PORT == GPIOB)

             if(data == ON)

                    rGPBDAT =( ~(0x1<<PIN) & rGPBDAT );

             if(data == OFF)

                 rGPBDAT = ( (~(0x1<<PIN) )& rGPBDAT )| (0x1<< PIN);

}

 

 

 

 

 

 

 

附录

1、             写之前的准备

1.1       每一个寄存器的地址都是32位的,而每一位都代表了一个字节(即8位)。【17:06

1.2       如果要对某一位操作,先将改为置1,然后整体取反,这样会导致该位为0,其余的都是1,然后和原来的数据进行“与”操作,这样其余位保持原来的数据不变,目标为为0.

1.3       在对寄存器操作时,记住0x11,代表00010001,写时很容易理解成00000011,注意。

2、             还需改进的地方

2.1       PORT还需要再写写。

声明:

本文及其他我写的文章,皆是鄙人学习总结笔记。文中内容我会尽最大的努力保证正确,如你发现bug,请一定要通知我,我会按您的指导进行Debug

我相信交流是提高技术最好的方法。

文章评论1条评论)

登录后参与讨论

用户379271 2011-6-9 13:02

首先,感谢EDN网站将此博文评为“博客精华”,同时也感谢网友们的支持。但这篇博文还有很多地方写的不够好,比如一些常用的函数并未写完整。 关于GPIO口常用的函数,可以参考我的另一篇博文 《S3C2440-GPIO口常用函数总结》,里面进行了较详细的阐述,并给出了常用函数的源代码。
相关推荐阅读
用户379271 2011-11-09 11:16
【S3C2440学习笔记】ADC&触摸屏
1         硬件原理图 触摸屏的电路还是比较复杂的,暂时先不考虑其具体电路,我们先总结出和CPU相连的管脚。   管脚 ...
用户379271 2011-10-31 15:34
怀念以前的EDNchina,怀念以前的气氛。
       今天好不容易将uboot-1.1.6移植到TQ2440上,本来想写篇博客总结一下,却怎么也找不到自己的博客了。登录之后,却满目狼藉。不想说什么了,不久前,就知道合并的事了,本希望它好...
用户379271 2011-10-21 08:23
Uboot在Nand Flash和SDRAM中的地址映射
1         我的困惑 (1)  .lds文件到底起什么作用 (2)  start.o中初始化和文字池的关系(汇编语言问题),以及的那几个变量的作用 注:本文是基于u-boot-1.1.6编写...
用户379271 2011-10-21 08:18
学习Uboot时的思考
其实,我在10月5日的时候就开始看Uboot了,但由于自己当时还不会ARM汇编,所以放下Uboot开始学习ARM汇编。之后又学习《ARM体系结构与编程》中的前五章的知识点,又写了一些小的验证理论的程...
用户379271 2011-10-17 00:41
指令LDR与伪指令LDR
1         指令LDR 应用举例: u       LDR R0, [R1, #4]     ;将内存单元R1+4中的字读取到R0寄存器 其中,R1为基址,#4为偏移地址,R0为目标地址。注...
用户379271 2011-10-13 07:21
ARM指令集学习笔记
目  录 1    ARM汇编指令格式... 3 2        数据处理指令... 4 3        存储器访问指令... 4 4        分支指令... 4 5        软中...
我要评论
1
4
关闭 站长推荐上一条 /2 下一条