应广单片机应用之--数码管驱动

迷迭香满地

迷迭香满地

2020-10-18

在单片机应用中,数码管是经常用的是器件之一.如果把一个简单的单片机系统看成是一台电脑,那么数码管就相当于一台电脑的显示器.现用一个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;

STT16 T16COUNTER;
IntFlashLed();
if ( count>0 )
{
count--;
}
else
{
count = 9;
/*1ms*/
FLAG_NMS= 1;
}

}
popaf;
}

精彩推荐

粤ICP备16095388号-1