源代碼轉自:51單片機C語言創新教程。
/*實驗名稱:紅綠燈實驗
*說明:紅綠燈實驗要求紅燈亮15秒,綠燈亮10秒,黃燈亮5秒。
當紅燈切換到綠燈或者綠燈切換到紅燈時,
?以實現閃爍的燈光。可以通過串口修改紅燈、綠燈、黃燈的點亮時長。
?並在下壹個周期更新該值。
*作者:溫梓岐
*修訂日期:2010/5/4
*註:代碼註釋和解釋請參考溫梓岐等主編的《51單片機C語言創新教程》,北航出版社。
*/
#包含?" stc.h "
typedef?未簽名?夏爾?UINT8
typedef?未簽名?int uit 16;
typedef?未簽名?龍?UINT32
typedef?charINT8
typedef?int?int 16;
typedef?longINT32
#定義?定時器0 _初始值?5000
#定義?高?1
#定義?低0
#定義?開?1
#定義?OFF0
#定義?SEG_PORT?p0蛋白
#定義?ls 164 _ DATA(x){ if((x))P0 _ 4 = 1;不然呢?P0 _ 4 = 0;}?
#定義?LS164_CLK(x)?{ if((x))P0 _ 5 = 1;不然呢?P0 _ 5 = 0;}?
#定義?NORTH_R_LIGHT(x)?{ if((x))P2 _ 0 = 0;不然呢?P2 _ 0 = 1;}
#定義?北Y光(x)?{ if((x))P2 _ 1 = 0;不然呢?P2 _ 1 = 1;}
#定義?北_ G _光(x)?{ if((x))P2 _ 2 = 0;不然呢?P2 _ 2 = 1;}
#定義?南R光(x)?{ if((x))P2 _ 3 = 0;不然呢?P2 _ 3 = 1;}
#定義?南光(x)?{ if((x))P2 _ 4 = 0;不然呢?P2 _ 4 = 1;}
#定義?SOUTH_G_LIGHT(x)?{ if((x))P2 _ 5 = 0;不然呢?P2 _ 5 = 1;}
#定義?TRAFFIC_STATUS_1?0
#定義?流量_狀態_2?1
#定義?流量_狀態_3?2
#定義?UART_MARKER0xEE
uint 8 timer 0 IRQ event = 0;
uint 8 time 1 sec event = 0;
uint 8 time 500 msevent = 0;
uint 8 time count = 0;
uint 8 segcurposition = 0;
uint 8 lightorgcount[4]= { 15,5,15,5 };
uint 8 lightcurcount[4]= { 15,5,15,5 };
uint 8 trafficilightstatus = 0;
代碼?UINT8SegCode[10]?={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x 90 };
UINT8SegBuf[4]?={0};
代碼?UINT8SegPosition[4]={0x07,0x0b,0x0d,0x0e };
typedef?struct?_燈光_瓦爾
{
UINT8?頭;?
UINT8?val[4];?
} LIGHT _ VAL
typedef?工會?_LIGHT_VAL_EX
{
LIGHT_VAL?呂;
uint 8 p[5];?
} LIGHT _ VAL _ EX
作廢?LS164Send(UINT8?字節)
{
UINT8?j;
for(j = 0;j & lt=7;j++)
{
如果(字節& amp(1 & lt;& lt(7-j)))
{
LS164_DATA(高);
?}
?其他
?{
LS164_DATA(低);
?}
LS164_CLK(低);?
LS164_CLK(高);
}
}
作廢?RefreshDisplayBuf(UINT8?s1)?//刷新顯示緩存
{
SegBuf[0]?=?s 1% 10;
SegBuf[1]?=?s 1/10;
SegBuf[2]?=?s 1% 10;
SegBuf[3]?=?s 1/10;
}
作廢?分段顯示(空)
{
UINT8t
t?=?seg code[seg buf[SegCurPosition]];?
SEG_PORT?|=?0x0f
ls 164 send(t);?
SEG_PORT?=?(SEG_PORT|0x0f)?& amp?seg position[SegCurPosition];
if(++SegCurPosition & gt;=4)?
{
SegCurPosition = 0;
}
}
作廢?TimerInit(無效)
{
TH1?=?0;
TL1?=?0;?
TH0?=?(65536-定時器0 _初始值)/256;
TL0?=?(65536-定時器0 _初始值)% 256;?//計時1毫秒
TMOD?=?0x 51;/*01010001?T1計數,T0計時*/
}
作廢?定時器0啟動(無效)
{
TR0?=?1;//啟動定時器1?
?ET0?=?1;
}
作廢?定時器0停止(無效)
{
TR0?=?0;//啟動定時器1?
ET0?=?0;
}
作廢?PortInit(void)
{
?P0 = p 1 = P2 = P3 = 0x ff;
}
作廢?UartInit(無效)
{
SCON = 0x 40;
T2CON = 0x34
RCAP2L = 0xD9
RCAP2H = 0xFF
任= 1;
ES = 1;
}
作廢?UartSendByte(UINT8?字節)
{
SBUF =字節;
while(TI = = 0);
TI = 0;
}
作廢?UartPrintfString(INT8?*str)
{
while(str?& amp& amp?*str)
{
UartSendByte(* str++);
}
}
作廢?主要(無效)
{
UINT8?I = 0;
PortInit();
timer init();
定時器0 start();
UART init();
RefreshDisplayBuf(LightCurCount[0]);
EA = 1;
NORTH_R_LIGHT(開);
SOUTH_G_LIGHT(開);
while(1)
{
if(定時器0IRQEvent)
{?
定時器0 IRQ event = 0;
time count++;
if(時間計數& gt=200)
{
time count = 0;
if(LightCurCount[0])
{
traffilightstatus = 0;
}
不然呢?if(LightCurCount[1])
{
traffilightstatus = 1;
}
不然呢?if(LightCurCount[2])
{?
traffilightstatus = 2;
}
不然呢?if(LightCurCount[3])
{
traffilightstatus = 3;
}
不然呢?
{
for(I = 0;我& lt4;i++)
{
LightCurCount[I]= LightOrgCount[I];
}
traffilightstatus = 0;
}
開關(交通指示燈狀態)
{
案子?0:
{
NORTH_R_LIGHT(開);
SOUTH_R_LIGHT(關);
NORTH_G_LIGHT(關);
SOUTH_G_LIGHT(開);
NORTH_Y_LIGHT(關);
SOUTH_Y_LIGHT(關);
}
打破;
案子?1:
{
if(LightCurCount[1]%2)
{
?NORTH_R_LIGHT(開);
SOUTH_G_LIGHT(開);
}
其他
{
?NORTH_R_LIGHT(關);
SOUTH_G_LIGHT(關);
}
NORTH_Y_LIGHT(開);
SOUTH_Y_LIGHT(開);
}
打破;
案子?2:
{
NORTH_R_LIGHT(關);
南_R_LIGHT(開);
NORTH_G_LIGHT(開);
SOUTH_G_LIGHT(關);
NORTH_Y_LIGHT(關);
SOUTH_Y_LIGHT(關);
}
打破;
案子?3:
{
if(LightCurCount[3]%2)
{
?NORTH_G_LIGHT(開);
南_R_LIGHT(開);
}
其他
{
?NORTH_G_LIGHT(關);
SOUTH_R_LIGHT(關);
}
NORTH_Y_LIGHT(開);
SOUTH_Y_LIGHT(開);
}
打破;
默認:break
}
RefreshDisplayBuf(LightCurCount[trafficklightstatus]);
LightCurCount[traffic light status]-;
}
seg display();
}
}
}
作廢?UartIRQ(void)中斷?4?
{
靜電?UINT8?CNT = 0;
靜電?LIGHT_VAL_EX?LightValEx
中頻(RI)
{?
RI = 0;
?light valex . p[cnt++]= SBUF;
if(LightValEx.lv.Head?==?UART_MARKER)
{
if(CNT & gt;=5)
{
for(CNT = 1;cnt & lt5;cnt++)
{
LightOrgCount[CNT-1]= light valex . LV . val[CNT];?
LightCurCount[CNT-1]= light valex . LV . val[CNT];
}
CNT = 0;
UartPrintfString("設置紅綠燈完成\ r \ n ");
}
}
其他
{
CNT = 0;
}
}
}
作廢?定時器0IRQ(void)?打斷?1?
{
ET0 = 0;
TH0?=?(65536-定時器0 _初始值)/256;
TL0?=?(65536-定時器0 _初始值)% 256;?//計時1毫秒
timer 0 IRQ event = 1;
ET0 = 1;
}
=====================================================================
等著拿分吧!