之前學習的數碼管的編程方法只能讓數碼管的六位數都顯示相同的數字~非常不實用!
數字電路中學過,生活中的數碼管顯示數字都是採用動態掃描的方法。
簡單說就是段選和位選以相同的頻率變化,當變化速度很快的時候,由於視覺暫留現象,我們就能看見百位十位個位...每一位數都不同的多種多樣的數字啦!
代碼如下:
#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_右移(移向低位)和左移(移向高位)。
仿真截圖:
嘻嘻完成啦~