AutoLeaders控制组—51单片机学习笔记(一)

本文详细介绍了如何通过单片机控制LED灯的闪烁、定时以及使用独立按键操作LED灯。还涉及了数码管的静态和动态显示,包括共阴极和共阳极连接方式,以及使用74HC245作为缓冲器增强驱动能力。最后展示了多个模式下的数字显示应用。
摘要由CSDN通过智能技术生成

1.点亮LED灯

1.1LED灯闪烁

LED点亮原理

电阻:作用限流,大小为102(其中2为倍率),即1000欧姆。

由CPU通过控制配置的寄存器控制硬件电路,寄存器后面连接导线,通过一个驱动器(增大电流),连接到io口端口,使引脚输出高低电平:(TTL电平)高电平5V,低电平0V。

左端VCC接电源正极,故端口输出高电平时(表示为1),负极接正,LED不点亮;

端口输出低电平时(表示为0),负极接负,LED点亮;

二进制应该换为16进制(0x为前缀)

注意:LED灯对应的二进制数字是从右往左一一对应,如0111 1111,是第8个灯亮,不是第一个灯亮

1.2控制LED灯按时闪烁:

#include <REGX52.H>
#include<INTRINS.H>
void Delay800ms()		//@12.000MHz
{
	unsigned char i, j, k;
 
	_nop_();
	i = 7;
	j = 21;
	k = 96;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
 
void main(){
	P2=0xFE;
	Delay800ms();	
	P2=0xFF;
	Delay800ms();
}

1.3 LED流水灯

#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
 
 
void main(){
	
	while(1){
		P2=0xFE;   //1111 1110
		Delay1ms(800);
		P2=0xFD;    //1111 1101
		Delay1ms(700);
		P2=0xFB;   //1111 1011
		Delay1ms(600);
		P2=0xF7;   //1111 0111
		Delay1ms(500);
		P2=0xEF;   //1110 1111
		Delay1ms(400);
		P2=0xDF;   //1101 1111
		Delay1ms(300);
		P2=0xBF;  //1011 1111
		Delay1ms(200);
		P2=0x7F;   //0111 1111
		Delay1ms(100);
	}
}

1.4二进制点灯

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
 
 
void main(){    
	unsigned char LEDnum=0;         //引入变量
	while(1){
		if(P3_1==0){
		    Delay(20);          //通过delay去抖
		    while(P3_1==0);     //while作用:
	                        //按键启动if循环,松手走出while循环,运行下一步代码
			Delay(20);
			LEDnum++;      //16进制0,1,2,3,4
			P2=~LEDnum;    //取反
		}
	}

2.独立按键控制LED灯

2.1按键控制LED亮灭

1.按键抖动:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动

 2.独立按键:一端共同接正极,当另一端(P3)连接低电平时,即表示按键接通

K1,K2,K3,K4分别对应代码的P3_1 P3_0 P3_2 P3_3

#include <REGX52.H>
#include <INTRINS.H>
void Delayms(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
 
 
void main(){
	if(P3_1==0){   //按键执行
		Delayms(20);   //除去抖动
		while(P3_1==0);   //按键,进入空白循环,不执行下面
		Delayms(20);    
		
		P2_1=~P2_1;    //松键状态改变
	}
}

2.2.按键控制灯左右移动

相关运算符

按位左移:0011 1100<<1    即0111 1000 

按位右移:0011 1100>>2    即0000 1111 

按位与:0001 1000& 0010 1010 每一位单独操作   结果0000 1000 即0&一切 为0  1&X为X本身

按位或:0001 1000 | 0010 1010    结果0011 1010   1|一切为1 0|X为X本身  

按位异或:0001 1000^0010 1010  结果0011 0010   即一样为0,不一样为1

取反:~00001111     11110000

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
 
 
void main(){
 
	unsigned char LEDnum=0;
	while(1){
		if(P3_1==0){
			Delay(20);
			while(P3_1==0);   
			Delay(20);
			
			if(LEDnum>=8){    
				LEDnum=0;
			}
			//LEDnum=1   0000 0001---0000 0010  取反1111 1101 
			P2=~(0x01<<LEDnum);
			LEDnum++;
		}
		if(P3_3==0){
			Delay(20);
			while(P3_3==0);   
			Delay(20);
			
			if(LEDnum==0){    
				LEDnum=7;
			}
			else{LEDnum--;}
			P2=~(0x01<<LEDnum);
			
		}
	}		
}

3.数码管

3.1静态数码管显示

3.1.1.一位数码管

共阴极连接(右上图):8个LED的阴极都连接到一个端口上

共阳极连接(右下图):8个LED的阳极都连接到一个端口上

51单片机的开发板为共阴极连接,即公共端阴极接低电平,未选端给相应数据,输入1即为亮;反之,共阳极连接则将公共端接正极电源,未选端输入0为亮

使这个数码管显示数字“6”,需要让A、F、E、D、C、G都亮起来。共阴极,首先3和8引脚都是要接地的(负极、低电平、0);然后A、F、E、D、C、G都接正极(高电平,1),B和DP接负极,这样就能得到一个数字“6”,即A、B、C、D、E、F、G、DP设置为1011 1110;
 

3.1.2.多位数码管

多分出几个小单元,公共端独立,未选端连在一起,作用是节省了io口,但同一个时刻下只能显示同样的数字,若要显示不同数字可通过动态数码管显示(利用人眼视觉暂留和数码管显示余晖的原理)

3.1.3. 138译码器

作用:和数码管相连接,8个io口简化为3个,

使用原理:

左边P2端123依次输入二进制数字,右边对应的十进制接口显示0,其他均为1

示例:输入二进制(101),对应十进制(5),即Y5口为0,对应LED口数据为1111 1011,(0即为接通,即第6个数码管显示,其他数码管不显示)(Y是从0开始计,Y5为0即LED6为0)
 

3.1.4.  74HC245 

作用:单片机高电平驱动能力有限,输出的最大电流不能太大,低电平驱动能力强一些。加入缓冲器74HC245,提高驱动能力,吸收P0端口的微弱信号,再从VCC电源汲取能量,驱动数码管灯光更亮

3.1.5操作示例一:使第三个数码管显示6

P2口控制数码管显示的位置,0为接通,P0口控制数码管显示的数字,1为接通;

0对应0x3F、1对应0x06、2对应0x5B、3对应0x4F、4对应0x66、

5对应0x6D、6对应0x7D、7对应0x07、8对应0x7F、9对应0x6F  

A对应0x77、B对应0x7C、C对应0x39、D对应0x5E、

E对应0x79、F对应0x71、空对应0x00,
 

#include <REGX52.H>
void main(){
	P2_4=1;      //第二个数码管
	P2_3=1;
	P2_2=0;   
	while(1){ 
		P0=0x7D;   //从下往上读数0111 1101显示6
	} 
}
#include <REGX52.H>
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,number){
	switch(location)
	{
		case 1:     
			P2_4=1;P2_3=1;P2_2=1;		
			break;
		case 2:   
			P2_4=1;P2_3=1;P2_2=0;
			break;
		case 3: 
			P2_4=1;P2_3=0;P2_2=1;
			break;
		case 4:  
			P2_4=1;P2_3=0;P2_2=0;		
			break;
		case 5:     
			P2_4=0;P2_3=1;P2_2=1;
			break;
		case 6:     
			P2_4=0;P2_3=1;P2_2=0;
			break;
		case 7:     
			P2_4=0;P2_3=0;P2_2=1;
			break;
		case 8:     
			P2_4=0;P2_3=0;P2_2=0;
			break;
	}
	P0=NUM[number];
}
 
void main(){
	Nixie(1,1); 
	while(1){};   
}

3.2.动态数码管显示

#include <REGX52.H>
void Delayms(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,unsigned char number){
	switch(location)
	{
		case 1:     
			P2_4=1;P2_3=1;P2_2=1;		
			break;
		case 2:   
			P2_4=1;P2_3=1;P2_2=0;
			break;
		case 3: 
			P2_4=1;P2_3=0;P2_2=1;
			break;
		case 4:  
			P2_4=1;P2_3=0;P2_2=0;		
			break;
		case 5:     
			P2_4=0;P2_3=1;P2_2=1;
			break;
		case 6:     
			P2_4=0;P2_3=1;P2_2=0;
			break;
		case 7:     
			P2_4=0;P2_3=0;P2_2=1;
			break;
		case 8:     
			P2_4=0;P2_3=0;P2_2=0;
			break;
	}
	P0=NUM[number];
	Delayms(2);
	P0=0x00;   //把前一个数据清零,防止对下一个显示有影响
}
 
void main(){ 
	while(1){
		Nixie(1,1);
		Nixie(2,3);
		Nixie(3,1);
	    Nixie(4,4);		
	};   
}

4.任务

#include <REGX52.H>
int a,b,c,num,i=0;
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x40};//0~9 U -
void Delay(unsigned int xms)		
{
unsigned char i, j;
while(xms)
{
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
	xms--;
}
}
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break; 
case 2:P2_4=1;P2_3=1;P2_2=0;break; 
case 3:P2_4=1;P2_3=0;P2_2=1;break; 
case 4:P2_4=1;P2_3=0;P2_2=0;break; 
case 5:P2_4=0;P2_3=1;P2_2=1;break; 
case 6:P2_4=0;P2_3=1;P2_2=0;break; 
case 7:P2_4=0;P2_3=0;P2_2=1;break; 
case 8:P2_4=0;P2_3=0;P2_2=0;break; 
}
P0= NixieTable[Number];
Delay(1);
P0=0x00;
}

unsigned char mode= 0;
void key()
{
if(P3_1==0) {Delay(20);while(P3_1==0);Delay(20);mode = 1;}
if(P3_0==0) {Delay(20);while(P3_1==0);Delay(20);mode = 2;}
if(P3_2==0) {Delay(20);while(P3_1==0);Delay(20);mode = 3;}
if(P3_3==0) {Delay(20);while(P3_1==0);Delay(20);mode = 4;}
}
 
void mode1()
{
	while(1){
	Nixie(1,10);
	Nixie(2,1);
	Nixie(7,0);
	Nixie(8,1);	
	if(!P3_0||!P3_2||!P3_3)break;
	}
}	
void mode2()
{ 
	for(i=1;1<2;i++)
	{
	a=230;
	while(a--)
	{
	Nixie(1,10);
	Nixie(2,2);
	Nixie(7,num/10);
	Nixie(8,num%10);
	}
	num++;
	if(num==11)
	{
		num= 1;
	}

if(!P3_1||!P3_2||!P3_3)break;
	}
}
void mode3()
{
for(i=1;i<=1000;i++)
	{
	a=83;	
	while(a--)
	{
	Nixie(1,10);
	Nixie(2,3);
	Nixie(7,0);
	Nixie(8,3);
	Nixie(5,11);	
	Nixie(6,11);
	}
if(!P3_0||!P3_1||!P3_3)break;
	a=83;
	while(a--)
	{	
	Nixie(1,10);
	Nixie(2,3);
	Nixie(7,0);
	Nixie(8,3);	
	}
	if(!P3_0||!P3_1||!P3_3)break;
}
	}
void mode4()
{
	while(1){
	Nixie(1,10);
	Nixie(2,4);
	Nixie(7,c);
	Nixie(8,c);	
if(P3_3==0)
{
	while(P3_3==0)
		{
	Nixie(1,10);
	Nixie(2,4);
	Nixie(7,c);
	Nixie(8,c);		
		}
		c++;		
	}
	if(c==10)
	{
		c = 0;
	}

if(!P3_0||!P3_2||!P3_1)break;}
}

void main()
{
	while(1)
	{
		key();
		if(mode == 1) mode1();
	    if(mode == 2) mode2();
		if(mode == 3) mode3();
		if(mode == 4) mode4();
	}
}
	

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值