????????單片機(jī)P1口控制數(shù)碼管段選,P2口控制數(shù)碼管位選,P0口控制兩邊的燈光。
void SMG_shift()
{
P2=~(0x01<<shift);
switch(shift)
{
case 0:bits=second1/10; break;
case 1:bits=second1%10; break;
case 2:bits=second2/10; break;
case 3:bits=second2%10; break;
}
P1=smg[bits];
shift=(shift+1)%4;
}
????????首先是數(shù)碼管控制函數(shù),聲明一個(gè)變量shift作為數(shù)碼管位移量,首先進(jìn)行位選,這里數(shù)碼管使用的是共陰極數(shù)碼管,所以位選腳為低時(shí)點(diǎn)亮,因?yàn)槲灰茣r(shí)除了置1的位保持1,其他的位都會(huì)變成0(例如0x01<<1是0x02,0xfe<<1是0x0xfc),為了避免位移時(shí)會(huì)點(diǎn)亮其他數(shù)碼管,這里對(duì)0x01位移后進(jìn)行取反,switch語句對(duì)變量bits賦值,結(jié)合數(shù)碼管段碼表達(dá)到第一位顯示計(jì)時(shí)器一的十位,第二位顯示計(jì)時(shí)器二并以此類推的效果。
void timer()
{
if(second<=60 && second>33) //左綠燈右紅燈
{
status1=1;
status2=3;
second1=second-33; //左邊倒計(jì)時(shí)為second-33
second2=second-30;
}
if(second<=33 && second>30) //左黃燈右紅燈
{
status1=2;
status2=3; //此時(shí)左右倒計(jì)時(shí)相等
second2=second-30;
second1=second2;
}
if(second<=30 && second>3) //左紅燈右綠燈
{
status1=3;
status2=1;
second1=second; //左倒計(jì)時(shí)等于second
second2=second-3; //右倒計(jì)時(shí)比左倒計(jì)時(shí)少3秒
}
if(second<=3 && second>=0) //左紅燈右黃燈
{
status1=3;
status2=2;
second1=second;
second2=second;
}
second--;
if(second==0)
second=60;
}
????????倒計(jì)時(shí)的效果用變量second實(shí)現(xiàn),將一個(gè)紅綠燈周期設(shè)定為60秒,則在60秒中需要實(shí)現(xiàn)左綠右紅,左黃右紅,左紅右綠,左紅右黃的循環(huán),黃燈占用3秒,綠燈27秒,紅燈30秒,在倒計(jì)時(shí)函數(shù)中分別對(duì)計(jì)時(shí)器一二進(jìn)行賦值,顯示當(dāng)前燈的剩余時(shí)間,對(duì)status賦值控制燈的變化。
void Light_Ctrl() //紅綠燈控制
{
switch(status1)
{
case 1: P0 |= 0x07; P0 &= 0xfe; break;
case 2: P0 |= 0x07; P0 &= 0xfd; break;
case 3: P0 |= 0x07; P0 &= 0xfb; break;
}
switch(status2)
{
case 1: P0 |= 0x38; P0 &= 0xf7; break;
case 2: P0 |= 0x38; P0 &= 0xef; break;
case 3: P0 |= 0x38; P0 &= 0xdf; break;
}
}
????????燈光控制函數(shù)利用上一個(gè)函數(shù)對(duì)status的賦值控制P0口輸出,在燈光變化之前先對(duì)之前的狀態(tài)用|=置1,再用&=置0(這里的燈光是低電平點(diǎn)亮),否則在變燈的時(shí)候會(huì)出現(xiàn)三個(gè)燈同時(shí)亮的情況。
void main()
{
Timer0Init();
P1=0xff;
P0=0xff;
second1=27;
second2=30;
while(1);
}
????????主函數(shù)包含了定時(shí)器0、P0P1口和計(jì)時(shí)器變量的初始化,while(1)死循環(huán)避免main函數(shù)循環(huán)運(yùn)行。
void timer0ISP () interrupt 1 //定時(shí)器0中斷服務(wù)函數(shù)
{
TH0=(65536-1000)/256; //1ms一次脈沖
TL0=(65536-1000)%256;
Light_Ctrl();
i++;
SMG_shift();
if(i>=1000)
{
i=0;
timer();
}
}
????????定時(shí)器0中斷服務(wù)程序包含燈光控制及數(shù)碼管刷新函數(shù),1秒運(yùn)行一次倒計(jì)時(shí)函數(shù)。
????????全部代碼
#include <REG51.H>
#define uint unsigned int
#define uchar unsigned char
uint second1,second2,i,bits,status1,status2,shift;
uint second=60;
uchar smg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Timer0Init()
{
TMOD=0x01; //工作模式1 ,需賦初值
TH0=(65536-1000)/256; //定時(shí)1000,高八位
TL0=(65536-1000)%256;
EA=1; //打開中斷允許總開關(guān)
ET0=1; //定時(shí)器0中斷允許
TR0=1; //定時(shí)器0啟動(dòng)控制
}
void SMG_shift()
{
P2=~(0x01<<shift);
switch(shift)
{
case 0:bits=second1/10; break;
case 1:bits=second1%10; break;
case 2:bits=second2/10; break;
case 3:bits=second2%10; break;
}
P1=smg[bits];
shift=(shift+1)%4;
}
void timer()
{
if(second<=60 && second>33) //左綠燈右紅燈
{
status1=1;
status2=3;
second1=second-33; //左邊倒計(jì)時(shí)為second-33
second2=second-30;
}
if(second<=33 && second>30) //左黃燈右紅燈
{
status1=2;
status2=3; //此時(shí)左右倒計(jì)時(shí)相等
second2=second-30;
second1=second2;
}
if(second<=30 && second>3) //左紅燈右綠燈
{
status1=3;
status2=1;
second1=second; //左倒計(jì)時(shí)等于second
second2=second-3; //右倒計(jì)時(shí)比左倒計(jì)時(shí)少3秒
}
if(second<=3 && second>=0) //左紅燈右黃燈
{
status1=3;
status2=2;
second1=second;
second2=second;
}
second--; //每運(yùn)行一次該函數(shù)減一秒
if(second==0)
second=60;
}
void Light_Ctrl() //紅綠燈控制
{
switch(status1)
{
case 1: P0 |= 0x07; P0 &= 0xfe; break;
case 2: P0 |= 0x07; P0 &= 0xfd; break;
case 3: P0 |= 0x07; P0 &= 0xfb; break;
}
switch(status2)
{
case 1: P0 |= 0x38; P0 &= 0xf7; break;
case 2: P0 |= 0x38; P0 &= 0xef; break;
case 3: P0 |= 0x38; P0 &= 0xdf; break;
}
}
void main()
{
Timer0Init();
P1=0xff;
P0=0xff;
second1=27;
second2=30;
while(1);
}
void timer0ISP () interrupt 1 //定時(shí)器0中斷服務(wù)函數(shù)
{
TH0=(65536-1000)/256; //1ms一次脈沖
TL0=(65536-1000)%256;
Light_Ctrl();
i++;
SMG_shift();
if(i>=1000)
{
i=0;
timer();
}
}
????????仿真電路圖
文章來源:http://www.zghlxwxcb.cn/news/detail-502596.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-502596.html
到了這里,關(guān)于基于51單片機(jī)的簡易紅綠燈電路的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!