目 录
1. 设置引脚的功能(输入、输出、特殊功能);
2. 为引脚赋值、读数据或其他功能。
由于此ARM9不能对位进行操作(至少我目前没有发现类似51中的sbit功能的符号),所以我们必须准确的找到相应的位,相关内容会在后文重点论述。
各IO口的特殊功能,请参考S3C2440的datasheet.
此寄存器用于配置B口 的功能,例如第5口(LED1口)的配置情况如下:
我们可以通过设置GPBCON的第[11:10]为01,使GPB5口为输出口。
初始状态:0x0.
此寄存器可以输出数据也可以读数据。
此寄存器控制相关的引脚是否加上拉电阻(默认加)。
置1表示不加上拉电阻。
初始状态:0x0.
NOTE: 这些寄存器理解起来还是比较简单的,但因为无法直接对位进行操作,控制起来比不简单。
在此之前,先介绍如何对寄存器特定位进行置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将得:
②. ~(0x3<<10)
这样我们就分离了[11:10]位。
③. ~(0x3<<10)& rGPBCON
这样得到的数据中除[11:10]位为0外,其余的位依旧保持了原来的值。
④. rGPBCON = ( ( ~(0x3<<(PIN*2)) ) & rGPBCON ) | (0x1<<10);
(0x1<<10)的值是:
或后,[11:10]=”01”,其它位保持原来的数据不变。
NOTE: 这是我目前想到的方法,如果大家有其它的好思路的话,请notice me.我一定会认真学习的。
【下面的是后来又加的】
【在我写完了,这片文档后,我总觉得自己的这种方法不是那么的直观,我总感觉我可以用指针或找到类似sbit的操作符。于是我看了以前自己用EasyARM1138写的程序,那里面有一项bit_bang技术,实现了对位的操作。里面介绍如下:
】
void GPIOPinTypeIn(U8 PORT, U8 PIN)
{
if(PORT == GPIOB)
rGPBCON =( ( ~(0x3<<(PIN*2)) ) & rGPBCON );
}
void GPIOPinTypeOut(U8 PORT, U8 PIN)
{
if(PORT == GPIOB)
rGPBCON = ( ( ~(0x3<<(PIN*2)) ) & rGPBCON ) | (0x1<<(PIN*2) );
}
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 每一个寄存器的地址都是32位的,而每一位都代表了一个字节(即8位)。【17:06】
1.2 如果要对某一位操作,先将改为置1,然后整体取反,这样会导致该位为0,其余的都是1,然后和原来的数据进行“与”操作,这样其余位保持原来的数据不变,目标为为0.
1.3 在对寄存器操作时,记住0x11,代表00010001,写时很容易理解成00000011,注意。
2.1 PORT还需要再写写。
本文及其他我写的文章,皆是鄙人学习总结笔记。文中内容我会尽最大的努力保证正确,如你发现bug,请一定要通知我,我会按您的指导进行Debug。
我相信交流是提高技术最好的方法。
用户379271 2011-6-9 13:02