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

单片机左右流水灯与数码管动态显示C程序

作者:徐冉   来源:本站原创   点击数:  更新时间:2014年03月24日   【字体:

本程序所用的原理图下载: 点这里 ,单片机芯片使用的stc89c52;找到相应部分即可.这是一整个单片机开发板的电路图其他的忽略.以下是通过测试的源代码:

/*
*功能:用定时器0实现定时200毫秒流水灯,
*    同时用定时器1实现动态显示654321,
*    且蜂鸣器发声;
*日期:2014-03-24
*作者:徐冉
*注意事项:若打开两个定时器时,必须使用两个定时器,
*     否则两个定时器都不工作!!!
**/
/**********AT89C52-RC 51hei单片机实验板**************/
/*************51hei-开发板*********************/
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit wela = P2^7;  //数码管位声明
sbit dula = P2^6; //数码管段选声明
sbit FM = P2^3;//蜂鸣器声明
uchar counter = 0, counter1 = 0, j = 0, flag = 0, flag1 = 0;
uchar num = 6, num1 = 0;
//数码管段选编码
uchar code table_du [] = {  
          0x3F,  //"0"
                   0x06,  //"1"
                   0x5B,  //"2"
                   0x4F,  //"3"
                   0x66,  //"4"
                   0x6D,  //"5"
                   0x7D,  //"6"
                   0x07,  //"7"
                   0x7F,  //"8"
                   0x6F,  //"9"
                   0x77,  //"A"
                   0x7C,  //"B"
                   0x39,  //"C"
                   0x5E,  //"D"
                   0x79,  //"E"
                   0x71,  //"F"
                   0x76,  //"H"
                   0x38,  //"L"
                   0x37,  //"n"
                   0x3E,  //"u"
                   0x73,  //"P"
                   0x5C,  //"o"
                   0x40,  //"-"
                   0x00,  //熄灭
                   0x00  //自定义
       };
//数码管位选编码
uchar code table_we[] = {
       0xfe,
       0xfd,
       0xfb,
       0xf7,
       0xef,
       0xdf
       };
void init();
void display();
void main()
{
 
 init();
 while(1)
 {
   if(counter1 == 30)
   {
    counter1 = 0;
   display();
   num--;
   num1++;
   if(num == 0)
   {
    num = 6;
   }
   if(num1 == 6)
   {
    num1 = 0;
    }
   }
  
   if(counter == 200)//定时到4秒后,流水灯向右流动
   {     
    counter = 0;//counter清零,
   //关闭定时器0
   TR0 = 0;
   //ET0 = 0;
   flag = 1; //标志变量置1后,定时器重新初始化
   TH0 = 0xB8; //定时器0定时20毫秒
   TL0 = 0x00;
   TR0 = 1;   //重新打开定时器0
   //ET0 = 1;
   j = 0;
   }
 }
}
//定时器初始化程序
void init()
{
 //定时器0和定时器1初始化函数
 TMOD = 0x11;//定义定时器1和0在工作方式1下
 TH0 = 0xB8; //定时器0定时20毫秒
 TL0 = 0x00;
 TH1 = 0xFC; //定时器1定时20毫秒
 TL1 = 0x67;
 TR0 = 1;   //打开定时器0
 TR1 = 1;   //打开定时器1
 EA = 1; //打开总中断
 ET0 = 1;  //打开定时器0中断
 ET1 = 1;  //打开定时器1中断
}
//数码管显示子程序
void display()
{
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 
 dula = 1;
 P0 = table_du[num];
 dula = 0;
 P0 = 0xff;
 wela = 1;
 P0 = table_we[num1];
 wela = 0;
 
}
//中断定时器0
void int_time0() interrupt 1
{
  TH0 = 0xB8;
  TL0 = 0x00;
  counter++;
  if(flag == 0)
  {
   if(counter % 10 == 0)//定时200毫秒
   {
    P1 = ~(1 << j++);//流水灯左移流动
    if(j == 8)
    {
     j = 0;
    }
   }
   }
   else
   {
    if(counter % 5 == 0)
   {
    //counter = 0;
     //流水灯右移流动
     P1 = ~(0x80 >> j++);
    FM = ~FM;
    if(j == 8)
    j = 0;
   }
   }
 
 
}
//中断定时器1
void int_time1() interrupt 3
{
   TH1 = 0xFC;
  TL1 = 0x67;
  counter1++;
 
}
 

 

关闭窗口

相关文章