天天看點

應廣單片機應用之--數位管驅動

 在單片機應用中,數位管是經常用的是器件之一.如果把一個簡單的單片機系統看成是一台電腦,那麼數位管就相當于一台電腦的顯示器.現用一個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;