一、实验任务
(一)、点亮一个数码管
数码管实现自己想要的数字
结合之前的独立按键知识,实现数码管与按键的结合
(二)、点亮多个数码管
数码管实现自己想要的组合
结合之前的矩阵按键知识,实现数码管与按键的结合
二、原理分析
数码管是如何点亮的?
我们可以将数码管看成8个LED灯组合成的,8个LED灯的不同组合就形成了数字或字母。数码管和LED灯一样分为共阴极和共阳极,如上图所示。
若共阳极数码管,当对应I/O口为0时,对应的段点亮。
例如:我们希望在共阳极数码管现实数字0,对应上图左边图像,就应该是abcdef亮,其他灭。
数码管从高位到低位 分别为 dp,g,f,e,d,c,b,a。结果就是1100 0000,就是0xc0。
每次使用都要计算一次的话,比较麻烦,所以我们将全部的数码管显示写在一个数组中,下次使用直接复制粘贴即可。通过数组内容和数组下标一一对应的关系,搜索下标数值就能找到我们希望传送给数码管的值了。
在书本上我们会看到一个code标识符,作用是,将常量数组存储在ROM中。片内资源有限,所以将一些不会变的,不经常调用的,占用内存较大的数据存储在ROM中。
共阳极数码管段选表:
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
共阴极数码管,将上述共阳数码管数组中的值展开成二进制,在取反即可。
例如:0的值是0xC0,展开就是1100 0000,取反后就是0011 1111,转换为16进制就是0x3F。剩下同理。
一个数码管就要占用8个I/O口,当出现多个数码管时,会占用大量I/O口,但是单片机本身自带I/O口数量又不是很多,所以在出现多个数码管时,通过动态扫描方式,数码管每次显示一个,延时一段时间,利用人眼的视觉残留,人就可以正常看到所有数码管数值,这就是动态数码管。之前讲解的是静态数码管。
动态数码管的运行过程中,从微观角度来看,是只有一个数码管在亮的。
单片机使用了3-8译码器实现动态数码管。单片机的I/O数量有限,在蓝桥杯的板子上需要实现的功能多,就加入了锁存器,可以将当前数据锁存,通过锁存器的应用扩展功能。
例如:让第二个数码管显示数字0。
P2=0xc0;//打开数码管位选573锁存器
P0=0x02; //选中第二个数码管
P2=0xe0;//打开数码管段选573锁存器
P0=tab[0];//使数码管显示0
对于锁存器的介绍我们之后再将,现在只需要知道如何使用即可。
三、实验过程
(一)、点亮一个数码管
1、让最后一个数码管显示数字1
#include<STC15F2K60S2.H>
void main(void)
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序 关闭蜂鸣器继电器,LED全部熄灭
P2=0XC0;P0=0X01;P2=0XFF;P0=0XFF; //数码管初始化程序,打开第一个数码管
P0=0XF9;//P0=1111 1001 (b、c段亮,显示1)等同于 P00=1;P01=0;P02=0;P03=1;P04=1;P05=1;P06=1;P07=1;
while(1);
}
2、结合独立按键,每个按键按下显示不同数值
#include<STC15F2K60S2.H>
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={
0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
void DelayMs(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=845;j>0;j--);
}
void keyscan()
{
if(P30==0)
{
DelayMs(10); //延时10ms,消除抖动
if(P30==0)
{
P0=tab[0];
}
while(!P30); //松手检测
}
if(P31==0) //当检测到按键S6(对应P31口)按下时
{
DelayMs(10); //延时10ms,消除抖动
if(P31==0)
{
P0=tab[1];
}
while(!P31);
}
if(P32==0) //当检测到按键S5(对应P32口)按下时
{
DelayMs(10); //延时10ms,消除抖动
if(P32==0)
{
P0=tab[2];
}
while(!P32);
}
if(P33==0) //当检测到按键S5(对应P32口)按下时
{
DelayMs(10); //延时10ms,消除抖动
if(P33==0)
{
P0=tab[3];
}
while(!P33);
}
}
void main(void)
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序
P2=0XC0;P0=0X01;P2=0XFF;P0=0XFF; //数码管初始化
while(1)
{
keyscan();
}
}
(二)、点亮所有数码管
1、数码管显示12345678
#include<STC15F2K60S2.H>
unsigned char tab[]={
0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
unsigned char num=99;
unsigned int i;
unsigned char yi,er,san,si,wu,liu,qi,ba;
void Delayms(int ms);
void display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba);
void main(void)
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8;//将需要显示的下标值改为变量,这样改变变量即可改变显示字符,更具有灵活性
display(yi,er,san,si,wu,liu,qi,ba);
while(1);
}
void display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba)
{
P2=0XC0; //打开数码管位选573锁存器
P0=0X01; //选中第一个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[yi];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X02; //选中第二个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[er];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X04; //选中第一个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[san];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X08; //选中第二个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[si];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X10; //选中第一个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[wu];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X20; //选中第二个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[liu];
Delayms(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X40; //选中第一个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[qi];
Delays(1);
P2=0XC0; //打开数码管位选573锁存器
P0=0X80; //选中第二个数码管
P2=0XE0; //打开数码管段选573锁存器
P0=tab[ba];
Delayms(1);
}
void Delayms(int ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=845;j>0;j--);
}
2、结合矩阵按键,每个按键按下显示不同数值
和之前的使用相似,仅需要做一步分开个位十位即可。
yi=num/10;
er=num%10;
总结
在本篇中,我们学习了静态动态数码管,结合按键使用,顺便复习了按键的使用。数码管的介绍过程中,我们还提到了锁存器,对于锁存器的使用,当前阶段仅需要记住如何使用即可,不多做要求。
——————————————————————————————————————
本文纯原创,如有侵权请联系删除,如有错误,敬请批评指正,谢谢大家。