您的位置:首页 > 其它

自己学驱动11——简单GPIO操作

2015-02-10 13:50 288 查看
1.对于GPIO的操作

对于GPIO的操作,通常是通过读写其相应的寄存器来实现的,S3C2440也是如此。比如,S3C2440的GPBCON和GPBDAT寄存器的地址分别是0x56000010和0x56000014,可以通过如下的指令让GPB5输出低电平。

#define GPBCON (*(volatile unsigned long *)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

GPBCON = (1<<(5*2)); //GPB5设置为输出

GPBDAT &= ~(1<<5); //GPB5输出低电平

对于寄存器的读与此类此,不举例说明。

2.NOR Flash操作注意点

假设开发板上NOR Flash的片选信号使用2440的nGCS0,当CPU发出的地址信号处于0x00000000~0x07ffffff之间时,nGCS0信号有效,NOR Flash被选中。需要注意的是NOR Flash在实际使用中多数以16位为单位读写,即2440的ADDR1~ADDR20与NOR Flash的A0~A19对应相连。

注意以下几种操作:

(1)地址对齐的16位读操作。

unsigned short pwAddr = (unsigned short *)0x2;

unsigned short wVal;

wVal = *pwAddr;

这段代码2440将0x2传送给NOR Flash时会读取到NOR Flash中的0x1处16位的数据(NOR Flash设置为word模式,每个地址对应的数据为16位),所以当2440要读取0x0~0x1均读取的是NOR Flash中0x0的数据,而当2440要读取0x2~0x3的数据时实际读取的是NOR Flash中0x1地址的数据。

(2)地址不对齐的16位读操作。

当2440传入的地址为0x1类似的地址时,由于地址不是按2对齐的,所以会导致异常。一般可以通过设置异常处理函数来处理这种情况,在异常函数中,使用0x0和0x2发起两次读操作,然后将两个结果各取一字节组合起来得到需要的数据。

(3)8位读操作。

unsigned char pwAddr = (unsigned char *)0x2;

unsigned char wVal;

wVal = *pwAddr;

CPU读取数据之后会自动丢弃D1,假设读到的数据为D0和D1。

(4)32位读操作。

unsigned int pwAddr = (unsigned int *)0x2;

unsigned int wVal;

wVal = *pwAddr;

CPU会首先使用地址0x2对NOR Flash发起一次读操作,然后使用0x4对NOR Flash发起一次读操作,最后将两次读取到的数据合并并且赋值给wVal,这个过程完全由处理器硬件机制完成对于程序员来说是不可见的。

(5)16位写操作。

由于NOR Flash的特性,使得对NOR Flash的写操作比较复杂——比如要先发出特定的地址信号通知NOR Flash准备接收数据,然后才能发出数据等。不过,其总线上的电信号与软件指令的关系与读操作类似,只是数据的传输方向相反。

unsigned short *pwAddr = (unsigned shrot *)0x6;

*pwAddr = 0x1234;

3.最简单的点灯程序(程序均烧写到Nand Flash中)

(1)汇编版

led.S源码:

.text

.global _start

_start:

LDR R0, =0x56000010

MOV R1, #0x00000400

STR R1, [R0]

LDR R0, =0x56000014

MOV R1, #0x00000000

STR R1, [R0]

MAIN_LOOP:

B MAIN_LOOP

可以看出,程序中所做的工作就是将GPB5设置为输出,然后再输出0,最后是一个死循环。

以上汇编代码对应的Makefile(编译连接等命令放于其中)为:

led.bin:led.S

arm-linux-gcc -g -c -o led.o led.S

arm-linux-ld -Ttext 0x0000000 -g led.o -o led_elf

arm-linux-objcopy -O binary -S led_elf led.bin

clean:

rm -f led.bin led_elf *.o

注:其中arm-linux-gcc指令中的-g选项表示生成本地调试信息,而-c选项表示只完成预处理、编译和汇编,不做连接。

(2)C语言版

C语言版的LED操作需要从汇编代码跳转到C语言中去完成,首先是一段必要的汇编代码完成关闭看门狗、设置堆栈以及跳转到C入口代码等操作。对应的汇编代码源文件内容如下(crt0.S):

.text

.global _start

_start:

ldr r0, =0x560000XX @0x560000XX代表具体的看门狗寄存器地址

mov r1, #0x0

str r1, [r0] @禁止看门狗

ldr sp, =1024*4 @设置堆栈,不能大于4KB

bl main @调用C程序中的main函数

halt_loop:

b halt_loop

而还有一个相应的C语言源代码文件如下(led.c):

#define GPBCON (*(volatile unsigned long *)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

int main()

{

GPBCON = 0x00000400;

GPBDAT = 0x00000000;

return 0;

}

这两段代码所对应的Makefile文件内容为:

led.bin:crt0.S led.c

arm-linux-gcc -g -c -o crt0.o crt0.S

arm-linux-gcc -g -c -o led.o led.c

arm-linux-ld -Ttext 0x0000000 -g crt0.o led.o -o led_elf

arm-linux-objcopy -O binary -S led_elf led.bin

arm-linux-objdump -D -m arm led_elf > led.dis

clean:

rm -f led.dis led.bin led_elf *.o

注意:arm-linux-objdump指令将结果转换为汇编代码以供查看。2440的OM1和OM0引脚用于设置启动位置。NOR Flash可以像内存一样进行读操作,却不可以像内存一样进行写操作,所以从NOR Flash启动时,一般先在代码的开始部分使用汇编指令初始化外接的内存,然后将代码复制到外存中,最后跳转到外存中继续执行。NAND Flash中前4KB的内容会自动的被复制到2440内部RAM中,所以小实验程序可以借助此性质比较方便的完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: