教大家如何在单片机中用汇编优雅的点灯

现在可能很少看到汇编程序了,但单片机的启动文件、rtos底层代码等一些地方,依然还有汇编代码的身影。
不知道大家有没有学过汇编,或者有没有用汇编语言编过程?
今天就给大家分享一下汇编语言的那些事。
1
学习汇编语言我在10年学习单片机编程的时候,老师教学都还是用汇编教我们,包括教学实验,也是要求我们用汇编写程序。
mov a,#00hmov p1,a
我记得那会儿,老师要求我们把汇编指令背下来。虽然现在很多汇编指令写不出来了,但看到很多汇编代码,还是基本明白它的意思。
以前计算机三级(pc技术)的上机考试,就是用汇编编程,我那个时候上机考试还是满分。当时觉得自己很牛逼,现在看来就是一菜鸟
2
汇编转c语言刚开始学习汇编那会儿,我真的用汇编在51单片机上写流水灯程序。后面看了用c语言写流水灯程序,突然发现,哇,用c语言写程序还能这么简单、方便。
于是,我就那个时候开始放弃了汇编,转向了c语言。包括后面我在大学实验室自己学习、diy做东西、以及后面的全国大学生电子设计竞赛,都是用c语言编写的程序。
10行汇编程序,可能只需要一行c语言代码就能实现,这是c语言相比汇编简化的优点。
但是,c语言编写的程序,经过编译,也会转为汇编。比如我们在线调试代码的时候,会看到类似的“汇编窗口”:
因为以前单片机的运行速度不高,且内存和flash容量不大,要求节约程序空间。
所以使用汇编的优点:代码运行效率更高、更节约代码存储空间。
3
对比用汇编和c语言写流水灯程序汇编语言写程序的主要缺点:语法复杂、可读性差、代码量大等。
下面分享一个实例:51单片机上的流水灯程序。分别用c语言和汇编写出来,大家对比一下就知道了。
c语言版:
/******************** 宏定义 **************************/#define main_fosc 22118400l //定义主时钟
/******************** 延时函数 **************************/void delay_ms(u8 ms){ u16 i; do{ i = main_fosc / 13000; while(--i) ; //14t per loop }while(--ms);}
/******************** 主函数 **************************/void main(void){ p0m1 = 0; p0m0 = 0; //设置为准双向口 p1m1 = 0; p1m0 = 0; //设置为准双向口 p2m1 = 0; p2m0 = 0; //设置为准双向口 p3m1 = 0; p3m0 = 0; //设置为准双向口 p4m1 = 0; p4m0 = 0; //设置为准双向口 p5m1 = 0; p5m0 = 0; //设置为准双向口 p6m1 = 0; p6m0 = 0; //设置为准双向口 p7m1 = 0; p7m0 = 0; //设置为准双向口
while(1) { p17 = 0; delay_ms(250); delay_ms(250); p17 = 1; p16 = 0; delay_ms(250); delay_ms(250); p16 = 1; p47 = 0; delay_ms(250); delay_ms(250); p47 = 1; p46 = 0; delay_ms(250); delay_ms(250); p46 = 1; }}
汇编语言版:
;******************** 宏定义 **************************/fosc_khz equ 22118 ;22118khz
stack_poirter equ 0d0h ;堆栈开始地质
;******************** 延时函数 **************************/f_delay_ms: push 02h ;入栈r2 push 03h ;入栈r3 push 04h ;入栈r4
mov r2,a
l_delay_ms_1: mov r3, #high (fosc_khz / 13) mov r4, #low (fosc_khz / 13) l_delay_ms_2: mov a, r4 ;1t total 13t/loop dec r4 ;2t jnz l_delay_ms_3 ;4t dec r3l_delay_ms_3: dec a ;1t orl a, r3 ;1t jnz l_delay_ms_2 ;4t djnz r2, l_delay_ms_1
pop 04h ;出栈r2 pop 03h ;出栈r3 pop 02h ;出栈r4 ret
;******************** 主程序 **************************/ org 0100h ;resetf_main: clr a mov p0m1, a ;设置为准双向口 mov p0m0, a mov p1m1, a ;设置为准双向口 mov p1m0, a mov p2m1, a ;设置为准双向口 mov p2m0, a mov p3m1, a ;设置为准双向口 mov p3m0, a mov p4m1, a ;设置为准双向口 mov p4m0, a mov p5m1, a ;设置为准双向口 mov p5m0, a mov p6m1, a ;设置为准双向口 mov p6m0, a mov p7m1, a ;设置为准双向口 mov p7m0, a
mov sp, #stack_poirter mov psw, #0 ;选择第0组r0~r7
l_mainloop: clr p1.7 mov a, #250 lcall f_delay_ms ;延时250ms lcall f_delay_ms ;延时250ms setb p1.7
clr p1.6 mov a, #250 lcall f_delay_ms ;延时250ms lcall f_delay_ms ;延时250ms setb p1.6
clr p4.7 mov a, #250 lcall f_delay_ms ;延时250ms lcall f_delay_ms ;延时250ms setb p4.7
clr p4.6 mov a, #250 lcall f_delay_ms ;延时250ms lcall f_delay_ms ;延时250ms setb p4.6
sjmp l_mainloop
上面两个程序,实现的功能都一样(流水灯),但对比代码,大家发现有啥区别?
对于有汇编基础的同学来说,可能这个简单的流水灯程序还是很好理解。
但是,对于大部分人来说,肯定都会觉得汇编很难读。是的,这个是汇编的“特点”。
4
最后汇编语法,对于绝大部分读者来说,我现在是不建议再深入学习了,只需要了解一些基础的内容即可。
有少部分人,想从事底层开发,比如底层驱动、单片机验证、固件库开发等这些读者,有时间还是可以进一步了解汇编的一些技术。


FPGA智能芯片的研发仍需努力
苏州固锝披露2019年年度报告,实现营业收入19.81亿元
电源给电容器充电时电路中有电流吗?
HOLTEK新推出BH66F2475连续血糖监测MCU
继电器是干什么用的,它有哪些作用
教大家如何在单片机中用汇编优雅的点灯
Psious公司用VR技术治疗抑郁症
中央广播电视总台首次启用机器人记者参与#两会#报道
华为P10零部件曝光
小米redmi9怎么样redmi9值得买吗?拆解告诉你2020年入门机新标准
基于DSP的PCI总线CAN适配器设计
智慧工地环境监测系统的特点是什么
我国集成电路产业发展转入快车道,未来将继续保持高质量增长态势
HOLTEK新推出HT16D724 LED全彩显示屏恒流驱动IC
共建共享5G网络,夯实数字经济发展底座
python设置环境变量
BittWare扩展其采用IntelAgilex FPGA的IA-系列FPGA加速器
G3-PLC技术最终使电动汽车充电智能化
传苹果寻求在印度生产iPhone 16电池
oppleled灯板如何接线