之前学习的数码管的编程方法只能让数码管的六位数都显示相同的数字~非常不实用!
数字电路中学过,生活中的数码管显示数字都是采用动态扫描的方法。
简单说就是段选和位选以相同的频率变化,当变化速度很快的时候,由于视觉暂留现象,我们就能看见百位十位个位...每一位数都不同的多种多样的数字啦!
代码如下:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
uint number,num;
uchar temp;
uchar code table[]={ 0x3f ,0x06 ,0x5b ,0x4f,0x66 ,0x6d, 0x7d ,0x07 ,0x7f, 0x6f};
void delay(uint z);
void display_number(uint number);
void main()
{
number=128;
display_number (number);
}
void delay(uint z)//延时函数 delay(1000)大致是1s
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display_number(uint number)
{
uint a[3];//写有code的数组不可修改
uchar code b[]={0xdf,0xef,0xf7};//显示数字的位
uint i;
dula=0;
wela=0;//预先置零
a[2]=number/100;
a[1]=(number%100)/10;
a[0]=(number%100)%10;//取得百位十位个位的值
if(a[2]==0&&a[1]==0) num=1;
else if(a[2]==0&&a[1]!=0) num=2;
else num=3;
wela=1;
i=num;
wela=0;
temp=b[i-1];
while(1)
{
wela=1;
P0=temp;
wela=0;
P0=0xff;//消隐
dula=1;
P0=table[a[i-1]];//段选显示数字
dula=0;
delay(5);//延时函数
if(i>1)i--;
else i=num;
if(temp!=0xdf)temp=_crol_(temp,1);//显示位
else temp=b[i-1];
P0=0xff;
}
}
有几点新学到的!
1.uchar和uint存储数字的范围需要注意,实际操作中超出存储范围会出错。
2.单片机语言中数组 uchar code table[]={xxx,x....};中code的作用:
数组或变量什么的默认的是存储在数据存储区。
为了防止数据存储区较小但数组的数据量太大,数据存储区存储不下,就应在定义式加上code,使数组存储在程序存储区(空间较大) 。
碎碎念:居然和今天复习的微机原理的知识巧妙挂钩了...我会好好学基础知识的:)
3.消隐语句。
举个栗子。
//
wela=1;
P0=temp;
wela=0;
P0=0xff;
dula=1;
P0=table[a[i-1]];//a[i-1]
dula=0;
delay(5);
//
如果delay(xx)延时时间较短,那么你需要的数字显示时间t1就很短。当段选信号打开dula=1;时,此刻P0的值仍为之前控制显示位的语句 P0=temp;在这一小点时间t2中,选择哪些段点亮的信号P0错误,就会显示错误的数字。
t1和t2时间如果没有较大差异,那么就会显示混乱!
所以注意延时时间和消隐语句哦~
4.数码管显示位
虽然很蠢但还是要注意!
六位数码管从左到右123456,若要靠右显示128,则百位(数字最高位)对应P0编码的11110111(0xf7)。(也就是从低位数的第4位)
十位11101111(0xef)。
个位同理。
所以它们是反着的...而且还要注意_cror_与_crol_右移(移向低位)和左移(移向高位)。
仿真截图:
嘻嘻完成啦~