參考《51單片機C語言創新教程》溫子祺等著。
源碼轉自:《51單片機C語言創新教程》。
/*實驗名稱:交通燈實驗
*描述:交通燈實驗要求紅燈亮15秒,綠燈亮10秒,黃燈亮5秒,當紅燈切換為綠燈或者綠燈切換為紅燈,
要實現燈閃爍。紅燈、綠燈、黃燈的點亮持續時間可以通過串口來修改,
並在下壹個循環中更新數值。
*作者:溫子祺 *修改日期:2010/5/4 *說明:代碼註釋與講解詳見《51單片機C語言創新教程》溫子祺等著,北京航空航天大學出版社 */#include?"stc.h"
typedef?unsigned?charUINT8;
typedef?unsigned?int UINT16;
typedef?unsigned?longUINT32;?
typedef?charINT8;
typedef?int?INT16;
typedef?longINT32;
#define?TIMER0_INITIAL_VALUE?5000
#define?HIGH1
#define?LOW0
#define?ON?1
#define?OFF0
#define?SEG_PORTP0
#define?LS164_DATA(x)?{if((x))P0_4=1;else?P0_4=0;}?
#define?LS164_CLK(x){if((x))P0_5=1;else?P0_5=0;}?
#define?NORTH_R_LIGHT(x){if((x))P2_0=0;else?P2_0=1;}
#define?NORTH_Y_LIGHT(x){if((x))P2_1=0;else?P2_1=1;}
#define?NORTH_G_LIGHT(x){if((x))P2_2=0;else?P2_2=1;}
#define?SOUTH_R_LIGHT(x){if((x))P2_3=0;else?P2_3=1;}
#define?SOUTH_Y_LIGHT(x){if((x))P2_4=0;else?P2_4=1;}
#define?SOUTH_G_LIGHT(x){if((x))P2_5=0;else?P2_5=1;}
#define?TRAFFIC_STATUS_10
#define?TRAFFIC_STATUS_21
#define?TRAFFIC_STATUS_32
#define?UART_MARKER0xEE
UINT8?Timer0IRQEvent=0;
UINT8?Time1SecEvent=0;
UINT8?Time500MsEvent=0;
UINT8?TimeCount=0;
UINT8?SegCurPosition=0;
UINT8?LightOrgCount[4]={15,5,15,5};
UINT8?LightCurCount[4]={15,5,15,5};
UINT8?TrafficLightStatus=0;
code?UINT8?SegCode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
UINT8?SegBuf[4]?={0};code?UINT8?SegPosition[4]={0x07,0x0b,0x0d,0x0e};
typedef?struct?_LIGHT_VAL
{
UINT8?Head;
UINT8?val[4];?
}LIGHT_VAL;
typedef?union?_LIGHT_VAL_EX
{
LIGHT_VAL?lv; UINT8p[5];?}LIGHT_VAL_EX;
void?LS164Send(UINT8?byte)
{
UINT8?j;
for(j=0;j<=7;j++)
{
if(byte&(1<<(7-j))) {LS164_DATA(HIGH);
?}
?else
?{
LS164_DATA(LOW);
?}
LS164_CLK(LOW);? LS164_CLK(HIGH);}
}
void?RefreshDisplayBuf(UINT8?s1) ?//刷新顯示緩存
{
SegBuf[0]?=?s1%10;
SegBuf[1]?=?s1/10;
SegBuf[2]?=?s1%10;
SegBuf[3]?=?s1/10;
}
void?SegDisplay(void)
{
UINT8?t;
t?=?SegCode[SegBuf[SegCurPosition]];?
SEG_PORT?|=?0x0f;
LS164Send(t);?
SEG_PORT?=?(SEG_PORT|0x0f)?&?SegPosition[SegCurPosition];
if(++SegCurPosition>=4)?
{
SegCurPosition=0;
}
?
}
void?TimerInit(void)
{
TH1?=?0;
TL1?=?0;?
TH0?=?(65536-TIMER0_INITIAL_VALUE)/256;
TL0?=?(65536-TIMER0_INITIAL_VALUE)%256;?//定時1MS
TMOD?=?0x51; /*01010001?T1計數,T0定時*/
}
void?Timer0Start(void)
{
TR0?=?1; //啟動計時器1??ET0?=?1;
}
void?Timer0Stop(void)
{
TR0?=?0; //啟動計時器1? ET0?=?0;?}
void?PortInit(void)
{
?P0=P1=P2=P3=0xFF;
}
void?UartInit(void)
{
SCON=0x40;
T2CON=0x34;
RCAP2L=0xD9;
RCAP2H=0xFF;
REN=1;
ES=1;
}
void?UartSendByte(UINT8?byte)
{
SBUF=byte;
while(TI==0);
TI=0;
}
void?UartPrintfString(INT8?*str)
{
while(str?&&?*str)
{
UartSendByte(*str++);
}
}
void?main(void)
{
UINT8?i=0;
PortInit();
TimerInit();
Timer0Start();
UartInit();
RefreshDisplayBuf(LightCurCount[0]);
EA=1;
NORTH_R_LIGHT(ON);
SOUTH_G_LIGHT(ON);
while(1)
{
if(Timer0IRQEvent)
{?
Timer0IRQEvent=0;
TimeCount++;
if(TimeCount>=200)
{
TimeCount=0;
if(LightCurCount[0])
{
TrafficLightStatus=0;
}
else?if(LightCurCount[1])
{
TrafficLightStatus=1;
}
else?if(LightCurCount[2])
{
TrafficLightStatus=2;
}
else?if(LightCurCount[3])
{
TrafficLightStatus=3;
}
else?
{
for(i=0;i<4;i++)
{
LightCurCount[i]=LightOrgCount[i];}
TrafficLightStatus=0;
}
switch(TrafficLightStatus)
{
case?0:
{
NORTH_R_LIGHT(ON);
SOUTH_R_LIGHT(OFF);
NORTH_G_LIGHT(OFF);
SOUTH_G_LIGHT(ON);
NORTH_Y_LIGHT(OFF);
SOUTH_Y_LIGHT(OFF);
}
break;
case?1:
{
if(LightCurCount[1]%2)
{
NORTH_R_LIGHT(ON);
SOUTH_G_LIGHT(ON);
}
else
{
NORTH_R_LIGHT(OFF);
SOUTH_G_LIGHT(OFF);
}
NORTH_Y_LIGHT(ON);
SOUTH_Y_LIGHT(ON);
}
break;
case?2:
{
NORTH_R_LIGHT(OFF);
SOUTH_R_LIGHT(ON);
NORTH_G_LIGHT(ON);
SOUTH_G_LIGHT(OFF);
NORTH_Y_LIGHT(OFF);
SOUTH_Y_LIGHT(OFF);
}
break;
case?3:
{
if(LightCurCount[3]%2)
{
NORTH_G_LIGHT(ON);
SOUTH_R_LIGHT(ON);
}
else
{
NORTH_G_LIGHT(OFF);
SOUTH_R_LIGHT(OFF);
}
NORTH_Y_LIGHT(ON);
SOUTH_Y_LIGHT(ON);
}
break;?
default:break;?
}
RefreshDisplayBuf(LightCurCount[TrafficLightStatus]);
LightCurCount[TrafficLightStatus]--;
}
SegDisplay();
}
}
}
void?UartIRQ(void)interrupt?4?
{
static?UINT8?cnt=0; static?LIGHT_VAL_EX?LightValEx; if(RI) { RI=0;?LightValEx.p[cnt++]=SBUF;
if(LightValEx.lv.Head?==?UART_MARKER) {?if(cnt>=5)
{
for(cnt=1;cnt<5;cnt++)
{
LightOrgCount[cnt-1]=LightValEx.lv.val[cnt];?
LightCurCount[cnt-1]=LightValEx.lv.val[cnt];
}
cnt=0;
UartPrintfString("設置交通燈完成\r\n");
}
} else {cnt=0;
} }}
void?Timer0IRQ(void)?interrupt?1?
{
ET0 =?0;
TH0?=?(65536-TIMER0_INITIAL_VALUE)/256;
TL0?=?(65536-TIMER0_INITIAL_VALUE)%256;?//定時1MS
Timer0IRQEvent=1;
ET0 =?1;
}
=====================================================================
坐等拿分!