一、在AT89C51芯片基础上使用c语言点亮流水灯
我们首先在pertous上进行电路仿真,在元件库里查询AT89C51芯片,LED-YELLOW,RES元件,为和实际情况相似,我们增加了电阻防止LED灯因电流过大损坏。我们采用共阳极连接方法,若要点亮LED灯,就需要将P0端赋值为低电平。
为了实现流水灯的效果我们采用循环实现一个延迟函数。然后在主函数里面将LED灯的地址赋值给端口使其显示出来,调用延迟函数后熄灭,不断的循环就可以达到流水灯的效果,具体代码如下:
//51单片机编程常用的头文件
#include <reg51.h>
#include <intrins.h>
//延迟函数
void delay_ms(int a)
{
int i,j;
for(i=0;i<a;i++)
{
for(j=0;j<1000;j++) _nop_();
}
}
void main(void)
{
while(1)
{
P0=0xfe;
delay_ms(50);
P0=0xfd;
delay_ms(50);
P0=0xfb;
delay_ms(50);
P0=0xf7;
delay_ms(50);
P0=0xef;
delay_ms(50);
P0=0xdf;
delay_ms(50);
P0=0xbf;
delay_ms(50);
P0=0x7f;
delay_ms(50);
}
}
最后效果如图所示:
二、使用汇编语言点亮LED灯
1.用汇编语言点亮一个LED灯
点亮一个LED灯相对简单,只需直接寻址到连接LED灯的端口,然后点亮就行。
代码如下:
ORG 0100H
SETB P2.0
SJMP $ ;无条件相对转移 $就是本句语言的指针地址
;SJMP $,就是硬件部分
END
ORG:设定一个新的程序起始地址
SETB:置位直接寻址位
结果图如下:
2.用汇编语言点亮流水灯
点亮流水灯就需要调用延迟函数,和c语言类似需要用到循环做延时函数,这里的延迟函数主要靠DJNZ R1,$实现,先将寄存器R1,R2,R3赋值,然后循环减1达到延时效果。
具体代码如下:
ORG 0x0000 ; 程序起始地址
LOOP:
MOV P2, #0xFF ; 将0xFF数据存入P2端口,点亮所有LED灯
ACALL DELAY ; 调用延时子程序
MOV P2, #0x00 ; 将0x00数据存入P2端口,关闭所有LED灯
ACALL DELAY ; 调用延时子程序
SJMP LOOP ; 无条件跳转到LOOP处,实现循环
DELAY:
MOV R1, #0xFF
MOV R2, #0xFF
MOV R3, #0xFF
DJNZ R1, $
DJNZ R2, $
DJNZ R3, $
RET ; 返回子程序
END ; 程序结束
LOOP::标签,用于无条件跳转到此处执行循环。
ACALL DELAY:调用延时子程序,实现延时效果。
SJMP LOOP:无条件跳转到LOOP处,实现循环。
DELAY::延时子程序,用于控制闪烁的频率。
MOV R1, #0xFF:将0xFF存入寄存器R1。
DJNZ R1, $:循环减1并判断结果是否为零,如果不为零则跳转到$处执行,实现延时效果。
RET:返回子程序。
具体电路图如下:
参考链接:
Proteus使用教程并仿真51程序——LED流水灯_电阻的英语-CSDN博客
51单片机使用汇编语言点亮LED灯_51单片机中用汇编指令控制p口的led-CSDN博客
总结
点亮LED灯是嵌入式的入门操作,看似简单但也有许多的东西需要注意,尤其是对汇编语言的学习,它的部分语法的用法有细微的差别,需要我们理解并正确运用。