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

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