51单片机入门-LED控制程序

文章介绍了51单片机如何控制LED,从点亮一个LED、使用reg52.h头文件,到实现LED间隔闪动和流水灯效果。文中详细讲解了代码实现、寄存器定义、延时技巧以及锁存器的作用,并提供了C51库函数的使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[2-1] 点亮一个LED_哔哩哔哩_bilibili

[2-2] LED闪烁_哔哩哔哩_bilibili

[2-3] LED流水灯_哔哩哔哩_bilibili

书籍:51单片机入门教程

目录

LED介绍

点亮一个LED

reg52.h的作用

流水灯模块布线

 排阻

发光二极管 

锁存器

while语句

LED以间隔1s闪动

define宏定义

用软件模拟延长时间

单片机的几个周期

训练:LED以间隔500ms闪动

LED流水灯

简单定义串口的值实现

利用C51库函数实现

学习记录


LED介绍

点亮一个LED

代码如下:

流水灯的管脚定义的是P1,我们想点亮的LED1也是与P1的最低位相接

#include <reg52.h>    
sbit led1 = P1^0; //将单片机P1口的最低位定义为led1          
void main(){
    led1 = 0;                        
}

reg52.h的作用

将鼠标移动到reg52.h上面,右键点击显示 open document,就可以打开这个头文件了,这个头文件定义了内部所有的寄存器

#ifndef __REG52_H__
#define __REG52_H__

/*  BYTE Registers  */
sfr P0    = 0x80; //把单片机内部地址0x80位置处的寄存器命名为P0
sfr P1    = 0x90;
sfr P2    = 0xA0;
sfr P3    = 0xB0;
sfr PSW   = 0xD0;
sfr ACC   = 0xE0;
sfr B     = 0xF0;
sfr SP    = 0x81;
sfr DPL   = 0x82;
sfr DPH   = 0x83;
sfr PCON  = 0x87;
sfr TCON  = 0x88;
sfr TMOD  = 0x89;
sfr TL0   = 0x8A;
sfr TL1   = 0x8B;
sfr TH0   = 0x8C;
sfr TH1   = 0x8D;
sfr IE    = 0xA8;
sfr IP    = 0xB8;
sfr SCON  = 0x98;
sfr SBUF  = 0x99;

/*  8052 Extensions  */
sfr T2CON  = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2    = 0xCC;
sfr TH2    = 0xCD;


/*  BIT Registers  */
/*  PSW  */
sbit CY    = PSW^7;//把PSW寄存器最高位重新命名为CY
sbit AC    = PSW^6;
sbit F0    = PSW^5;
sbit RS1   = PSW^4;
sbit RS0   = PSW^3;
sbit OV    = PSW^2;
sbit P     = PSW^0; //8052 only

/*  TCON  */
sbit TF1   = TCON^7;
sbit TR1   = TCON^6;
sbit TF0   = TCON^5;
sbit TR0   = TCON^4;
sbit IE1   = TCON^3;
sbit IT1   = TCON^2;
sbit IE0   = TCON^1;
sbit IT0   = TCON^0;

/*  IE  */
sbit EA    = IE^7;
sbit ET2   = IE^5; //8052 only
sbit ES    = IE^4;
sbit ET1   = IE^3;
sbit EX1   = IE^2;
sbit ET0   = IE^1;
sbit EX0   = IE^0;

/*  IP  */
sbit PT2   = IP^5;
sbit PS    = IP^4;
sbit PT1   = IP^3;
sbit PX1   = IP^2;
sbit PT0   = IP^1;
sbit PX0   = IP^0;

/*  P3  */
sbit RD    = P3^7;
sbit WR    = P3^6;
sbit T1    = P3^5;
sbit T0    = P3^4;
sbit INT1  = P3^3;
sbit INT0  = P3^2;
sbit TXD   = P3^1;
sbit RXD   = P3^0;

/*  SCON  */
sbit SM0   = SCON^7;
sbit SM1   = SCON^6;
sbit SM2   = SCON^5;
sbit REN   = SCON^4;
sbit TB8   = SCON^3;
sbit RB8   = SCON^2;
sbit TI    = SCON^1;
sbit RI    = SCON^0;

/*  P1  */
sbit T2EX  = P1^1; // 8052 only
sbit T2    = P1^0; // 8052 only
             
/*  T2CON  */
sbit TF2    = T2CON^7;
sbit EXF2   = T2CON^6;
sbit RCLK   = T2CON^5;
sbit TCLK   = T2CON^4;
sbit EXEN2  = T2CON^3;
sbit TR2    = T2CON^2;
sbit C_T2   = T2CON^1;
sbit CP_RL2 = T2CON^0;

#endif

流水灯模块布线

 排阻

每个发光二极管上面都串联电阻(限流电阻,限制通过发光二极管的电流,一般在3-20mA之间),然后在电阻的另一端接电源,这个叫做公共端,下图是使用的贴片式排阻:

算阻值:

102 = 10* 10^2 = 1k ohm

1002 = 100 * 10^2 = 10k ohm

标号位数不同,精度不同

三位数 - 5%精度

四位数 - 1%精度 

发光二极管 

发光二极管两端 1.7V 导通压降,长脚阳极,短脚阴极,电流只能从阳极流向阴极 

锁存器

(23条消息) 锁存器芯片74HC573芯片的用法,及其在实际电路中的应用_74hc573真值表_fxfreefly的博客-CSDN博客

 发光二极管通过锁存器连接到单片机的P1口,板上A/D芯片输出端也是P1口,若没有锁存器,那么当我们做A/D实验的时候,LED的阴极电平也会变化,导致无规则闪动。于是在做AD实验的时候,可以将锁存器的锁存端关闭。做LED实验的时候,可以把锁存端打开,也就是高电平状态。但是在代码里面我们没有写这个控制语句:因为51单片机一上电,所有未控制的I/O口默认高电平。

while语句

上面的主函数里面只有一行语句,我们并没有给他下一句需要执行的内容,于是Keil会自动从主函数处重新执行语句,实际上,是在不停得重复点亮发光二极管,但我们是想点亮二极管之后就结束,为了让程序停止,我们需要while语句

加上while(1); 判断语句是真,但是里面没有执行语句,所以什么都不执行,又开始判断语句是真...

单片机只要有电,就不会停止工作,所以没有办法不执行语句。

LED以间隔1s闪动

#include<reg52.h>
#define uint unsigned int
sbit led1 = P1^0;
uint i,j;

void main(){
	while(1){
		led1 = 0;
		
		for(i = 1000; i > 0; i--)
			for(j = 110; j > 0; j--);
					
		led1 = 1;
		
		for(i = 1000; i > 0; i--)
			for(j = 110; j > 0; j--);
		
	}
}

define宏定义

#define uint unsigned int  数字区间0-65535

用软件模拟延长时间

1.更改XTAL hz为单片机上晶振频率值 11.0592HZ

2.点击这个按钮进入软件模拟调试模式

3. 点击peripherals - I/O ports - port 1 模拟单片机P1口8位口线得状态, 单片机上电后I/O口全为1,0xFF

4. sec是执行到现在黄色箭头指向语句得累计时间

5.当我们选择 step over一行的时候,步进一行,累积运行时间变成了423.18μs,也就是一条执行语句所需要的时间是423.18-422.09=1.09μs,也就是一个机器周期花费的时间

6.在for循环的前后设置两个断点,就能算出一个for循环的所需时间

7.当for循环的两个变量类型都是unsigned int的时候,内层是110恒定不变,外层是多少就大概是多长时间

单片机的几个周期

训练:LED以间隔500ms闪动

#include <reg52.h>
#define uint unsigned int

sbit led1 = P1^0;
void delay500ms();

void main(){
	led1 = 0;
	delay500ms();
	led1 = 1;
	delay500ms();
}

void delay500ms(){
	uint i,j;
	for(i = 500; i > 0; i--)
		for(j = 110; j > 0; j--);
}

变量分为全局和部分变量,当前程序执行完成之后,变量将会自动销毁,全局变量占用的是单片机中固定的RAM,局部变量是用时随时分配,所以能用局部就用局部变量

LED流水灯

简单定义串口的值实现

用视频中的方法写出来的代码:

#include <reg52.h>
#define uint unsigned int

void delay(uint tms);
void main(){
	while(1){
		P1 = 0xFE;//1111 1110
		delay(100);
		P1 = 0xFD;//1111 1101
		delay(100);
		P1 = 0xFB;//1111 1011
		delay(100);
		P1 = 0xF7;//1111 0111
		delay(100);
		P1 = 0xEF;//1110 1111
		delay(100);
		P1 = 0xDF;//1101 1111
		delay(100);
		P1 = 0xBF;//1011 1111
		delay(100);
		P1 = 0x7F;//0111 1111
		delay(100);
	}
}

void delay(uint tms){
	uint i,j;
	for(i = tms; i > 0; i--)
		for(j = 110; j > 0; j--);
}

利用C51库函数实现

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//uchar led;

void delay(uint tms);
void main(){
	uchar led = 0xFE;
	while(1){
		P1 = led;
		led = _crol_(led, 1);
		delay(1000);
		
	}
}

void delay(uint tms){
	uint i,j;
	for(i = tms; i > 0; i--)
		for(j = 110; j > 0; j--);
}

#include <intrins.h>

unsigned char _crol_(unsigned char c, unsigned char b) 

----> it rotates the bit pattern for the character left b bits 循环向左移动

学习记录

5/4 下午1h + 5/5 上午2h 感觉书上讲的内容非常全面,学到了很多东西,视频的内容就是非常通俗易懂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值