分类: 嵌入式
2015-01-02 21:13:34
最近在学习TQ2440,以前都以为汇编程序不怎么重要,但现在通过一段时间的学习,感觉熟悉汇编能使你在使用高级语言开发程序时有事倍功半的效果。所以开始用汇编写裸机程序。没想到一开始问题就来了,起初我只想先写个点亮LED灯的程序这个很简单,我初步实现成功,后来想让它闪烁,问题由此而来。以下是我的程序代码:
AREA Init,CODE,READONLY //在ADS1.2中必须要有AREA表明Init为代码段ENTRY为程序入口点
ENTRY
ldr r0,=0x53000000 //关闭看门狗
mov r1,#0x00000000
str r1,[r0]
ldr r0,=0x56000010 //设置四个LED灯的控制端口
mov r1,#0xfffc03ff //除了4个LED灯外其它引脚都设定为保持原状态,目的是防止程序在未知情况下改动其它端口
ldr r2,[r0]
and r2,r2,r1
mov r1,#0x00015400 //设置四个LED为输出状态
orr r2,r2,r1
str r2,[r0]
led_on
ldr r0,=0x56000014 //同时点亮四个LED灯
mov r1,#0x0000
str r1,[r0]
mov r0,#0x0
bl comper1 //延时一段时间
b led_off
led_off
ldr r0,=0x56000014 //关闭4个LED灯
mov r1,#0x01e0
ldr r2,[r0]
orr r2,r2,r1
str r2,[r0]
mov r0,#0x0
bl comper //延时一段时间
b led_on
comper
add r0,r0,#0x1
cmp r0,#0xff
bne comper
mov pc,lr
comper1
add r0,r0,#0x1
cmp r0,#0x0f
bne comper1
mov pc,lr
END
上面的代码是经过多次修改后能正确得出结果。以前然我意向不到的错误代码是在led_on这段代码上如下所示:
led_on
ldr r0,=0x56000014
mov r1,#0x0000
ldr r2,[r0]
orr r2,r2,r1
str r2,[r0]
mov r0,#0x0
bl comper1
b led_off
红色字体是出错代码(注意编译是能通过的,运行时结果不对)。上面红色的带码原意是只想改变连接四个LED灯的四个端口的数据,不想改变其它端口数据。但实际中运行时灯只闪了一下就熄灭了。起初我以为是B和BL指令出问题了,对这个指令用其它的方式进行替换但结果不如人意,因为没有JTAG不能在线调试,在这里耽误了很长一段时间。经过多次的修改测试后才忽然发现上面的红色代码是一个致命点。原因很然我无语,LED能闪一下就不亮,问题不在于B和BL指令,而是第一次灯亮r2寄存器的值是0x00000000,灯灭r2寄存器值是0x01e0,且在内存地址为0x56000014处的值为0x01e0,之后B跳转到led_on时r2从0x56000014处取得的值就变为了0x01e0,在与0x0000进行orr运算就没有什么意义了。所以结果会出乎我的意料。当然,我是一个初学者,因为没有JTAG我看不了0x56000014处的内容这都是我的一些揣测,有不对的还请各位不吝啬指出。由此我还得到了一些收获,在ADS1.2中立即数的值超过256后会报错,这个我还没找到解决的办法。同时以后再用ldr 读取内存地址中的值时要多加留意该值是不是原来的值,有没有被意外的改变过。谨此作为一个教训!