专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

51单片机控制数码管动态显示程序

作者:huqin   来源:本站原创   点击数:  更新时间:2014年04月15日   【字体:

      说明: 驱动四位一体数码管动态显示数字,可方便的移植到其它程序中。
             例如:1、硬件改为三位一体或二位一体数码管,只需修改Display_Scan()函数COM个数。
                   2、本例中,采用了共阴数码管,如果用在共阳数码管,只需修改相应段码表。
           
             本程序使用P0口作为段码数据发送端,P2.0-P2.3作为数码管扫描选通,
             使用P0口时,因单片机内部没有上拉电阻,所以要外接上拉电阻(参考阻值470欧姆).


//                  STC89C52RC
//               +---------------+        
//                 |                 |
//                 |                 |           Digital Number
//               |               |    _______________________
//               |               |    |     __      __   __      __    |
//               |     P0.0--P0.7|===>| |  | |  | |  | |  | |
//               |    (a,b...g,h)|    | |--| |--| |--| |--| | 4位共阴数码管
//               |               |    |    |__|.|__|.|__|.|__|.|
//               |               |      -----------------------
//               |               |          |       |    |    |
//               |               |          |       |    |    |
//               |     P2.7(COM3)|--------+       |    |     |
//               |               |               |    |     |
//               |     P2.6(COM2)|-------------+    |     |
//               |               |                    |     |
//               |     P2.5(COM1)|------------------+     |
//               |               |                         |
//               |     P2.4(COM0)|-----------------------+
//               +---------------+


#include    
 
//                           函数声明
//=======================================================================
void DisplayNumber(unsigned int Num);
void delayms( int ms);
//=======================================================================
unsigned char code LED_table[]={       //使用附带“51单片机工具箱”可以很容易编码
0x3f,                             //"0"
0x06,                             //"1"
0x5b,                             //"2"            AAAA
0x4f,                             //"3"           F    B
0x66,                             //"4"           F    B
0x6d,                             //"5"            GGGG
0x7d,                             //"6"           E    C
0x07,                             //"7"           E    C
0x7f,                             //"8"            DDDD    H
0x6f,                             //"9"
0x00,                             //black
0x80                             //dot
};

#define black 10                // 空白
#define dot   11                // 小数点

unsigned char DisBuff[4];        //定义显示缓冲数组
unsigned char COM;

//                   定义通信端口
//===========================================================================
sbit COM0=P2^4;
sbit COM1=P2^5;                //对应口线由硬件确定
sbit COM2=P2^6;
sbit COM3=P2^7;
//===========================================================================


void Sys_Init()
{
  TMOD=0x01;                //定时器/计数器0为定时器方式 16位工作模式  
  TH0=(65536-1000)/256;        //初始时间常数
  TL0=(65536-1000)%6;     //1.0ms
  ET0=1;                    //定时器/计数器0中断允许
  EA=1;                        //总中断允许
  TR0=1;                    //启动定时器/计数器开始工作
}


void DisplayNumber(unsigned int Num)      //显示程序
{
    unsigned char i;                   
    EA=0;                                  //禁止总中断
    for(i=0;i<4;i++)
    {
     DisBuff[i]=Num;                            //拆分数字
    Num/=10;
    }
     
    for(i=3;i>=0;i--)                     //循环4次
     {
    if (DisBuff[i]==0) DisBuff[i]=black;  //消隐无效"0" 
    else break;                              //例如将 0123 改成 123,仅显示有效数字
     }   
    EA=1;                                  //总中断允许


}

void Display_Scan() interrupt 1                 // 中断服务程序,数码管选通扫描
{
TR0=0;                                       
  TH0=(65536-1000)/256;                         //高8位和低8位时间常数
  TL0=(65536-1000)%6; 
TR0=1;                                         //启动定时器0
   
    if(COM>3) COM=0;
    COM0=COM1=COM2=COM3=1;                     //将COM0-COM3置1,全暗
    switch(COM)
    {
    case 0:    P0=LED_table[DisBuff[0]]; COM0=0; break;     //分别选通COM0-COM3   低电平有效
    case 1: P0=LED_table[DisBuff[1]]; COM1=0; break;   
    case 2:    P0=LED_table[DisBuff[2]]; COM2=0; break;   
    case 3:    P0=LED_table[DisBuff[3]]; COM3=0; break;                                       
 
    }                                             // 与decp(0x20)位或,恰好点亮小数点位段
    COM++;                   
}


void delayms(int ms)
{
   unsigned int i;
   for(;ms>0;ms--)            //循环ms次
   {
      for(i=0;i<123;i++);   // for(i=0;i<123;i++); 每次1ms延迟@ 12.0MHz
   }                        // for(i=0;i<113;i++); 每次1ms延迟@ 11.0592MHz
}


void main()
{
 unsigned int i;                //定义变量
 
 Sys_Init();                        //初始化timer0
 
 while(1)                         //死循环,单片机必须是死循环
   {   
    DisplayNumber(i);            //调用数码管显示函数   
    delayms(200);                 //调用延时函数,使显示数字保持一段时间
    i++;                        //这里演示一个数字累加的程序
                                      //也可以直接写一个常数用来显示,看实际效果
   }                             //例如DisplayNumber(1234); 编译后将HEX文件
}                                //下载到学板里应该正常显示数字   1234    。

 

 


//                   另一种段编码方法   
//===========================================================================


//宏定义,数码管a-g各段对应的比特,更换硬件只用改动以下8行
#define    a 0x04                  //  AAAA
#define    b 0x01                    // F    B
#define    c 0x10                    // F    B
#define    d 0x40                    //  GGGG
#define    e 0x80                    // E    C
#define    f 0x02                    // E    C
#define g 0x08                    //  DDDD    H
#define    h 0x20
           

//用宏定义自动生成段码表,很好的写法,值得学习
//更换硬件无需重写段码表
unsigned char code LED_table[]={
a+b+c+d+e+f,                   //"0"
b+c,                           //"1"
a+b+d+e+g,                       //"2"
a+b+c+d+g,                       //"3"
b+c+f+g,                       //"4"
a+c+d+f+g,                       //"5"
a+c+d+e+f+g,                   //"6"
a+b+c,                           //"7"
a+b+c+d+e+f+g,                   //"8"
a+b+c+d+f+g,                   //"9"
b+c+e+f+g,                       //"H"
a+f+e+g,                       //"C"
d+e+f,                           //"L"
g,                               //"-"
0x00                           //black
};

#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g

关闭窗口

相关文章