本程序的pdf格式的原理圖下載: http://www.zg4o1577.cn/f/ks51.pdf ,是在51hei單片機(jī)開(kāi)發(fā)板上面做的,只需要看數(shù)碼管部分的原理圖即可 其他的可以忽略.
/**
***********************************************************************************
* @file : main.c
* @author : xr
* @date : 2014年4月16日10:04:27 - 2014年4月16日11:09:50
* @version : V1.2.3
* @brief : 數(shù)碼管交通燈 TrafficLight 單片機(jī)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;
//數(shù)碼管編碼真值表
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"
};
//數(shù)碼管顯示緩沖區(qū)+LED小燈顯示緩沖區(qū)
unsigned char LedBuff[7] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char thr0, tlr0;//Timer0定時(shí)初值高低字節(jié)
bit flag1s = 0;
unsigned char timer = 0;//倒計(jì)時(shí)時(shí)間
enum TrafficLightColor
{
GREEN = 0, YELLOW = 1, RED = 2
};
static enum TrafficLightColor color = GREEN;//定義枚舉變量color,表示紅綠黃燈,開(kāi)始時(shí)是黃燈
/****************function definition************************/
void TrafficLight();
void ConfigTimer0(unsigned int xms);
void Initial();
/*主程序main()*/
void main(void)
{
Initial();
ConfigTimer0(1);//定時(shí)1ms
while (1)
{
if (flag1s)
{
flag1s = 0;
TrafficLight();//每過(guò)1s進(jìn)行交通燈的切換或timer的倒計(jì)時(shí),并分解timer到緩沖區(qū)
}
}
}
/*初始化*/
void Initial()
{
ADDR3 = 1;
ENLED = 0;//選擇U3,即選擇數(shù)碼管顯示+LED顯示
P0 = 0xFF;
}
/*定時(shí)器T0配置*/
void ConfigTimer0(unsigned int xms)
{
unsigned long tmp;
tmp = 11059200/12;//機(jī)器周期頻率
tmp = tmp * xms /1000;//定時(shí)xms需要的計(jì)數(shù)值(f*T=計(jì)數(shù)個(gè)數(shù))
tmp = 65536-tmp+18;//定時(shí)xms裝入的初值
thr0 = (unsigned char)(tmp >> 8);//重載值高字節(jié)
tlr0 = (unsigned char)tmp; //重載值低字節(jié)
TMOD &= 0xF0;//清零T0控制位
TMOD |= 0x01;//T0工作方式1,16位可設(shè)定時(shí)模式
TH0 = thr0;
TL0 = tlr0;//裝入初值
TR0 = 1;
ET0 = 1;
EA = 1;
}
/*交通燈的紅綠黃燈的切換和倒計(jì)時(shí)值的設(shè)定*/
void TrafficLight()
{
//首先判斷timer倒計(jì)時(shí)時(shí)間是否到了0,若到了0就進(jìn)行紅綠黃交通燈的切換,否則進(jìn)行倒計(jì)時(shí)
if (timer == 0) //倒計(jì)時(shí)到0,進(jìn)行交通燈的切換
{
switch (color)
{
case GREEN: color = YELLOW; LedBuff[6] = 0xE7; timer = 2;//綠燈切換到黃燈,LED6和LED5作為綠燈,倒計(jì)時(shí)3s
break;
case YELLOW: color = RED; LedBuff[6] = 0xFC; timer = 29;//黃燈切換到紅燈,LED3和LED2作為紅燈,倒計(jì)時(shí)30s
break;
case RED: color = GREEN; LedBuff[6] = 0x3F; timer = 45;//紅燈切換到綠燈,LED9和LED8作為綠燈,倒計(jì)時(shí)46s
break;
default: break;
}
}
else
{
timer--;//倒計(jì)時(shí)
}
/*分解timer并存放到數(shù)碼管緩沖區(qū)*/
LedBuff[0] = LedTable[timer % 10];
LedBuff[1] = LedTable[timer / 10 % 10];
}
/*數(shù)碼管刷新*/
void LedCharRefresh()
{
static unsigned char j = 0;//刷新索引
P0 = 0xFF;//消隱
// switch (j)
// {
// case 0: ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
// break; //LEDS0 = 0;點(diǎn)亮第一個(gè)數(shù)碼管
// 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;點(diǎn)亮第5個(gè)數(shù)碼管
// case 5: ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;
// break; //LEDS5=0;點(diǎn)亮第6個(gè)數(shù)碼管
// case 6: ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;
// break; //LEDS6=0;選中LED小燈
// default : break;
// }
P1 &= 0xF8;//清零P1口的低三位
P1 |= j;//低三位控制三八譯碼器工作,同時(shí)刷新6個(gè)數(shù)碼管和LED小燈
P0 = LedBuff[j++];
if (j >= 7)
j = 0; //j 0->6
}
/*定時(shí)器T0中斷服務(wù)*/
void Timer0_ISP() interrupt 1
{
static unsigned int counter = 0;//計(jì)數(shù)器
TH0 = thr0;
TL0 = tlr0;//重新裝入初值
counter++;
LedCharRefresh();//刷新數(shù)碼管和小燈
if (counter >= 1000) //1s
{
counter = 0;
flag1s = 1;
}
}