栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

51单片机入入入入入入门小练习之——动态数码管

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

51单片机入入入入入入门小练习之——动态数码管

       数码管本质上就是八个led,在程序中通过”段选“来控制led的显示组合,从而显示数字或符号。

       动态数码管利用人眼的视觉暂留原理,通过不停的“段选、位选”,循环显示几个不同数字,使几个数字可供人眼同时观察。

本次实验内容:

1.第 5 位显示一个 8;

2.按下 K1 显示 1,按下 K2 显示 2,按下 K3 显示 3,按下 K4 显示 4;

3.按下 K1 显示的数加 1,按下 K2 显示的数减 1,初始数值为 0;

4.数码管依次显示“198605”(无线电小组成立时间);

5.更多有趣设计!!!

参考代码:

(参考代码格式相对标准易读,适合大家学习、理解。但并非最简单的代码)

1.第 5 位显示一个 8;

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;


void main()
{
	LSA=1;LSB=0;LSC=1; //位选第5位(第五位是从右往左数第六个数码管)
	P0=0x7f;//段选显示8			
}

2.按下 K1 显示 1,按下 K2 显示 2,按下 K3 显示 3,按下 K4 显示 4;


#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P3^1;	 //定义P31口是k1
sbit k2=P3^0;	 //定义P30口是k2
sbit k3=P3^2;	 //定义P31口是k1
sbit k4=P3^3;	 //定义P30口是k2

u8 code smgduan[4]={0x06,0x5b,0x4f,0x66};//显示1~4的值

int i;


void delay(u16 i)
{
	while(i--);	
}


void key()
{
	if(k1==0)	   	   //检测按键K1是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	   //再次判断按键是否按下
		{
			P0=smgduan[0]; //发送段码
		}
		while(!k1);	   //检测按键是否松开
	}
	if(k2==0)		   //检测按键K2是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k2==0)	   //再次判断按键是否按下
		{
			P0=smgduan[1]; //发送段码
		}
		while(!k2);	   //检测按键是否松开
	}
	if(k3==0)		   //检测按键K2是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k3==0)	   //再次判断按键是否按下
		{
			P0=smgduan[2]; //发送段码
		}
		while(!k2);	   //检测按键是否松开
	}
	if(k4==0)		   //检测按键K2是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k4==0)	   //再次判断按键是否按下
		{
			P0=smgduan[3]; //发送段码
		}
		while(!k2);	   //检测按键是否松开
	}
}


void main()
{
	LSA=0;LSB=0;LSC=0; //位选初始化
	P0=0x00;//段选初始化	
	while(1)
	{	
		key();		   //按键处理函数
	}		
}

3.按下 K1 显示的数加 1,按下 K2 显示的数减 1,初始数值为 0;

示例1:一位数字、可显示负数

      负数的显示,需要对数字正负进行判断,若为负数,将负号显示在数字前,再将负数取正,按照正数显示方法显示数字的值。

      (如果不对数字进行处理,那单个数码管仅能显示一位数字,所显示数字无法超过9)


#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P3^1;	 //定义P31口是k1
sbit k2=P3^0;	 //定义P30口是k2

u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9的值
char i;


void delay(u16 i)
{
	while(i--);	
}


void DigDisplay()
{
	if(i>=0)
	{
		LSA=0;LSB=0;LSC=0;
		P0=smgduan[i]; //发送段码
		delay(100);    //间隔一段时间扫描	
		P0=0x00;       //消隐	
	}
	if(i<0)
	{
		LSA=1;LSB=0;LSC=0;
		P0=0x40;       //发送负号的十六进制段码到P0
		delay(100);    //间隔一段时间扫描	
		P0=0x00;       //消隐
		LSA=0;LSB=0;LSC=0;
		P0=smgduan[-i];//发送段码(“-i”将i变为正数)
		delay(100);    //间隔一段时间扫描	
		P0=0x00;       //消隐
	}	
}


void key()
{
	if(k1==0)	   	   //检测按键K1是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	   //再次判断按键是否按下
		{
			i++;
		}
		while(!k1);	   //检测按键是否松开
	}
	if(k2==0)		   //检测按键K2是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k2==0)	   //再次判断按键是否按下
		{
			i--;
		}
		while(!k2);	   //检测按键是否松开
	}

}


void main()
{	
	LSA=0;LSB=0;LSC=0; //位选初始化
	P0=0x00;//段选初始化	
    while(1)
	{	
		DigDisplay();  //数码管显示函数	
		key();		   //按键处理函数
	}		
}

示例2:多位数字、可显示负数。

      要想显示多位数字,需要对数字进行分位处理(即将数字每一位分开显示)。本示例所用的方法是对数字进行末位取余,再利用for循环进行动态显示。for循环在数字除尽(等于零0)时结束(整型变量的除法中,除数如果大于被除数,商为0)。

(由于变量定义为int数字值不能超出int型整数的取值范围,若想显示更大数,将变量改为双精度型即可)

【说的可能很难理解,但我是故意的( ̄︶ ̄)。大家仔细读代码就能懂了。】

【随手写的代码,期待大家有更好的方法】


#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P3^1;	 //定义P31口是k1
sbit k2=P3^0;	 //定义P30口是k2

u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9的值
u8 LS_A[8]={0,1,0,1,0,1,0,1};
u8 LS_B[8]={0,0,1,1,0,0,1,1};
u8 LS_C[8]={0,0,0,0,1,1,1,1};
int i;


void delay(u16 i)
{
	while(i--);	
}


void DigDisplay()
{
	u8 k=0;
	u16 q=0;
	if(i>=0)
	{
		k=0;
		for(q=i;q!=0;)
		{
			LSA=LS_A[k];LSB=LS_B[k];LSC=LS_C[k];
			P0=smgduan[(q%10)]; //发送段码
			delay(100);    //间隔一段时间扫描	
			P0=0x00;       //消隐
			q=q/10;
			k=k+1;	
		}
	}
	if(i<0)
	{
		for(q=-i;q!=0;)
		{
			LSA=LS_A[k];LSB=LS_B[k];LSC=LS_C[k];
			P0=smgduan[q%10]; //发送段码
			delay(100);    //间隔一段时间扫描	
			P0=0x00;       //消隐
			q=q/10;
			k++;	
		}
		LSA=LS_A[k];LSB=LS_B[k];LSC=LS_C[k];
		P0=0x40;       //发送负号的十六进制段码到P0
		delay(100);    //间隔一段时间扫描	
		P0=0x00;       //消隐
	}	
}


void key()
{
	if(k1==0)	   	   //检测按键K1是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	   //再次判断按键是否按下
		{
			i++;
		}
		while(!k1);	   //检测按键是否松开
	}
	if(k2==0)		   //检测按键K2是否按下
	{	
		delay(1000);   //消除抖动 一般大约10ms
		if(k2==0)	   //再次判断按键是否按下
		{
			i--;
		}
		while(!k2);	   //检测按键是否松开
	}
}


void main()
{	
	LSA=0;LSB=0;LSC=0; //位选初始化
	P0=0x00;//段选初始化	
    while(1)
	{	
		DigDisplay();  //数码管显示函数	
		key();		   //按键处理函数
	}		
}

4.数码管依次显示“198605”(无线电小组成立时间);


#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值


void delay(u16 i)
{
	while(i--);	
}


void DigDisplay()
{

	LSA=0;LSB=0;LSC=0;//显示第0位
 	P0=smgduan[5];//发送段码
	delay(100); //间隔一段时间扫描	
	P0=0x00;//消隐

	LSA=1;LSB=0;LSC=0;//显示第1位
	P0=smgduan[0];
	delay(100); 
	P0=0x00;

	LSA=0;LSB=1;LSC=0;//显示第2位
	P0=smgduan[6];
	delay(100); 	
	P0=0x00;

	LSA=1;LSB=1;LSC=0;//显示第3位
	P0=smgduan[8];
	delay(100);
	P0=0x00;

	LSA=0;LSB=0;LSC=1;//显示第4位
	P0=smgduan[9];
	delay(100); 
	P0=0x00;

	LSA=1;LSB=0;LSC=1;//显示第5位
	P0=smgduan[1];
	delay(100); 
	P0=0x00;
}


void main()
{	
	while(1)
	{	
		DigDisplay();  //数码管显示函数	
	}		
}

无线电小组———TZ

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738064.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号