大家好,今天来为大家分享单片机交通灯程序的一些知识点,和c51单片机c语言交通灯的程序的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!
c51单片机控制交通灯要求用汇编语言
//51单片机控制交通灯要求用汇编语言,仿真实例,可以参考一下
SNFEQU00H;南北通行标志位
EWFEQU01H;东西通行标志位
URFEQU02H;紧急事件标志位
ORG0000H
LJMPMAIN;上电转主程序
ORG000BH;定时中断入口
LJMPDSZD
ORG0003H;紧急中断入口
LJMPURZD
ORG0030H
MAIN:LCALLINIT;调用初始化子程序
LOOP:LCALLDIS;循环执行显示子程序
AJMPLOOP
;*********初始化程序
INIT:SETBSNF
SETBEWF
SETBURF
MOVR2,#20;定时器中断20次为1s
MOVTMOD,#01H;初始化定时器
MOVTL0,#0B0H
MOVTH0,#3CH
SETBEA;开定时中断与紧急中断
SETBET0
SETBTR0
SETBEX0
SETBIT0;设置中断程控方式
MOVDPTR,#TAB;数值首地址放入DPTR中
MOV40H,#40;东南西北通行时间设置
MOV41H,#40
MOV30H,#40;通行时间初始化
MOV31H,#60
MOVP0,#4CH;初始化时南北通行并把交通灯状态分别放在32H和33H中
MOV32H,#4CH
MOVP2,#15H
MOV33H,#15H
RET
;*********显示子程序
DIS:MOVP3,#0DFH;选中南北方向的十位数码管
MOVA,30H;把显示数据送人数码管显示
MOVB,#10
DIVAB
MOVCA,@A+DPTR
MOVP1,A;
LCALLD1MS
MOVP3,#0EFH;选中南北方向的个位数码管
MOVA,B;送入数码管显示
MOVCA,@A+DPTR
MOVP1,A
LCALLD1MS
MOVP3,#7FH;选中第东西方向的十位数码管
MOVA,31H;送入数码管显示
MOVB,#10
DIVAB
MOVCA,@A+DPTR
MOVP1,A
LCALLD1MS
MOVP3,#0BFH;选中第东西方向的个位数码管
MOVA,B
MOVCA,@A+DPTR
MOVP1,A
LCALLD1MS
SETBP3.0
SETBP3.1
JNBP3.0,DIS_S;查询是否第一个按键按下
JNBP3.1,DIS_E;查询是否第二个按键按下
AJMPDIS_R;没有键按下则返回
DIS_S:LCALLD5MS;按键去抖
JNBP3.0,DIS_SN
AJMPDIS_R
DIS_SN:MOV40H,#50;对通行时间从新分配,南北通行时间加长
MOV41H,#30
AJMPDIS_R
DIS_E:LCALLD5MS;按键去抖
JNBP3.1,DIS_EW
AJMPDIS_R
DIS_EW:MOV40H,#30;东西通行时间加长
MOV41H,#50
DIS_R:RET
;*********定时中断处理程序
DS_C:LJMPDS_R;接力跳转
DSZD:PUSHACC;保护现场
PUSHPSW
CLRTR0;关定时器及中断标志位并重新赋值
CLRTF0
MOVTL0,#0B0H
MOVTH0,#3CH
DJNZR2,DS_C;判断1m时间是否到达
MOVR2,#20;到达重新赋值
DEC30H;南北方向通行时间减一
MOVA,30H;把减一后的时间送入显示存储单元
;*********南北通行到达最后4秒时黄灯闪烁
DS_10:CJNEA,#4,DS_11;如果通行时间剩余4秒
JNBSNF,DS_11;判断是否是南北通行
MOVP0,#8AH
MOV32H,#8AH;把交通灯状态存入存储单元(后面类似)
DS_11:CJNEA,#3,DS_12;不是剩余3秒,返回
JNBSNF,DS_12;不是南北通行时间,返回
MOVP0,#88H
MOV32H,#88H
DS_12:CJNEA,#2,DS_13
JNBSNF,DS_13
MOVP0,#8AH
MOV32H,#8AH
DS_13:CJNEA,#1,DS_14
JNBSNF,DS_14
MOVP0,#88H
MOV32H,#88H
;*********
DS_14:JNZDS_NE;通行时间没有结束转向改变东西方向的数码管
CPLSNF;如果通行时间结束则对标志位取反
JNBSNF,DS_1;判断是否南北通行
MOV30H,40H;是,点亮相应的交通灯
MOVP0,#4CH
MOV32H,#4CH;存储交通灯状态
MOVP2,#15H
MOV33H,#15H;存储交通灯状态
DS_NE:DEC31H;东西方向通行时间减一
MOVA,31H;把通行剩余时间送入显示存储单元
;*********东西方向通行时间剩余4秒钟黄灯闪烁(程序注释与南北方向类似略)
DS_20:CJNEA,#4,DS_21
JBEWF,DS_21
MOVP0,#51H
MOV32H,#51H
DS_21:CJNEA,#3,DS_22
JBEWF,DS_22
MOVP0,#41H
MOV32H,#41H
DS_22:CJNEA,#2,DS_23
JBEWF,DS_23
MOVP0,#51H
MOV32H,#51H
DS_23:CJNEA,#1,DS_24
JBEWF,DS_24
MOVP0,#41H
MOV32H,#41H
;*********
DS_24:JNZDS_R;东西方向时间没有结束,返回
CPLEWF;对通行状态取反
JNBEWF,DS_2;东西方向通行时间到来,跳转
MOV31H,#80;东西方向通行结束,重新显示时间
MOVP0,#89H;点亮相应的交通灯
MOV32H,#89H
MOVP2,#29H
MOV33H,#29H
AJMPDS_R
DS_1:MOV30H,#80;南北通行时间结束,重新对显示存储单元赋值
MOVP0,#89H;执行转弯状态1
MOV32H,#89H
MOVP2,#26H
MOV33H,#26H
AJMPDS_NE
DS_2:MOV31H,41H;东西方向开始通行,赋值予显示存储单元
MOVP0,#61H;点亮相应的交通灯
MOV32H,#61H
MOVP2,#15H
MOV33H,#15H
DS_R:SETBTR0
POPPSW;恢复现场
POPACC
RETI
;*********紧急中断处理程序
URZD:PUSHACC;保护现场
PUSHPSW
CLRIE0;清除中断标志位
CLRTR0;关定时器
CPLURF;紧急事件标志位
JBURF,UR_CON;紧急结束;跳转
MOVP0,#49H;各路口灯全显示红灯亮
MOVP2,#15H
AJMPUR_R
UR_CON:SETBTR0;恢复正常交通
MOVA,32H
MOVP0,A
MOVA,33H
MOVP2,A
UR_R:POPPSW;恢复现场
POPACC
RETI
;*********查表指令0,1,2,3,4,5,6,7,8,9
TAB:DB3FH,06H,5BH,4FH,66H,6DH
DB7DH,07H,7FH,6FH
;*********延时5ms与1ms
D5MS:MOVR7,#5
D1MS:MOVR7,#10
MOVR6,#50
L1:DJNZR6,$
DJNZR7,L1
RET
END
用51单片机编写城市道路交通灯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=100;
Time_Count=100;
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;
}
}
}
}
c51单片机c语言交通灯的程序
Proteus仿真原理图:
程序如下:
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
uchardatabuf[4];
uchardatasec_dx=20;//东西数默认
uchardatasec_nb=30;//南北默认值
uchardataset_timedx=20;
uchardataset_timenb=30;
intn;
uchardatab;//定时器中断次数
sbitk1=P1^6;//定义5组开关
sbitk2=P1^7;
sbitk3=P2^7;
sbitk4=P3^0;
sbitk5=P3^1;
sbitYellow_nb=P2^5;//南北黄灯标志
sbitYellow_dx=P2^2;//东西黄灯标志
sbitGreen_nb=P2^4;
sbitGreen_dx=P2^1;
sbitBuzz=P3^7;
bitBuzzer_Indicate;
bittime=0;//灯状态循环标志
bitset=1;//调时方向切换键标志
ucharcodetable[11]={//共阴极字型码
0x3f,//--0
0x06,//--1
0x5b,//--2
0x4f,//--3
0x66,//--4
0x6d,//--5
0x7d,//--6
0x07,//--7
0x7f,//--8
0x6f,//--9
0x00//--NULL
};
//函数的声明部分
voiddelay(intms);//延时子程序
voidkey();//按键扫描子程序
voidkey_to1();//键处理子程序
voidkey_to2();
voidkey_to3();
voiddisplay();//显示子程序
voidlogo();//开机LOGO
voidBuzzer();
//主程序
voidmain()
{
TMOD=0X01;
TH0=0XD8;
TL0=0XF0;
EA=1;
ET0=1;
TR0=1;
EX0=1;
EX1=1;
logo();
P2=0Xc3;//开始默认状态,东西绿灯,南北黄灯
sec_nb=sec_dx+5;
while(1)
{
key();//调用按键扫描程序
display();//调用显示程序
Buzzer();
}
}
//函数的定义部分
voidkey()//按键扫描子程序
{
if(k1!=1)
{
delay(10);
if(k1!=1)
{
while(k1!=1)
{
key_to1();
for(n=0;n<40;n++)
{display();}
}
}
}
if(k2!=1)
{
delay(10);
if(k2!=1)
{
while(k2!=1)
{
key_to2();
for(n=0;n<40;n++)
{display();}
}
}
}
if(k3!=1)
{
TR0=1;//启动定时器
Buzzer_Indicate=0;
sec_nb=set_timenb;//从中断回复,仍显示设置过的数值
sec_dx=set_timedx;
if(time==0)
{P2=0X99;sec_nb=sec_dx+5;}
else{P2=0xC3;sec_dx=sec_nb+5;}
}
if(k4!=1)
{
delay(5);
if(k4!=1)
{
while(k4!=1);
set=!set;
}
}
if(k5!=1)
{
delay(5);
if(k5!=1)
{
while(k5!=1)
key_to3();
}
}
}
voiddisplay()//显示子程序
{
buf[1]=sec_dx/10;//第1位东西秒十位
buf[2]=sec_dx%10;//第2位东西秒个位
buf[3]=sec_nb/10;//第3位南北秒十位
buf[0]=sec_nb%10;//第4位南北秒个位
P1=0xff;//初始灯为灭的
P0=0x00;
P1=0xfe;//片选LCD1
P0=table[buf[1]];
delay(1);
P1=0xff;
P0=0x00;
P1=0xfd;//片选LCD2
P0=table[buf[2]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xfb;//片选LCD3
P0=table[buf[3]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xf7;
P0=table[buf[0]];//片选LCD4
delay(1);
}
voidtime0(void)interrupt1using1//定时中断子程序
{
b++;
if(b==19)//定时器中断次数
{b=0;
sec_dx--;
sec_nb--;
if(sec_nb<=5&&time==0)//东西黄灯闪
{Green_dx=0;Yellow_dx=!Yellow_dx;}
if(sec_dx<=5&&time==1)//南北黄灯闪
{Green_nb=0;Yellow_nb=!Yellow_nb;}
if(sec_dx==0&&sec_nb==5)
sec_dx=5;
if(sec_nb==0&&sec_dx==5)
sec_nb=5;
if(time==0&&sec_nb==0)
{P2=0x99;time=!time;sec_nb=set_timenb;sec_dx=set_timenb+5;}
if(time==1&&sec_dx==0)
{P2=0Xc3;time=!time;sec_dx=set_timedx;sec_nb=set_timedx+5;}
}
}
voidkey_to1()//键盘处理子程序之+
{
TR0=0;//关定时器
if(set==0)
set_timenb++;//南北加1S
else
set_timedx++;//东西加1S
if(set_timenb==100)
set_timenb=1;
if(set_timedx==100)
set_timedx=1;//加到100置1
sec_nb=set_timenb;//设置的数值赋给东西南北
sec_dx=set_timedx;
}
voidkey_to2()//键盘处理子程序之-
{
TR0=0;//关定时器
if(set==0)
set_timenb--;//南北减1S
else
set_timedx--;//东西减1S
if(set_timenb==0)
set_timenb=99;
if(set_timedx==0)
set_timedx=99;//减到1重置99
sec_nb=set_timenb;//设置的数值赋给东西南北
sec_dx=set_timedx;
}
voidkey_to3()//键盘处理之紧急车通行
{
TR0=0;
P2=0Xc9;
sec_dx=00;
sec_nb=00;
Buzzer_Indicate=1;
}
voidint0(void)interrupt0using1//只允许东西通行
{
TR0=0;
P2=0Xc3;
Buzzer_Indicate=0;
sec_dx=00;
sec_nb=00;
}
voidint1(void)interrupt2using1//只允许南北通行
{
TR0=0;
P2=0X99;
Buzzer_Indicate=0;
sec_nb=00;
sec_dx=00;
}
voidlogo()//开机的Logo"----"
{for(n=0;n<50;n++)
{
P0=0x40;
P1=0xfe;
delay(1);
P1=0xfd;
delay(1);
P1=0Xfb;
delay(1);
P1=0Xf7;
delay(1);
P1=0xff;
}
}
voidBuzzer()
{
if(Buzzer_Indicate==1)
Buzz=!Buzz;
elseBuzz=0;
}
voiddelay(intms)//延时子程序
{
uintj,k;
for(j=0;j<ms;j++)
for(k=0;k<124;k++);
}
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!