1、51 单片机的那些事儿(续)上次说到彩灯循环的程序,使用汇编语言编写。现在我们逐一分析一下。彩灯循环:这是常见的简单程序,我们先让 P0 口接的 LED 中的一个灯亮,然后顺序左移,移到最后一个再右移。循环往复。代码如下:ORG 0000HAJMP MAINORG 0080HMAIN : MOV A , #7FH 这行是让一个灯亮起来MOV P0 , AMOV R0,#07H 移动 7 次MOV R1,#07HMOV R2 , #0FFH 用来延时,要不然太快了MOV R3 ,#0FFHL1:RRC AMOV P0 , AL2 : DJNZ R2 , L2NOPNOPNOPNOPDJNZ R3
2、,L2DJNZ R0,L1MOV R3 ,#0FFHMOV R2 , #0FFHL3:RLC AMOV P0,AL4:DJNZ R2,L4NOPNOPNOPNOPDJNZ R3, L4DJNZ R1 , L3AJMP MAINEND首先为什么要 MOV A , #7FH 呢,7FH 转换成二进制是01111111,大家会发现,这里面只有一个零,所以,在共阳极的LED 接法中, 0 会让 LED 发光,所以这里面只亮一个灯。 MOV P0 , A就是把这个 7FH 输出,输出了才能亮起来。所以这两句表示一个初始的彩灯状态,就是只有第一个灯亮了。MOV R0,#07H MOV R1,#07H 两句
3、为什么是 7 次呢,因为从第一个到最后一个,我们只接通 8 个灯,初始状态第一个灯已经亮了,所以剩下 7 个灯,只能移动七次,就能让最后一个灯亮,移动 8 次就仍然回到第一个灯了。我们要达到的效果不是简单的从头到尾再从头到尾的循环,而是先从第一个移动到最后一个然后从最后一个再回到第一个,所以不能让每次再回到第一个。MOV R3 ,#0FFH MOV R2 , #0FFH 这两句为了延长时间而设计。汇编语言中,为了延长时间,我们只能让单片机一次一次的减一,然后判断是否为零,不是零就再减一判断,就这么周而复始的消磨时间,这就是延时。RRC A RLC A 就是整体右移和左移。DJNZ 用的较为普遍
4、,例如 DJNZ R3 , L3 就是把 R3 当中的数自减一,然后判断是否为零,不是零就跳转到标签为 L3 处的程序执行。最后别忘了 END,虽然它不产生编译代码,但是为了尊重程序的完整性,还是写在最后吧。单片机程序编写还有一种语言,就是 C51,语言。KEIL 编译器可以把 C 语言转化成汇编语言,然后用转化成的汇编语言再次变异 hex 文件。上面的彩灯循环,我们可以写成如下的方式。#include#includesfr P0 = 0x80;void delay() int a,b;for (a=0;a1;P0 = c;delay();delay();for(e=0,e7,e+)c = c1;P0 = c;delay();C 语言最大的特点就是模块化特别强,用 C 语言编写的程序出了兼顾 51 单片机的结构,最重要的是语法规范。大家可以参照 C 语言教程中的语法结构来分析这段简单的程序。记得一位前辈写过,单片机程序的大体结构是首先上电复位,然后是参数初始化,之后就是个大循环体。每个循环体开始要有使能标志,以便取舍。这一篇先告一段落,下一篇分享一下定时器/计数器的应用,以及矩阵键盘,中断应用,还有 LCD1602 的驱动方式。