我给你写个参考程序,看看程序符不符合你的要求,程序如下:
#include "REG52H"
// LED灯端口定义
sbit GPIO_Exio1 = P0^0;
sbit GPIO_Exio2 = P0^1;
sbit GPIO_Exio3 = P0^2;
sbit GPIO_Exio4 = P0^3;
// 按键输入端口
sbit KEY1_Exitm = P1^0;
sbit KEY2_Exitm = P1^1;
sbit KEY3_Exitm = P1^2;
sbit KEY4_Exitm = P1^3;
/
延时1ms
/
void Delay_1ms(unsigned int Cnt)
{
unsigned int x, y;
for(x = Cnt; x > 0; x--)
for(y = 120; y > 0; y--);
}
/
按键扫描子函数
/
void KEY_ScanExtio(void)
{
// 判断K1 、K2其中一个按键按下
if((KEY1_Exitm == 0) || (KEY2_Exitm == 0))
{
Delay_1ms(5);
if((KEY1_Exitm == 0) || (KEY2_Exitm == 0))
{
// 按键按下点亮LED
GPIO_Exio1 = 0;
GPIO_Exio2 = 0;
GPIO_Exio3 = 0;
GPIO_Exio4 = 0;
}
while((KEY1_Exitm == 0) || (KEY2_Exitm == 0)); // 按键松手检测
// 按键松手后LED灭
GPIO_Exio1 = 1;
GPIO_Exio2 = 1;
GPIO_Exio3 = 1;
GPIO_Exio4 = 1;
}
// 判断K3 、K4其中一个按键按下
if((KEY3_Exitm == 0) || (KEY4_Exitm == 0))
{
Delay_1ms(5);
if((KEY3_Exitm == 0) || (KEY4_Exitm == 0))
{
}
while((KEY3_Exitm == 0) || (KEY4_Exitm == 0)); // 按键松手检测
// 按键松手后取反LED
GPIO_Exio1 = ~GPIO_Exio1;
GPIO_Exio2 = ~GPIO_Exio2;
GPIO_Exio3 = ~GPIO_Exio3;
GPIO_Exio4 = ~GPIO_Exio4;
}
}
/
主函数
/
int main(void)
{
// 初始化IO
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
P3 = 0xFF;
while(1)
{
KEY_ScanExtio();
}
}
#include<reg52h>
//#include<stdioh>
sbit LED = P2^0;
unsigned char ReceiveData;
void main()
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xfd;//baud 9600bit/s
//TI = 1;
TR1 = 1;
ES = 1;
EA = 1;
while(1)
{
}
}
void UART1_Routine()interrupt 4
{
if(RI)
{
RI = 0;
ReceiveData = SBUF;
//此处视上位机发过来的指令而定(将0x01改成对应字节命令即可),只适用于单字节命令,数据包格式需另改代码
if(ReceiveData==0x01)
{
LED =~LED;//实现按一下灯亮,再次按下灯灭
}
}
}
///如有问题,可再咨询
主程序:
LOOP: SETB P10 ;(1)
LCALL DELAY ;(2)
CLR P10 ;(3)
LCALL DELAY ;(4)
AJMP LOOP;(5)
;以下子程序
DELAY: MOV R7,#250;(6)
D1: MOV R6,#250;(7)
D2: DJNZ R6,D2;(8)
DJNZ R7,D1 ;(9)
RET ;(10)
END ;(11)
按上面的设想分析一下前面的五条指令。
第一条是让灯灭,第二条应当是延时,第三条是让灯亮,第四条和第二条一模一样,也是延时,第五条应当是转去执行第一条指令。第二和第四条实现的原理稍后谈,先看第五条,LJMP是一条指令,意思是转移,往什么地方转移呢?后面跟的是LOOP,看一下,什么地方还有LOOP,对了,在第一条指令的前面有一个LOOP,所以很直观地,我们能认识到,它要转到第一条指令处。这个第一条指令前面的LOOP被称之为标号,它的用途就是给这一行起一个名字,便于使用。是否一定要给它起名叫LOOP呢?当然不是,起什么名字,完全由编程序的人决定,能称它为A,X等等,当然,这个时候,第五条指令LJMP后面的名字也得跟着改了。
第二条和第四条指令的用途是延时,它是怎样实现的呢?指令的形式是LCALL,这条指令称为调用子程序指令,看一下指令后面跟的是什么,DELAY,找一下DELAY,在第六条指令的前面,显然,这也是一个标号。这条指令的作用是这样的:当执行LCALL指令时,程序就转到LCALL后面的标号所标定的程序处执行,如果在执行指令的过程中遇到RET指令,则程序就返回到LCALL指令的下面的一条指令继续执行,从第六行开始的指令中,能看到确实有RET指令。在执行第二条指令后,将转去执行第6条指令,而在执行完6,7,8,9条指令后将遇到第10条令:RET,执行该条指令后,程序将回来执行第三条指令,即将P10清零,使灯亮,然后又是第四条指令,执行第四条指令就是转去执行第6,7,8,9,10条指令,然后回来执行第5条指令,第5条指令就是让程序回到第1条开始执行,如此周而复始,灯就在持续地亮、灭了。
在标号DELAY标志的这一行到RET这一行中的所有程序,这是一段延时程序,大概延时零点几秒,至于具体的时间,以后我们再学习如何计算。 程序的最后一行是END,这不是一条指令,它只是告诉我们程序到此结束,它被称为"伪指令"。
单片机内部结构分析:为了知道延时程序是如何工作的,我们必需首先了解延时程序中出现的一些符号,就从R1开始,R1被称之为工作寄存器。什么是工作寄存器呢?让我们从现实生活中来找找答案。如果出一道数学题:123+567,让你回答结果是多少,你会马上答出是690,再看下面一道题:123+567+562,要让你要上回答,就不这么不难了吧?我们会怎样做呢?如果有张纸,就不难了,我们先算出123+567=690,把690写在纸上,然后再算690+562得到结果是1552。这其中1552是我们想要的结果,而690并非我们所要的结果,但是为了得到最终结果,我们又不得不先算出690,并记下来,这其实是一个中间结果,计算机中做运算和这个类似,为了要得到最终结果,一般要做很多步的中间结果,这些中间结果要有个地方放才行,把它们放哪呢?放在前面提到过的ROM中能吗?显然不行,因为计算机要将结果写进去,而ROM是不能写的,所以在单片机中另有一个区域称为RAM区(RAM是随机存取存储器的英文缩写),它能将数据写进去。 特别地,在MCS-51单片机中,将RAM中分出一块区域,称为工作寄存器区
以上就是关于求写一个单片机控制LED灯程序全部的内容,包括:求写一个单片机控制LED灯程序、51单片机怎么写程序用hc05 控制led的亮灭、求控制led灯亮灭的例程和详解等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)