? ? ? ?数码管本质上就是八个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;
/**************************************************************************************
*数码管显示实验*
实现现象: 数码管第5位显示一个8
***************************************************************************************/
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
*******************************************************************************/
void main()
{
LSA=1;LSB=0;LSC=1; //位选第5位(第五位是从右往左数第六个数码管)
P0=0x7f;//段选显示8
}
2.按下 K1 显示 1,按下 K2 显示 2,按下 K3 显示 3,按下 K4 显示 4;
/**************************************************************************************
*独立按键控制数码管显示*
实现现象: 按键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;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : key
* 函数功能 : 按键K1:数码管显示1
按键K2:数码管显示2
按键K3:数码管显示3
按键K4:数码管显示4
*******************************************************************************/
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); //检测按键是否松开
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
*******************************************************************************/
void main()
{
LSA=0;LSB=0;LSC=0; //位选初始化
P0=0x00;//段选初始化
while(1)
{
key(); //按键处理函数
}
}
3.按下 K1 显示的数加 1,按下 K2 显示的数减 1,初始数值为 0;
示例1:一位数字、可显示负数
? ? ? 负数的显示,需要对数字正负进行判断,若为负数,将负号显示在数字前,再将负数取正,按照正数显示方法显示数字的值。
? ? ??(如果不对数字进行处理,那单个数码管仅能显示一位数字,所显示数字无法超过9)
/**************************************************************************************
*数码管实验*
实现现象:按键K1:数字加
按键K2:数字减
(可以显示负数)
***************************************************************************************/
#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;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数、判断数字正负并显示
*******************************************************************************/
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; //消隐
}
}
/*******************************************************************************
* 函 数 名 : key
* 函数功能 : 按键K1:数字加
按键K2:数字减
*******************************************************************************/
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); //检测按键是否松开
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
*******************************************************************************/
void main()
{
LSA=0;LSB=0;LSC=0; //位选初始化
P0=0x00;//段选初始化
while(1)
{
DigDisplay(); //数码管显示函数
key(); //按键处理函数
}
}
示例2:多位数字、可显示负数。
? ? ? 要想显示多位数字,需要对数字进行分位处理(即将数字每一位分开显示)。本示例所用的方法是对数字进行末位取余,再利用for循环进行动态显示。for循环在数字除尽(等于零0)时结束(整型变量的除法中,除数如果大于被除数,商为0)。
(由于变量定义为int数字值不能超出int型整数的取值范围,若想显示更大数,将变量改为双精度型即可)
【说的可能很难理解,但我是故意的( ̄︶ ̄)。大家仔细读代码就能懂了。】
【随手写的代码,期待大家有更好的方法】
/**************************************************************************************
*数码管实验升级版,可显示多位数字*
作 者:TZ
实现现象:按键K1:数字加
按键K2:数字减
(可以显示负数)
***************************************************************************************/
#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;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数、判断数字正负并显示
*******************************************************************************/
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; //消隐
}
}
/*******************************************************************************
* 函 数 名 : key
* 函数功能 : 按键K1:数字加
按键K2:数字减
*******************************************************************************/
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); //检测按键是否松开
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
*******************************************************************************/
void main()
{
LSA=0;LSB=0;LSC=0; //位选初始化
P0=0x00;//段选初始化
while(1)
{
DigDisplay(); //数码管显示函数
key(); //按键处理函数
}
}
4.数码管依次显示“198605”(无线电小组成立时间);
/**************************************************************************************
*动态数码管显示实验*
实现现象:下载程序后数码管从右至左显示0-7。
注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。
***************************************************************************************/
#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的值
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
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;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
DigDisplay(); //数码管显示函数
}
}
无线电小组———TZ
|