單片機實驗--交通燈
1、進一步熟悉HNIST-2型單片機系統
本文引用地址:http://www.104case.com/article/201611/319587.htm相關硬件電路;
2、掌握單片機中斷的應用和中斷處理程序的編寫方法;
3、掌握單片機內部定時/計數器的使用及編程方法
。
二、實驗前準備
1、完成作業4
2、根據實驗內容編寫好相關程序,并進行Proteus仿真。
三、實驗內容
實驗內容為3項,其中第1、2項必做。
1、基本交通燈。
根據圖3.2電路,用單片機的IO口控制4組紅綠黃共12個發光二極管,使發光二極管按照一定規則與次序發光與閃亮以實現模擬交通燈的功能。假設初始狀態為:(南北通行狀態)南北綠燈、東西紅燈(25s);后轉為過度狀態:南北黃燈、東西紅燈(5s);再轉為東西通行狀態:東西綠燈、南北紅燈25(s)。再轉為過渡狀態:東西黃燈、南北紅燈(5s),然后循環往復。
要求采用定時器實現所需要的定時時間。
2、鍵控交通燈。
按一下K1鍵
,保持南北通行狀態;按一下K2鍵
,保持東西通行狀態;按一下K3鍵
,保持正常交通燈。
要求在中斷中進行按鍵處理。
3、具有閃爍的交通燈。
在2的基礎上增加,綠燈最后5s閃爍,即亮0.5S滅0.5S閃爍。
四、實驗原理圖

圖3.2共有4個按鍵K1、K2、K3、K4,分別連接到單片機P2.0、P2.1、P2.2、P2.3引腳,按鍵后對應引腳為低電平,通過4個二極管D17、D18、D19、D20連接到P3.2(外部中斷0),這是二極管構成的相與電路,即任意按一個鍵能在P3.2上產生一個低電平或下降,作為中斷觸發信號。
五、軟件設計思想
1、定時思想。
采用定時器T0或T1的方式1定時500ms,每500ms中斷進行計數,計數10次即0.5s,計數20次即1s,對秒計數實現所需要的定時時間。
2、亮燈控制思想。
單片機控制燈引腳與燈對應如下,0點亮。
一共有四種狀態S0、S1、S2、S3,
a、南北通行S0狀態:
南北綠燈、東西紅燈,P0=11110111=0xf7,P1=10011110=0x9e;

b、過渡狀態S1:
南北黃燈、東西紅燈,P0=11111011=0xfb,P1=10101110=0xae;?

c、東西通行狀態S2:
東西綠燈、南北紅燈,P0=11111100=0xfc,P1=11110011=0xf3;?

d、過渡狀態S3:
東西黃燈、南北紅燈,P0=11111101=0xfd,P1=01110101=0x75;

設置一個秒計數單元SEC每秒+1,設置兩個控制值變量a,b。
首先令SEC=0,a=0xfd,b=0x75,處于S0狀態;
SEC==25,a=0xfc,b=0xf3,處于S1狀態;
SEC==30,a=0xfb,b=0xae,處于S2狀態;
SEC==55,a=0xf7,b=0x9e,處于S3狀態;
SEC==60,SEC=0,a=0xfd,b=0x75,處于S0狀態;
P0=a,P1=b。
3、交通燈鍵控
按鍵后即進入外部中斷0,在外部中斷0中斷程序中判斷:若是按K1鍵,控制南北通行狀態,并將定時器T0關閉,即可保持南北通行狀態;若是按K2鍵,控制東西通行狀態,并將定時器T0中斷關閉,即可保持東西通行狀態;若是按K3鍵,開啟定時器T0中斷,恢復正常交通燈。
4、閃爍控制?
在需要閃爍時,0.5s按正常顯示,0.5s全滅,即是閃爍效果。實現方法是:當=0.5s的時刻,并且在南北通行的最后5s(19或在東西通行的最后5s(49,滅綠燈:P0=0xf9,P1==0x24,當=1s的時刻,按正常顯示。
六、實驗源代碼
#include//基本的交通燈程序
#defineuintunsignedint
uintflag=20;//定義計時器標志
uintsecond=0;//定義秒標志
voidmain()
{
TMOD=0x01;//選擇T0計時器的工作方式1
TH0=(65536-50000)/256;//給TH0裝初始值為50000us
TL0=(65536-50000)%6;//給TH1裝初始值
TR0=1;//SCON中T0計時器打開
ET0=1;//打開定時計數器T0中斷
EA=1;//打開總中斷
P2=0xf7;//交通燈賦初始狀態
P3=0x9e;
while(1)//等待時間,做出反應
{
if(second==25)
{P2=0xf7;P3=0x9e;}
if(second==30)
{P2=0xfb;P3=0xae;}
if(second==55)
{P2=0xfc;P3=0xf3;}
if(second==60)
{P2=0xfd;P3=0x75;}
if(second>60)second=second`;
}
}
voidT0_int(void)interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%6;
flag--;
if(flag==0)
{
second++;//秒標志加1
flag=20;//重置計時器標志
}
}
#include//基本的交通燈程序
#defineuintunsignedint
sbitk1=P2^0;
sbitk2=P2^1;
sbitk3=P2^2;
uintflag=5;//定義計時器標志
uintsecond=0;//定義秒標志
uintkey;//判斷按鍵是否按下的標志
voidmain()
{
TMOD=0x01;//選擇T0計時器的工作方式1
TH0=(65536-5000)/256;//給TH0裝初始值為50000us
TL0=(65536-5000)%6;//給TH1裝初始值
TR0=1;//SCON中T0計時器打開
ET0=1;//打開定時計數器T0中斷
EX0=1;//開外部中斷0
IT0=1;//外部中斷0觸發方式為跳變沿觸發
PX0=1;//設置外部中斷0優先級為1
EA=1;//開總中斷
P1=0xf7;//交通燈賦初始狀態
P3=0x9e;
while(1)//等待時間,做出反應
{
if(second==10)
{P1=0xf7;P3=0x9e;}
if(second==20)
{P1=0xfb;P3=0xae;}
if(second==30)
{P1=0xfc;P3=0xf3;}
if(second==40)
{P1=0xfd;P3=0x75;}
if(second>40)second=second`;
if(key==1){TR0=0;P1=0xf7;P3=0x9e;}//如果k1按下,南北通行
if(key==2){TR0=0;P1=0xfc;P3=0xf3;}//如果k2按下,東西通行
if(key==3)//如果k3按下,普通交通燈
{
TR0=1;
TH0=(65536-5000)/256;
TL0=(65536-5000)%6;
}
}
}
voidT0_int(void)interrupt1//定時計數器的中斷子程序
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%6;
flag--;
if(flag==0)
{
second++;//秒標志加1
flag=5;//重置計時器標志
}
}
voidX0_int(void)interrupt0//外部中斷0的中斷子程序
{
if(k1==0)key=1;//根據各按鍵情況設置按鍵標志
if(k2==0)key=2;
if(k3==0)key=3;
}
評論