005-数码管的使用
数码管的使用
- 功能:实现数码管的控制及使用方式
方案一:控制数码管1显示数字5
#include<reg52.h>
sbit Ls1 = P2^2; //74LS138控制端
sbit Ls2 = P2^3;
sbit Ls3 = P2^4;
void main()
{
Ls1 = 0; //选择数码管1
Ls2 = 0;
Ls3 = 0;
//P0 = 0x6D; //数字5 (注意:h,g,f,e,d,c,b,a,显示谁为1)
P0 = 0x77;
while(1);
}
方案二:数码管从0~F动态显示
#include<reg52.h>
//数码管从0~F动态显示;
sbit LS1 = P2^2;
sbit LS2 = P2^3;
sbit LS3 = P2^4;
void main()
{
unsigned char shu_ma_guan[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0~F的对应值
unsigned char i = 0;
unsigned int cnt = 0;
TMOD = 0x01; //定时器,一次10ms
TH0 = 0xD8;
TL0 = 0xF0;
TR0 = 1;
LS1 = 0; //74LS138片选一号数码管
LS2 = 0;
LS3 = 0;
while(1)
{
P0 = shu_ma_guan[i];
if(TF0 == 1)
{
TF0 = 0;
TH0 = 0xD8;
TL0 = 0xF0;
cnt++;
if(cnt == 100)
{
cnt = 0;
i++;
if(i == 15)
{
i = 0;
}
}
}
}
}
方案三:八个数码管动态显示,实现每一秒数字加1的效果,从1显示至99999999
#include<reg52.h> //头文件
sbit LS1 = P2^2; //74LS138控制端
sbit LS2 = P2^3;
sbit LS3 = P2^4;
unsigned char shu_ma_guan[16] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //0~F的对应值
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char LedBuff[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //定义8个数码管初始状态均为00000000,即都不显示
void main() //主函数
{
unsigned int cnt = 0;
unsigned long sec = 0;
unsigned char i = 0;
TMOD = 0x01; //定时器定义,晶振12Mhz,每次1ms
TH0 = 0xFC;
TL0 = 0x18;
TR0 = 1; //打开定时器
while(1)
{
if(TF0 == 1) //溢出标志
{
TF0 = 0; //溢出标志复位
TH0 = 0xFC; //定时器定义复位
TL0 = 0x18;
cnt++; //定时器溢出计次
if(cnt == 1000) //溢出1000次,时长1000ms,为1秒
{
cnt = 0; //计次清零
sec++; //时长加1.即过了一秒钟
LedBuff[0] = shu_ma_guan[sec%10]; //确定数码管在某个时间时各个位的显示数字
LedBuff[1] = shu_ma_guan[sec/10%10];
LedBuff[2] = shu_ma_guan[sec/100%10];
LedBuff[3] = shu_ma_guan[sec/1000%10];
LedBuff[4] = shu_ma_guan[sec/10000%10];
LedBuff[5] = shu_ma_guan[sec/100000%10];
LedBuff[6] = shu_ma_guan[sec/1000000%10];
LedBuff[7] = shu_ma_guan[sec/10000000%10];
}
//备注:这里的片选信号排序LS3为高位,LS1为低位,对应74LS138译码器中C为高位,A为低位
//下面一段作用为:数码管刷新
if(i == 0)
{LS1=0; LS2=0; LS3=0;i++;P0=LedBuff[0];} //片选使得第一个数码管显示
else if(i == 1)
{LS1=1; LS2=0; LS3=0;i++;P0=LedBuff[1];} //片选使得第二个数码管显示
else if(i == 2)
{LS1=0; LS2=1; LS3=0;i++;P0=LedBuff[2];}
else if(i == 3)
{LS1=1; LS2=1; LS3=0;i++;P0=LedBuff[3];}
else if(i == 4)
{LS1=0; LS2=0; LS3=1;i++;P0=LedBuff[4];}
else if(i == 5)
{LS1=1; LS2=0; LS3=1;i++;P0=LedBuff[5];}
else if(i == 6)
{LS1=0; LS2=1; LS3=1;i++;P0=LedBuff[6];}
else if(i == 7)
{LS1=1; LS2=1; LS3=1;i=0;P0=LedBuff[7];}
}
}
}
备注:关于此方案中的数码管刷新有一种新的方法,替换上面的刷新代码即可实现,具体代码如下:
switch(i)
{
case 0: LS3=0;LS2=0;LS1=0;i++;P0=LedBuff[0];break;
case 1: LS3=0;LS2=0;LS1=1;i++;P0=LedBuff[1];break;
case 2: LS3=0;LS2=1;LS1=0;i++;P0=LedBuff[2];break;
case 3: LS3=0;LS2=1;LS1=1;i++;P0=LedBuff[3];break;
case 4: LS3=1;LS2=0;LS1=0;i++;P0=LedBuff[4];break;
case 5: LS3=1;LS2=0;LS1=1;i++;P0=LedBuff[5];break;
case 6: LS3=1;LS2=1;LS1=0;i++;P0=LedBuff[6];break;
case 7: LS3=1;LS2=1;LS1=1;i=0;P0=LedBuff[7];break;
default: break;
}
问题一:鬼影
鬼影:在以上方式实现从1~99999999的过程中,数码管显示可能会出现鬼影,即在非显示段会出现暗红色的情况。(目前所用的普中A2开发板好像没出现此问题,但是会有开发板出现这样的情况,例如金沙滩工作室的开发板)
出现原因:瞬态误差。
鬼影的解决方法:目前有两种方式:
- 每次刷新完后delay一下,即在break语句前添加delay,但是这样解决时,一方面delay时间难以确定,另外这样也会占用单片机CPU,一般不推荐使用。
- 每次刷新之前先关闭一下 数码管所有的段,即可以在刷新代码前加上语句:
P0 = 0x00; //使得数码管的所有段全灭
问题二:数码管加1时其他数码管同一抖动一下
出现原因:确定数码管在某个时间时各个位的显示数字的计算占用了一定的时间,造成了刷新时间的不均衡,在加1时造成其他数码管抖动闪烁。
解决办法:中断机制——在计算的过程中,如果刷新时间到了,立马去执行刷新任务,刷新结束后再回头进行计算过程(具体方式见006-中断)。
本文来自博客园,作者:shihao_Yang,转载请注明原文链接:https://www.cnblogs.com/Yang-shihao/p/14352291.html