1、点亮LED灯:
1)查看底板原理图得知LED灯通过NLED1-NLED4引脚控制,低电平亮;
2)查看核心板原理图得知NLED1-NLED4引脚连接到GPM0-GPM3引脚;
3)查看S3c6410芯片手册GPIO章节得到GPMCON寄存器和GPMDAT寄存器的地址;
4)配置GPMCON寄存器,配置为输出引脚:GPMCON |= 0x1111
5)设置GPMDAT的值点亮LED灯;GPMDAT &= ~(0x0F)
程序的问题:
1)必须对CPU的外设地址进行初始化(这个是6410需要的步骤,没关看门狗程序也能运行):
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4
2)使用宏定义设置寄存器的地址时,程序没有运行:
#define GPMCON (*((volatile unsigned long*)0x7F008820))
#define GPMDAT (*((volatile unsigned long*)0x7F008824))
而将寄存器的地址使用局部变量存储时,程序可以运行:
volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008820;
volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008824;
这里不是因为宏定义的问题,而是因为程序的位操作错误导致的:将GPMCON设置为输出模式时,
使用的GPMCON |= 0x1111; 单凭此条语句不能保证低16位等于0x1111,需要先将低16位清零。
3)位操作问题(犯了多次错误)
同时对(寄存器的)多位进行置0或置1时,不能只对相应的位进行操作,而是需要多位全部操作,比如:
a)将GPMCON[3:0]设置为输出引脚,不能只GPMCON |= 0x1111, 此时低16位中可能有多个1,所以需要先将低16
位全部清0, GPMCON &= ~0xFFFF;
b)再比如只设置GPMDAT[3:0]中某一位为0,不能只GPMDAT &= ~(1<<index); 此时确实可以把index清0,但是GPMDAT[3:0]
中其他位也可能是0,所以需要先将GPMDAT[3:0]全部置1,GPMDAT |= 0x0F;而后再将index位清0,才能保证低4位只有1个0;