在單片機應用中,數位管是經常用的是器件之一.如果把一個簡單的單片機系統看成是一台電腦,那麼數位管就相當于一台電腦的顯示器.現用一個2位半的數位管做個範例,循環顯示0-199,稍作改造就可以做成一個電腦.使用8pin數位管,采用掃描方式驅動,4*4,正好16段.單片機使用pms152,不多說上代碼.
實際顯示效果
#include "extern.h"
BIT COM1 :PB.0;/*Pin8*/
BIT COM2 :PB.1;/*Pin1*/
BIT COM3 :PB.2;/*Pin6*/
BIT COM4 :PB.3;/*Pin3*/
BIT SEG1 :PB.4;/*Pin7*/
BIT SEG2 :PB.5;/*Pin5*/
BIT SEG3 :PB.6;/*Pin4*/
BIT SEG4 :PB.7;/*Pin2*/
/*顯示變量區域*/
byte ucLcdComVoltSw;
byte ucHun;
byte ucTen;
byte ucOne;
bit SB2:ucHun.1;
bit SC2:ucHun.2;
bit SA0:ucTen.0;
bit SB0:ucTen.1;
bit SC0:ucTen.2;
bit SD0:ucTen.3;
bit SE0:ucTen.4;
bit SF0:ucTen.5;
bit SG0:ucTen.6;
bit SH0:ucTen.7;
bit SA1:ucOne.0;
bit SB1:ucOne.1;
bit SC1:ucOne.2;
bit SD1:ucOne.3;
bit SE1:ucOne.4;
bit SF1:ucOne.5;
bit SG1:ucOne.6;
bit SH1:ucOne.7;
/*系統時鐘變量*/
bit FLAG_NMS;/*定時時間是否到了cinit*/
word usSystick;
BYTE count;/* count區*/
word T16COUNTER;/*定時器初始化cinit*/
word usMsTmr;
BYTE ucVoltChgTmr;
BYTE ucVoltPerc;
/*系統變量*/
word point;
/*算法變量*/
BYTE div_src, div_val, div_res;
void Byte_Div_Byte (void)
{ // div_src[B] / div_val[B] = div_src[B] * div_val[B] + div_res[B]
BYTE div_cnt;
div_cnt = 0;
div_res = 0;
A = -div_val;
div_src <<= 1;
do
{
slc div_res;
div_cnt++;
div_res += A;
if (!CF) div_res -= A;
div_src <<<= 1;
} while (! div_cnt.3);
}
/* 共陽led表,共陰取反即可*/
void ReadLedTab ( void )
{
_pcadd
{
ret 0x3f;/*0*/
ret 0x06;/*1*/
ret 0x5b;/*2*/
ret 0x4f;/*3*/
ret 0x66;/*4*/
ret 0x6d;/*5*/
ret 0x7d;/*6*/
ret 0x07;/*7*/
ret 0x7f;/*8*/
ret 0x6f;/*9*/
}
}
/***************************************/
void TIME16_Init(void)
{
/*計數值清零*/
T16COUNTER =488;
/*ms标記reset*/
FLAG_NMS =0;
/*使能定時器*/
INTEN.T16=1;
/*關中斷*/
INTRQ = 0;
STT16 T16COUNTER;
/*計算方法16M/*/
$ T16M IHRC,/1,BIT11;
}
/*顯示百分比*/
void DispVoltPerc(void)
{
byte ucTemp;
if(ucVoltPerc>99&&ucVoltPerc<200)
{
/*表示顯示1*/
ucHun=0x00;
}
else
{
ucHun=0xff;
}
/*把電壓值變成0-99之間的值*/
div_src=ucVoltPerc;
div_val=100;
Byte_Div_Byte();
div_src=div_res;
div_val=10;
Byte_Div_Byte();
/*10 位*/
A=(div_src+1);
ReadLedTab();
/*儲存目前值*/
ucTemp=A;
/*輸出為0*/
if(ucTemp==0x3f)
{
/*最高位為1*/
if(!ucHun)
{
/*顯示十位*/
ucTen=~ucTemp;
}
/*十位為0,且最高位為0*/
else
{
/*十位不顯示*/
ucTen=0xff;
}
}
else
{
ucTen=~ucTemp;
}
/*個位*/
A=div_res+1;
ReadLedTab();
ucOne=~A;
}
void AppInit(void)
{
ucVoltChgTmr=0;
ucVoltPerc=0;
}
void FPPA0 ( void )
{
/* SYSCLK=2MHz, one cycles =0.5 us */
.ADJUST_IC SYSCLK=IHRC/8, IHRC=16MHz, VDD=3.9v;
WORD usTmp;
TIME16_Init();
/*全亮2s,檢視數位管是否連接配接OK*/
$ COM1 out,high;
$ COM2 out,high;
$ COM3 out,high;
$ COM4 out,high;
$ SEG1 out,low;
$ SEG2 out,low;
$ SEG3 out,low;
$ SEG4 out,low;
usTmp=200;
while(usTmp--)
{
.delay 20000;
wdreset; //複位看門狗定時器
}
/*關閉顯示*/
COM1=0;
COM2=0;
COM3=0;
COM4=0;
SEG1=0;
SEG2=0;
SEG3=0;
SEG4=0;
AppInit();
ucVoltPerc=0;
engint;
while ( 1 )
{
if(FLAG_NMS)
{
usMsTmr++;
/*300ms更新一次*/
if(usMsTmr>300)
{
/*數字範圍0-199*/
ucVoltPerc++;
if(ucVoltPerc>199)
{
ucVoltPerc=0;
}
usMsTmr=0;
}
FLAG_NMS=0;
}
/*數位管顯示*/
DispVoltPerc();
}
}
void IntFlashLed(void)
{
ucLcdComVoltSw++;
if(ucLcdComVoltSw>3)
{
ucLcdComVoltSw=0;
}
switch(ucLcdComVoltSw)
{
case 0:
SEG1=1;
SEG2=1;
SEG3=1;
SEG4=1;
#if 1
COM1=1;
COM2=0;
COM3=0;
COM4=0;
#endif
if(SA0)
{
SEG1=1;
}
else
{
SEG1=0;
}
if(SB0)
{
SEG2=1;
}
else
{
SEG2=0;
}
if(SC0)
{
SEG3=1;
}
else
{
SEG3=0;
}
if(SD0)
{
SEG4=1;
}
else
{
SEG4=0;
}
break;
case 1:
SEG1=1;
SEG2=1;
SEG3=1;
SEG4=1;
#if 0
COM1=1;
COM2=0;
COM3=1;
COM4=1;
#endif
#if 1
COM1=0;
COM2=1;
COM3=0;
COM4=0;
#endif
if(SF0)
{
SEG1=1;
}
else
{
SEG1=0;
}
if(SG0)
{
SEG2=1;
}
else
{
SEG2=0;
}
if(SE0)
{
SEG3=1;
}
else
{
SEG3=0;
}
if(SB2)
{
SEG4=1;
}
else
{
SEG4=0;
}
break;
case 2:
SEG1=1;
SEG2=1;
SEG3=1;
SEG4=1;
#if 0
COM1=1;
COM2=1;
COM3=0;
COM4=1;
#endif
#if 1
COM1=0;
COM2=0;
COM3=1;
COM4=0;
#endif
if(SA1)
{
SEG1=1;
}
else
{
SEG1=0;
}
if(SB1)
{
SEG2=1;
}
else
{
SEG2=0;
}
if(SC1)
{
SEG3=1;
}
else
{
SEG3=0;
}
if(SD1)
{
SEG4=1;
}
else
{
SEG4=0;
}
break;
case 3:
SEG1=1;
SEG2=1;
SEG3=1;
SEG4=1;
#if 0
COM1=1;
COM2=1;
COM3=1;
COM4=0;
#endif
#if 1
COM1=0;
COM2=0;
COM3=0;
COM4=1;
#endif
if(SF1)
{
SEG1=1;
}
else
{
SEG1=0;
}
if(SG1)
{
SEG2=1;
}
else
{
SEG2=0;
}
if(SE1)
{
SEG3=1;
}
else
{
SEG3=0;
}
if(SC2)
{
SEG4=1;
}
else
{
SEG4=0;
}
break;
default:
break;
}
}
void Interrupt ( void )
{
pushaf;
if ( Intrq.T16 )
{
Intrq.T16 = 0;