|
/* *文件名:led.s *作者:宗虎冬 *描述:这是arm裸机led灯亮灭循环效果 * */ .global _start //把_start链接属性改为外部,这样其他文件就可以看见_start了 #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 _start: //第一步:把所有引脚都设置为输出模式,代码不变 ldr r0, =0x11111111 //从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数 ldr r1, =GPJ0CON //是合法立即数还是非法立即数。一般写代码都用ldr伪指令 str r0, [r1] //寄存器间接寻址,功能是把r0的数写入到r1中的数为地址的内存中去
flash: //全部点亮 ldr r0, =((0<<3) | (0<<4) | (0<<5)) ldr r1, =GPJ0CON ldr r0, =[r1] //延时 bl delay //全部灭 ldr r0, =((1<<3) | (1<<4) | (1<<5)) ldr r1, =GPJ0CON ldr r0, =[r1] //延时 bl delay //返回循环 b flash delay: ldr r2, =100000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 //r2 = r2 - 1 cmp r2, r3 //cmp会影响z标志位,如果r2等于r3则z=1,下一句中eq就会成立 bne delay_loop //不相等就跳回delay_loop mov pc, lr //函数调用返回
如果用c可以这样写 while(1); //空的死循环
while(1) //非空的死循环 { XXX
}
|
|
|
|
|
b .是一个空的死循环
以下是一个非空的死循环 flash: XXX
b flash
|
|
|
|
|
一步步点亮LED5_汇编编写延时函数并实现LED闪烁效果 闪烁效果原理分析 闪烁 = 亮 + 延时 + 灭 + 延时 + 亮 + 延时 ······ 延时函数原理 在汇编中实现延时的方法:用一些没有目的的代码来执行消耗时间,达到延时的效果。 汇编编写延时函数 汇编编写延时函数的原理,用一个寄存器存放一个数字,然后在循环中每个循环里给数字减1,然后再判断这个数字的值是否为0.如果为0则停止循环,如果不为0则继续循环。 汇编编写及调用函数的方式 汇编中整个汇编的主程序是一个死循环,这个死循环是我们汇编程序的主体,类似于C中的main函数。其他函数必须写在这个主死循环程序的后面(死循环外),不然会出错。 汇编编写delay延时函数时,要注意函数的初始化和函数体的位置,不能把初始化写在了循环体内。 汇编中调用函数用bl指令,子函数中最后用mov pc, lr来返回。
一步步点亮LED6_再难一点的流水灯效果 流水灯原理分析 流水灯又叫跑马灯,实现的效果就是:挨着的LED一次点亮熄灭(同时只有1颗LED亮的) 流水灯编写(使用循环) LED1亮延时 + LED2亮延时 + LED3亮延时 + 循环
|
|
|
|
|
在linux下复制,在windows下打开 /* *文件名:led.s *作者:宗虎冬 *描述:这是arm裸机led流水灯效果效果 * */ .global _start //把_start链接属性改为外部,这样其他文件就可以看见_start了 #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 _start: // 第一步:把所有引脚都设置为输出模式,代码不变 ldr r0, =0x11111111 // 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数 ldr r1, =GPJ0CON // 是合法立即数还是非法立即数。一般写代码都用ldr伪指令 str r0, [r1] // 寄存器间接寻址。功能是把r0中的数写入到r1中的数为地址的内存中去
flash: //第一步:点亮第一颗led灯 ldr r0, =((0<<3) | (1<<4) | (1<<5)) ldr r1, =GPJ0CON ldr r0, [r1] //延时 bl delay //第二步:点亮第二颗led灯 ldr r0, =((1<<3) | (0<<4) | (0<<5)) ldr r1, =GPJ0CON ldr r0, [r1] //延时 bl delay //第三步:点亮第三颗led灯 ldr r0, =((1<<3) | (1<<4) | (0<<5)) ldr r1, =GPJ0CON ldr r0, [r1] //延时 bl delay //返回循环 b flash // 延时函数:函数名:delay delay: ldr r2, =9000000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 //r2 = r2 -1 cmp r2, r3 // cmp会影响Z标志位,如果r2等于r3则Z=1,下一句中eq就会成立 bne delay_loop mov pc, lr // 函数调用返回
|
|
|
|
|
/* *文件名:led.s *作者:宗虎冬 *描述:复杂方式实现arm裸机led流水灯效果 *待以后测试 */ .global _start //把_start链接属性改为外部,这样其他文件就可以看见_start了 #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 _start: // 第一步:把所有引脚都设置为输出模式,代码不变 ldr r0, =0x11111111 // 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数 ldr r1, =GPJ0CON // 是合法立即数还是非法立即数。一般写代码都用ldr伪指令 str r0, [r1] // 寄存器间接寻址。功能是把r0中的数写入到r1中的数为地址的内存中去 mov r4, #3 flash:
//第一步:点亮第一颗led灯 ldr r0, =~(1<<r4) ldr r1, =GPJ0CON ldr r0, [r1] //延时 bl delay add r4, r4, #1 cmp r4, #6 //如果等于6就返回循环 bne flash //否则r4传入3再返回循环 mov r4, #3 b flash // 延时函数:函数名:delay delay: ldr r2, =9000000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 //r2 = r2 -1 cmp r2, r3 // cmp会影响Z标志位,如果r2等于r3则Z=1,下一句中eq就会成立 bne delay_loop mov pc, lr // 函数调用返回
|
|
|
|
|
复杂点的实现 用位取反操作符来轻松愉快的实现单颗LED点亮流水效果 总结:一步步写,根本不难 从一步一步点亮LED1开始到6,写了8个示例代码,一步步的实现了更复杂的效果,其间夹杂使用了位运算来给LED赋值,以实现想要的点亮效果。如果按部就班实际上非常简单。 编程操控一个硬件的步骤:1 分析硬件工作原理 2 分析原理图 3 分析数据手册 4 找到相关的SFR 5 写代码设置寄存器得到想要的效果
|
|
|
|