本帖最后由 yzai 于 2015-9-2 16:51 编辑
程序实例来自韦东山老师教学实例
S3C2440:130个IO管脚,除了A口的控制寄存器GPACON有25位,且是每位控制一个IO管脚外, 其他口的控制寄存器GPxCON都是两位控制一个对应的IO管脚,见图
#define GPFCON (*(volatile unsigned long *)0x56000050)//给寄存器设置地址:(volatile unsigned long *)0x56000050表示 volatile unsigned long型指针指向地址0x56000050,volatile表示不会因编译器的优化而省略, *(volatile unsigned long *)0x56000050表示指针操作,最终该语句表示将GPFCON定义为 指针 操作,即 #define GPFCON *p=&a ,(unsigned long a volatile unsigned long *p , a的内存地 址为0x56000050 ) #define GPFDAT (*(volatile unsigned long *)0x56000054)//IO口数据寄存器,该寄存器的每一位对应一个IO口管脚
#define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064)
/*
* LED1,LED2,LED4对应GPF4、GPF5、GPF6
*/ #define GPF4_out (1<<(4*2))//1向左移8位,#define GPF4_out 01 0000 0000 #define GPF5_out (1<<(5*2))//1向左移10位,#define GPF5_out 0100 0000 0000 #define GPF6_out (1<<(6*2))//1向左移12位,#define GPF6_out 01 0000 0000 0000
#define GPF4_msk (3<<(4*2))//11向左移8位,#define GPF4_msk 11 0000 0000 #define GPF5_msk (3<<(5*2))//11向左移10位,#define GPF4_msk 1100 0000 0000 #define GPF6_msk (3<<(6*2))//11向左移12位,#define GPF4_msk 11 0000 0000 0000
/* * S2,S3,S4对应GPF0、GPF2、GPG3 */ #define GPF0_in (0<<(0*2)) //0向左移0位,#define GPF0_in 0 #define GPF2_in (0<<(2*2)) //0向左移4位,#define GPF2_in 0 0000 #define GPG3_in (0<<(3*2)) //0向左移6位,#define GPG3_in 000 0000
#define GPF0_msk (3<<(0*2)) //11向左移0位,#define GPF0_msk 11 #define GPF2_msk (3<<(2*2)) //11向左移4位,#define GPF2_msk 11 0000 #define GPG3_msk (3<<(3*2)) //11向左移6位,#define GPG3_msk 1100 0000
int main() { unsigned long dwDat; // LED1,LED2,LED4对应的3根引脚设为输出 GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);//对应位清零操作 与-反操作,过程如下: // ~(GPF4_msk | GPF5_msk | GPF6_msk)=~(11 0000 0000|1100 0000 0000|11 0000 0000 0000) // =00 0000 1111 1111,GPFCON &00 0000 1111 1111=xx00 0000 xxxx xxxx GPFCON |= GPF4_out | GPF5_out | GPF6_out; //对应位赋值操作 或操作,过程如下: // GPF4_out | GPF5_out | GPF6_out=(1 0000 0000|100 0000 0000|1 0000 0000 0000) //=1 0101 0000 0000,GPFCON |1 0101 0000 0000=xx00 0000 xxxx xxxx|1 0101 0000 0000 // =xx01 0101 xxxx xxxx,即GPFCON=xx01 0101 xxxx xxxx F口的第4、5、6管脚设置为输出状态
// S2,S3对应的2根引脚设为输入 GPFCON &= ~(GPF0_msk | GPF2_msk); //对应位清零,GPFCON=xxxx xxxx xx00 xx00 GPFCON |= GPF0_in | GPF2_in; //对应位赋值,GPFCON|0 0000=xxxx xxxx xx00 xx00 F口的第0、2管脚设置为输入状态
// S4对应的引脚设为输入 GPGCON &= ~GPG3_msk; //对应位清零,GPGCON=xxxx xxxx 00xx xxxx GPGCON |= GPG3_in; //对应位赋值,GPGCON|000 0000=xxxx xxxx 00xx xxxx G口的第3管脚设置为输入状态 while(1){ //若Kn为0(表示按下),则令LEDn为0(表示点亮) dwDat = GPFDAT; // 读取GPF管脚电平状态
if (dwDat & (1<<0)) // 若F口第0管脚输入1,即对应按键未被按下 GPFDAT |= (1<<4); // 则F口第4管脚输出1,即对应灯熄灭 else GPFDAT &= ~(1<<4); // 则F口第4管脚输出0,即对应灯点亮
if (dwDat & (1<<2)) // 若F口第2管脚输入1,即对应按键未被按下 GPFDAT |= (1<<5); // 则F口第5管脚输出1,即对应灯熄灭 else GPFDAT &= ~(1<<5); // 则F口第5管脚输出0,即对应灯点亮
dwDat = GPGDAT; // 读取GPG管脚电平状态
if (dwDat & (1<<3)) // 若G口第3管脚输入1,即对应按键未被按下 GPFDAT |= (1<<6); // 则F口第6管脚输出1,即对应灯熄灭 else GPFDAT &= ~(1<<6); // 则F口第6管脚输出0,即对应灯点亮 }
return 0; } //综上,对于GPFCON等两位对应一个IO口管脚的寄存器,应先清零才能赋值;对于GPFDAT等一位对应一个IO口管脚的寄存器,不用先清零就能赋值;
|