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

51单片机数码管交通灯程序

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

本程序的pdf格式的原理图下载: http://www.51hei.com/f/ks51.pdf  ,是在51hei单片机开发板上面做的,只需要看数码管部分的原理图即可 其他的可以忽略.

/**
  ***********************************************************************************
  * @file    :  main.c
  * @author  :  xr
  * @date    :  2014年4月16日10:04:27 - 2014年4月16日11:09:50
  * @version :  V1.2.3
  * @brief   :  数码管交通灯 TrafficLight  单片机STC89C52RC MCU  晶振 11.0592MHZ
  ***********************************************************************************
  */

#include <reg52.h>

//74HC138
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

//数码管编码真值表
unsigned char code LedTable[] = {
0xC0,  //"0"
                0xF9,  //"1"
                0xA4,  //"2"
                0xB0,  //"3"
                0x99,  //"4"
                0x92,  //"5"
                0x82,  //"6"
                0xF8,  //"7"
                0x80,  //"8"
                0x90,  //"9"
                0x88,  //"A"
                0x83,  //"B"
                0xC6,  //"C"
                0xA1,  //"D"
                0x86,  //"E"
                0x8E   //"F"
};

//数码管显示缓冲区+LED小灯显示缓冲区
unsigned char LedBuff[7] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

unsigned char thr0, tlr0;//Timer0定时初值高低字节
bit flag1s = 0;
unsigned char timer = 0;//倒计时时间

enum TrafficLightColor
{
GREEN = 0, YELLOW = 1, RED = 2
};

static enum TrafficLightColor color = GREEN;//定义枚举变量color,表示红绿黄灯,开始时是黄灯
/****************function definition************************/
void TrafficLight();
void ConfigTimer0(unsigned int xms);
void Initial();

/*主程序main()*/
void main(void)
{
Initial();
ConfigTimer0(1);//定时1ms

while (1)
{
if (flag1s)
{
flag1s = 0;
TrafficLight();//每过1s进行交通灯的切换或timer的倒计时,并分解timer到缓冲区
}
}
}

/*初始化*/
void Initial()
{
ADDR3 = 1;
ENLED = 0;//选择U3,即选择数码管显示+LED显示

P0 = 0xFF;
}

/*定时器T0配置*/
void ConfigTimer0(unsigned int xms)
{
unsigned long tmp;
tmp = 11059200/12;//机器周期频率
tmp = tmp * xms /1000;//定时xms需要的计数值(f*T=计数个数)
tmp = 65536-tmp+18;//定时xms装入的初值

thr0 = (unsigned char)(tmp >> 8);//重载值高字节
tlr0 = (unsigned char)tmp; //重载值低字节

TMOD &= 0xF0;//清零T0控制位
TMOD |= 0x01;//T0工作方式1,16位可设定时模式
TH0 = thr0;
TL0 = tlr0;//装入初值
TR0 = 1;
ET0 = 1;
EA  = 1;
}

/*交通灯的红绿黄灯的切换和倒计时值的设定*/
void TrafficLight()
{
//首先判断timer倒计时时间是否到了0,若到了0就进行红绿黄交通灯的切换,否则进行倒计时
if (timer == 0) //倒计时到0,进行交通灯的切换
{
switch (color)
{
case GREEN:  color = YELLOW; LedBuff[6] = 0xE7; timer = 2;//绿灯切换到黄灯,LED6和LED5作为绿灯,倒计时3s
break;
case YELLOW: color = RED; LedBuff[6] = 0xFC; timer = 29;//黄灯切换到红灯,LED3和LED2作为红灯,倒计时30s
break;
case RED:    color = GREEN; LedBuff[6] = 0x3F; timer = 45;//红灯切换到绿灯,LED9和LED8作为绿灯,倒计时46s
break;
default: break;
}
}
else
{
timer--;//倒计时
}

/*分解timer并存放到数码管缓冲区*/
LedBuff[0] = LedTable[timer % 10];
LedBuff[1] = LedTable[timer / 10 % 10];
}

/*数码管刷新*/
void LedCharRefresh()
{
   static unsigned char j = 0;//刷新索引

   P0 = 0xFF;//消隐
 
//   switch (j)
//   {
//   case 0: ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
// break; //LEDS0 = 0;点亮第一个数码管
// case 1: ADDR2 = 0; ADDR1 = 0; ADDR0 = 1;
// break;
// case 2: ADDR2 = 0; ADDR1 = 1; ADDR0 = 0;
// break;
// case 3: ADDR2 = 0; ADDR1 = 1; ADDR0 = 1;
// break;
// case 4: ADDR2 = 1; ADDR1 = 0; ADDR0 = 0;
// break; //LEDS4 = 0;点亮第5个数码管
// case 5: ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;
// break; //LEDS5=0;点亮第6个数码管
// case 6: ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;
// break; //LEDS6=0;选中LED小灯
// default : break;
//   }
   P1 &= 0xF8;//清零P1口的低三位
   P1 |= j;//低三位控制三八译码器工作,同时刷新6个数码管和LED小灯

   P0 = LedBuff[j++];
   if (j >= 7)
   j = 0; //j 0->6
}

/*定时器T0中断服务*/
void Timer0_ISP() interrupt 1
{
static unsigned int counter = 0;//计数器

TH0 = thr0;
TL0 = tlr0;//重新装入初值
counter++;
LedCharRefresh();//刷新数码管和小灯

if (counter >= 1000) //1s
{
counter = 0;
flag1s = 1;
}
}

关闭窗口

相关文章