交通灯单片机c语言
1. 鍗旷墖链篊璇瑷绾㈢豢𨱔绋嫔簭锛岃佹眰锛氭暟镰佺℃樉绀烘椂闂村掕℃椂銆16*16LED镣归樀鏄剧ず妯″潡鏄剧ず绾㈢豢榛勭伅銆
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define BLKN 2 //鍒楅挛瀛桦櫒鏁
sbit G = P1^7; //P1.7涓烘樉绀轰笡闄鍏佽告带鍒朵俊鍙风鍙
sbit RCLK = P2^0; //P2.0涓鸿緭鍑洪挛瀛桦拹锣勫櫒镞堕挓淇″彿绔
sbit SCLR = P2^1; //P2.1涓虹Щ浣嶅瘎瀛桦櫒娓呪棆绔
void delay(uint); //寤舵椂鍑芥暟
uchar data display[32]; //鏄剧ず缂揿瓨
uchar code BMP[][32]={{16,0,16,0,37,248,36,64,120,64,8,64,16,64,32,64,124,64,0,64,0,64,12,64,112,64,3,252,0,0,0,0},
{16,0,19,240,32,16,41,240,120,16,19,252,32,64,122,72,1,80,0,224,25,80,102,76,0,64,1,192,0,0,0,0},
{4,64,4,64,63,248,4,64,127,252,1,0,31,240,17,16,31,240,17,16,31,240,8,32,16,16,32,8,0,0,0,0}}; //瀛楁ā琛'绾⑩樷欑豢钬樷橀粍钬
void main()
{
register uchar i,j;
SCON=0x00; //涓插彛宸ヤ綔妯″纺0锛氱Щ浣嶅瘎瀛桦櫒鏂瑰纺
TMOD=0x01; //瀹氭椂鍣═0宸ヤ綔鏂瑰纺1锛16浣嶆柟寮
P1=0x3f; //P1绔鍙e埯鍊硷细鍏佽告帴鏀躲侀挛瀛樸佹樉绀
TR0=1; //钖锷ㄥ畾镞跺櫒T0
ET0=1; //鍏佽稿畾镞跺櫒T0涓鏂
EA=1; //寮钖镐讳腑鏂锛
while(1)
{
delay(2000);
for(j=0;j<3;j++)
{
for(i=0;i<32;i++)
{
display[i]=~BMP[j][i];
if (i%2) delay(100);
}
delay(10000);
}
}
}
void delay(uint x)
{
register uchar i,j;
for (i=x;i>0;i--)
for (j=120;j>0;j--);
}
void leddisplay(void) interrupt 1 using 1
{
register uchar i, j=BLKN;
TH0 =(65536-100)/256; //琛¢儜瀵熻惧畾鏄剧ず灞忓埛鏂扮巼姣忕60甯
TL0 =(65536-100)%256;
i = P1; //璇诲彇褰揿墠鏄剧ず镄勮屽彿
i = ++i & 0x0f; //琛屽彿锷1锛屽睆钄介珮4浣
while(j)
{
j--;
SBUF = display[i*BLKN + j]; //阃佹樉绀烘暟鎹
while (!TI);
TI = 0;
} //瀹屾垚涓琛屾暟鎹镄勫彂阃
G = 1; //娑堥殣锛埚叧闂鏄剧ず锛
P1 &= 0xf0; //琛屽彿绔鍙f竻鈼
RCLK = 1; //鏄剧ず鏁版嵁镓揿叆杈揿嚭阌佸瓨鍣
P1 |= i; //鍐椤叆琛屽彿
RCLK = 0; //阌佸瓨鏄剧ず鏁版嵁
G = 0; //镓揿紑鏄剧ず
}
2. 交通灯 c语言 单片机。中断函数问题
参考《51单片机C语言创新教程》温子祺等着。
源码转自:《51单片机C语言创新教程》。
/*实验名称:交通灯实验
*描述:交通灯实验要求红灯亮15秒,绿灯亮10秒,黄灯亮5秒,
当红灯切换为绿灯或者绿灯切换为红灯,
要实现灯闪烁。红灯、绿灯、黄灯的点亮持续时间可以通过串口来修改,
并在下一个循环中更新数值。
*作者:温子祺
*修改日期:2010/5/4
*说明:代码注释与讲解详见《51单片机C语言创新教程》温子祺等着,北京航空航天大学出版社
*/
#include"stc.h"
typedefunsignedcharUINT8;
typedefunsignedint UINT16;
typedefunsignedlongUINT32;
typedefcharINT8;
typedefintINT16;
typedeflongINT32;
#defineTIMER0_INITIAL_VALUE5000
#defineHIGH1
#defineLOW0
#defineON1
#defineOFF0
#defineSEG_PORTP0
#defineLS164_DATA(x){if((x))P0_4=1;elseP0_4=0;}
#defineLS164_CLK(x){if((x))P0_5=1;elseP0_5=0;}
#defineNORTH_R_LIGHT(x){if((x))P2_0=0;elseP2_0=1;}
#defineNORTH_Y_LIGHT(x){if((x))P2_1=0;elseP2_1=1;}
#defineNORTH_G_LIGHT(x){if((x))P2_2=0;elseP2_2=1;}
#defineSOUTH_R_LIGHT(x){if((x))P2_3=0;elseP2_3=1;}
#defineSOUTH_Y_LIGHT(x){if((x))P2_4=0;elseP2_4=1;}
#defineSOUTH_G_LIGHT(x){if((x))P2_5=0;elseP2_5=1;}
#defineTRAFFIC_STATUS_10
#defineTRAFFIC_STATUS_21
#defineTRAFFIC_STATUS_32
#defineUART_MARKER0xEE
UINT8Timer0IRQEvent=0;
UINT8Time1SecEvent=0;
UINT8Time500MsEvent=0;
UINT8TimeCount=0;
UINT8SegCurPosition=0;
UINT8LightOrgCount[4]={15,5,15,5};
UINT8LightCurCount[4]={15,5,15,5};
UINT8TrafficLightStatus=0;
codeUINT8SegCode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
UINT8SegBuf[4]={0};
codeUINT8SegPosition[4]={0x07,0x0b,0x0d,0x0e};
typedefstruct_LIGHT_VAL
{
UINT8Head;
UINT8val[4];
}LIGHT_VAL;
typedefunion_LIGHT_VAL_EX
{
LIGHT_VALlv;
UINT8p[5];
}LIGHT_VAL_EX;
voidLS164Send(UINT8byte)
{
UINT8j;
for(j=0;j<=7;j++)
{
if(byte&(1<<(7-j)))
{
LS164_DATA(HIGH);
}
else
{
LS164_DATA(LOW);
}
LS164_CLK(LOW);
LS164_CLK(HIGH);
}
}
voidRefreshDisplayBuf(UINT8s1) //刷新显示缓存
{
SegBuf[0]=s1%10;
SegBuf[1]=s1/10;
SegBuf[2]=s1%10;
SegBuf[3]=s1/10;
}
voidSegDisplay(void)
{
UINT8t;
t=SegCode[SegBuf[SegCurPosition]];
SEG_PORT|=0x0f;
LS164Send(t);
SEG_PORT=(SEG_PORT|0x0f)&SegPosition[SegCurPosition];
if(++SegCurPosition>=4)
{
SegCurPosition=0;
}
}
voidTimerInit(void)
{
TH1=0;
TL1=0;
TH0=(65536-TIMER0_INITIAL_VALUE)/256;
TL0=(65536-TIMER0_INITIAL_VALUE)%256;//定时1MS
TMOD=0x51; /*01010001T1计数,T0定时*/
}
voidTimer0Start(void)
{
TR0=1; //启动计时器1
ET0=1;
}
voidTimer0Stop(void)
{
TR0=0; //启动计时器1
ET0=0;
}
voidPortInit(void)
{
P0=P1=P2=P3=0xFF;
}
voidUartInit(void)
{
SCON=0x40;
T2CON=0x34;
RCAP2L=0xD9;
RCAP2H=0xFF;
REN=1;
ES=1;
}
voidUartSendByte(UINT8byte)
{
SBUF=byte;
while(TI==0);
TI=0;
}
voidUartPrintfString(INT8*str)
{
while(str&&*str)
{
UartSendByte(*str++);
}
}
voidmain(void)
{
UINT8i=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;
}
elseif(LightCurCount[1])
{
TrafficLightStatus=1;
}
elseif(LightCurCount[2])
{
TrafficLightStatus=2;
}
elseif(LightCurCount[3])
{
TrafficLightStatus=3;
}
else
{
for(i=0;i<4;i++)
{
LightCurCount[i]=LightOrgCount[i];
}
TrafficLightStatus=0;
}
switch(TrafficLightStatus)
{
case0:
{
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;
case1:
{
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;
case2:
{
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;
case3:
{
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();
}
}
}
voidUartIRQ(void)interrupt4
{
staticUINT8cnt=0;
staticLIGHT_VAL_EXLightValEx;
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("设置交通灯完成 ");
}
}
else
{
cnt=0;
}
}
}
voidTimer0IRQ(void)interrupt1
{
ET0 =0;
TH0=(65536-TIMER0_INITIAL_VALUE)/256;
TL0=(65536-TIMER0_INITIAL_VALUE)%256;//定时1MS
Timer0IRQEvent=1;
ET0 =1;
}
=====================================================================
坐等拿分!
3. 单片机模拟交通灯C语言例子,看不懂,求解释
问题1:Flash_count每加1黄灯的引脚状态取反一次,引脚高低电平取反两次是闪一下。(原来是灭,取反,亮了,再取反,灭了,这才完成了一次闪烁。)因此Flash_count每加2才是闪烁一次。
问题2:1、return有函数返回数值作用,在函数末尾添加return (数字)可以使函数在被调用的地方返回一个值。例:uchar hanshu(){return 99;} void main(){num=hanshu();}则num值为1.
2、return有完全结束循环的作用,在循环中插入return可以彻底结束循环。
例:while(1){if(i==0)return; (后文省略)}如果i==1,则一直死循环,当i==0时跳出循环。
3、return可以结束函数。
例:void hanshu(){ return; while(1); }这个子函数不会陷入死循环,while(1)根本执行不到。
您的函数中到达return后其实子函数Light()也结束了,其实跳出了该函数,返回到main中了,
只不过由于main中的while的作用再次重头进入了而已。
4、return在switch语句中还有终止查找的作用。这个您网络switch就可以了
4. 单片机交通灯c语言
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitRED_A=P3^0;//东西向指示灯
sbitYELLOW_A=P3^1;
sbitGREEN_A=P3^2;
sbitRED_B=P3^3;//南北向指示灯
sbitYELLOW_B=P3^4;
sbitGREEN_B=P3^5;
sbitKEY1=P1^0;
sbitKEY2=P1^1;
sbitKEY3=P1^2;
//延时倍数,闪烁次数,操作类型变量
ucharFlash_Count=0,Operation_Type=1,LEDsng,LEDsns,LEDewg,LEDews,discnt;
uintTime_Count=0,time;
ucharledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
voiddisplaysn()
{
LEDsng=((time-Time_Count)/20)%10;
LEDsns=((time-Time_Count)/20)/10;
LEDewg=0x10;
LEDews=0x10;
}
voiddisplayew()
{
LEDewg=((time-Time_Count)/20)%10;
LEDews=((time-Time_Count)/20)/10;
LEDsng=0x10;
LEDsns=0x10;
}
//定时器0中断函数
voidT0_INT()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
switch(Operation_Type)
{
case1://东西向绿灯与南北向红灯亮
if((Time_Count%20)==0)displayew();
RED_A=0;YELLOW_A=0;GREEN_A=1;
RED_B=1;YELLOW_B=0;GREEN_B=0;
if(++Time_Count!=time)return;
Time_Count=0;
Operation_Type=2;
break;
case2://东西向黄灯开始闪烁,绿灯关闭
LEDewg=0x0;
LEDews=0x0;
if(++Time_Count!=8)return;
Time_Count=0;
YELLOW_A=~YELLOW_A;GREEN_A=0;
if(++Flash_Count!=10)return;//闪烁
Flash_Count=0;
Operation_Type=3;
break;
case3://东西向红灯与南北向绿灯亮
if((Time_Count%20)==0)displaysn();
RED_A=1;YELLOW_A=0;GREEN_A=0;
RED_B=0;YELLOW_B=0;GREEN_B=1;
if(++Time_Count!=time)return;
Time_Count=0;
Operation_Type=4;
break;
case4://南北向黄灯开始闪烁,绿灯关闭
LEDsng=0x0;
LEDsns=0x0;
if(++Time_Count!=8)return;
Time_Count=0;
YELLOW_B=~YELLOW_B;GREEN_A=0;
if(++Flash_Count!=10)return;//闪烁
Flash_Count=0;
Operation_Type=1;
break;
}
}
voidt1_isr()interrupt3
{
TR1=0;
TH1=(65536-3000)/256;
TL1=(65536-3000)%256;
TR1=1;
switch(discnt)
{
case0:
P2=0x02;
P0=ledtab[LEDewg];
break;
case1:
P2=0x01;
P0=ledtab[LEDews];
break;
case2:
P2=0x08;
P0=ledtab[LEDsng];
break;
case3:
P2=0x04;
P0=ledtab[LEDsns];
break;
default:discnt=0;break;
}
discnt++;
discnt&=0x03;
}
voiddelay()
{
uinti;
for(i=0;i<1000;i++);
}
//主程序
voidmain()
{
TMOD=0x11;//T0方式1
EA=1;
ET0=1;
TR0=1;
TH1=(65536-3000)/256;
TL1=(65536-3000)%256;
TR1=1;
ET1=1;
time=600;
Time_Count=600;
Time_Count=0;
Operation_Type=1;
while(1)
{
if(KEY1==0) //按一下加1S
{
delay();
if(KEY1==0)
{
while(KEY1==0);
TR0=0;
time+=20;
LEDsng=(time/20)%10;
LEDsns=(time/20)/10;
LEDewg=0x10;
LEDews=0x10;
}
}
if(KEY2==0) //按一下减1S
{
delay();
if(KEY2==0)
{
while(KEY2==0);
TR0=0;
time-=20;
if(time==0)time=20;
LEDewg=(time/20)%10;
LEDews=(time/20)/10;
LEDsng=0x10;
LEDsns=0x10;
}
}
if(KEY3==0) //启动
{
delay();
if(KEY3==0)
{
while(KEY2==0);
TR0=1;
Time_Count=0;
}
}
}
}