c51单片机c语言交通灯的程序

c51单片机c语言交通灯的程序,第1张

Proteus仿真原理图:圆颤亮

程序如下:

#include <reg51.h>

#define uchar unsigned char

#define uint  unsigned int

uchar data buf[4]

uchar data sec_dx=20//东西数默认

uchar data sec_nb=30//南北默认值

uchar data set_timedx=20

uchar data set_timenb=30

int n

uchar data b//定时器中断次数

sbit  k1=P1^6//定义5组开关

sbit  k2=P1^7

sbit  k3=P2^7

sbit  k4=P3^0

sbit  k5=P3^1

sbit Yellow_nb=P2^5       //南北黄灯标志

sbit Yellow_dx=P2^2       //东西黄灯标志

sbit Green_nb=P2^4

sbit Green_dx=P2^1

sbit Buzz=P3^7

bit Buzzer_Indicate

bit time=0//灯状态循环标志

bit   set=1//调时方向切换键标志

uchar code table[11]={       //共阴极字型码

0x3f,  //--0

0x06,  //--1

0x5b,  //--2

0x4f,  //--3

0x66,  //--4

0x6d,  //--5

0x7d,  //--6

0x07,  //--7

0x7f,  //--8

0x6f,  //--9

0x00   //--NULL

}

//函数的声明部分

void delay(int ms)//延时子程序

void key()//按键扫描子程序

void key_to1()//键处理子程序

void key_to2()

void key_to3()

void display()//显示子程序

void logo()   //开机LOGO

void Buzzer()

//主程序

void main()

{

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()

}   

}

//函数的定义部分

void key()    //按键扫描子程序

{

if(k1!=1)

{

delay(10)

if(k1!=1)

{

while(k1!=1)

{

key_to1()

for(n=0n<40n++)

{ display()}

}

}

}

if(k2!=1)

{

delay(10)

if(k2!=1)

{

while(k2!=1)

{

key_to2()

for(n=0n<40n++)

{ display()}

}

}

}

if(k3!=1)

{

TR0=1   //启动定时器

Buzzer_Indicate=0

sec_nb=set_timenb  //从中断回复,仍显示设置过的数值

sec_dx=set_timedx

if(time==0)

{ P2=0X99sec_nb=sec_dx+5}

else { P2=0xC3sec_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()

}

}

}

void display() //显示子程序

{

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)

}

void time0(void) interrupt 1 using 1  //定时中断子程序

{

b++

if(b==19)                        // 定时器中断次数

{      b=0

sec_dx--

sec_nb--

if(sec_nb<=5&&time==0)  //东西黄灯闪

{  Green_dx=0Yellow_dx=!Yellow_dx}               

if(sec_dx<=5&&time==1)  //南北黄灯闪

{  Green_nb=0Yellow_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=0x99time=!timesec_nb=set_timenbsec_dx=set_timenb+5}

if(time==1&&sec_dx==0)

{P2=0Xc3time=!timesec_dx=set_timedxsec_nb=set_timedx+5}

}

}

void key_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

}

void key_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

}

void key_to3()   //键盘处理之紧急车通行

{

TR0=0

P2=0Xc9

sec_dx=00

sec_nb=00

Buzzer_Indicate=1

}

void int0(void) interrupt 0 using 1  //只允许东西通行

{

TR0=0

P2=0Xc3

Buzzer_Indicate=0

sec_dx=00

sec_nb=00

}

void int1(void) interrupt 2 using 1       //只允许南北通行

{

TR0=0

P2=0X99

Buzzer_Indicate=0

sec_nb=00

sec_dx=00

}

void logo()//开机的Logo  "- - - -"

{ for(n=0n<50n++)

{

P0=0x40

P1=0xfe

delay(1)

P1=0xfd

delay(1)

P1=0Xfb

delay(1)

P1=0Xf7

delay(1)

P1 = 0xff

}

}

void Buzzer()

{

if(Buzzer_Indicate==1)

Buzz=!Buzz

else Buzz=0

}

void delay(int ms)            //延时子程序

{

uint j,k

for(j=0j<msj++)

for(k=0k<124k++)

}

-----------------------------------

SNF   EQU  00H             南北通行标志位

EWF   EQU  01H             东西通行标志位

URF   EQU  02H             紧急事件标志位

ORG   0000H

LJMP  MAIN                 上电转主程序

ORG   000BH                定时中断入口

LJMP  DSZD                   

ORG   0003H                紧急中断入口

LJMP  URZD

ORG   0030H   

MAIN: LCALL INIT           调用初始化子程序

LOOP: LCALL DIS            循环执行显示子程序

      AJMP  LOOP

///////////初始化程序

INIT: SETB   SNF             

      SETB   EWF           

      SETB   URF           

      MOV   R2,#20         定时器中断20次为1s

      MOV   TMOD,#01H      初始化定时器

      MOV   TL0,#0B0H

      MOV   TH0,#3CH

      SETB  EA             开定时中断与紧急中断

      SETB  ET0

      SETB  TR0

      SETB  EX0

      SETB  IT0            设置中断程控方式

      MOV   DPTR,#TAB      数值首地址放入DPTR中

      MOV   40H,#40        东南西北通行时间设置

      MOV   41H,#40

      MOV   30H,#40        通行时间初始化

      MOV   31H,#60

      MOV   P0,#4CH        初始化时南北通行并把交通灯状态分别放在32H和33H中

      MOV   32H,#4CH

      MOV   P2,#15H

      MOV   33H,#15H

      RET

////////////显示子程序

DIS:  MOV   P3,#0DFH       选中南北方向的十位数码管

      MOV   A,30H          把显示数据送人数码管显示

      MOV   B,#10

      DIV   AB

      MOVC  A,@A+DPTR

      MOV   P1,A           

      LCALL D1MS

      MOV   P3,#0EFH       选中南北方向的个位数码管

      MOV   A,B            送入数码管显示

     腊戚 MOVC  A,@A+DPTR     

      MOV   P1,A

      LCALL D1MS

    MOV   P3,#7FH        选中第东西方向的十位数码管

      MOV   A,31H          送入数码管显示

      MOV   B,#10

      DIV   AB

      MOVC  A,@A+DPTR

      MOV   P1,A

      LCALL D1MS

      MOV   P3,#0BFH       选中第东西方向的个位数码管

      MOV   A,B

      MOVC  A,@A+DPTR

      MOV   P1,A

      LCALL D1MS

      SETB  P3.0

      SETB  P3.1

      JNB   P3.0,DIS_S     查询是否第一个按键按下

      JNB   P3.1,DIS_E     查询是否第二个按键按下

      AJMP  DIS_R          没有键按下则返回

DIS_S:LCALL D5MS           按键去型做抖

      JNB   P3.0,DIS_SN

      AJMP  DIS_R   

DIS_SN:MOV   40H,#50       对通行时间从新分配,南北通行时间加长

       MOV   41H,#30

       AJMP  DIS_R

DIS_E:LCALL D5MS           按键去抖

      JNB   P3.1,DIS_EW 

      AJMP  DIS_R

DIS_EW:MOV   40H,#30       东西通行时间加长

       MOV   41H,#50

DIS_R:RET                 

///////定时中断处理程序

DS_C: LJMP  DS_R           接力跳转

DSZD: PUSH  ACC            保护现场卜局衡

      PUSH  PSW

      CLR   TR0            关定时器及中断标志位并重新赋值

      CLR   TF0

      MOV   TL0,#0B0H

      MOV   TH0,#3CH

      DJNZ  R2,DS_C        判断1m时间是否到达

      MOV   R2,#20         到达重新赋值

      DEC   30H            南北方向通行时间减一

      MOV   A,30H          把减一后的时间送入显示存储单元

南北通行到达最后4秒时黄灯闪烁

DS_10:CJNE  A,#4,DS_11     如果通行时间剩余4秒

      JNB   SNF,DS_11      判断是否是南北通行

      MOV   P0,#8AH       

      MOV   32H, #8AH      把交通灯状态存入存储单元(后面类似)

DS_11:CJNE  A,#3,DS_12     不是剩余3秒,返回

      JNB   SNF,DS_12      不是南北通行时间,返回

      MOV   P0,#88H

      MOV   32H, #88H

DS_12:CJNE  A,#2,DS_13

      JNB   SNF,DS_13

      MOV   P0,#8AH

      MOV   32H, #8AH 

DS_13:CJNE  A,#1,DS_14

      JNB   SNF,DS_14

      MOV   P0,#88H

      MOV   32H, #88H

------------------------

DS_14:JNZ   DS_NE          通行时间没有结束转向改变东西方向的数码管

      CPL   SNF            如果通行时间结束则对标志位取反

      JNB   SNF,DS_1       判断是否南北通行

      MOV   30H,40H        是,点亮相应的交通灯

      MOV   P0,#4CH

      MOV   32H,#4CH       存储交通灯状态

      MOV   P2,#15H

      MOV   33H, #15H      存储交通灯状态

DS_NE:DEC   31H            东西方向通行时间减一

      MOV   A,31H          把通行剩余时间送入显示存储单元

东西方向通行时间剩余4秒钟黄灯闪烁(程序注释与南北方向类似 略)

DS_20:CJNE  A,#4,DS_21   

      JB    EWF,DS_21

      MOV   P0,#51H

      MOV   32H, #51H

DS_21:CJNE  A,#3,DS_22

      JB    EWF,DS_22

      MOV   P0,#41H

      MOV   32H, #41H

DS_22:CJNE  A,#2,DS_23

      JB    EWF,DS_23

      MOV   P0,#51H

      MOV   32H, #51H

DS_23:CJNE  A,#1,DS_24

      JB    EWF,DS_24

      MOV   P0,#41H

      MOV   32H, #41H

-----------------------------

DS_24:JNZ   DS_R             东西方向时间没有结束,返回

      CPL   EWF              对通行状态取反

      JNB   EWF,DS_2         东西方向通行时间到来,跳转

      MOV   31H,#80          东西方向通行结束,重新显示时间

      MOV   P0,#89H          点亮相应的交通灯

      MOV   32H, #89H

      MOV   P2,#29H

      MOV   33H, #29H

      AJMP  DS_R     

DS_1: MOV   30H,#80          南北通行时间结束,重新对显示存储单元赋值     

      MOV   P0,#89H          执行转弯状态1

      MOV   32H, #89H

      MOV   P2,#26H

      MOV   33H, #26H

      AJMP  DS_NE           

DS_2: MOV   31H,41H         东西方向开始通行,赋值予显示存储单元

      MOV   P0,#61H         点亮相应的交通灯

      MOV   32H, #61H

      MOV   P2,#15H

      MOV   33H, #15H

DS_R: SETB  TR0 

      POP   PSW             恢复现场

      POP   ACC

      RETI

/////////////紧急中断处理程序

URZD: PUSH  ACC             保护现场

      PUSH  PSW

      CLR   IE0             清除中断标志位

      CLR   TR0             关定时器

      CPL   URF             紧急事件标志位

      JB    URF,UR_CON      紧急结束;跳转

      MOV   P0,#49H         各路口灯全显示红灯亮

      MOV   P2,#15H

      AJMP  UR_R

UR_CON:SETB  TR0            恢复正常交通

      MOV   A,32H

      MOV   P0,A

      MOV   A,33H

      MOV   P2,A

UR_R: POP   PSW             恢复现场

      POP   ACC

      RETI     

////////////查表指令0,1,2,3,4,5,6,7,8,9

TAB:  DB  3FH,  06H,  5BH,  4FH,  66H,  6DH

      DB  7DH,  07H,  7FH,  6FH

//////////延时5ms与1ms

D5MS:  MOV    R7,#5

D1MS:  MOV    R7,#10

       MOV    R6,#50 

L1:    DJNZ   R6,$

       DJNZ   R7,L1

       RET

       END

ORG 1000H

L:JNB P3.0,LP3

JNB P3.1,LP2 判断p3.1,p3.0口

如果P3.0为1的话,正州瞎差常运行交通灯

如果P3.1为1的话,正常运行交通灯

如果P3.1为0的话,依次点亮灯

如果P3.0为0的话,停止交通灯,只有黄灯闪烁

正常运行交通灯

LP1:

MOV P1,#61H

CLR P3.2

CLR P3.3

CLR P3.4

SETB P3.5 1,3 路口红灯亮,2,4 路口绿灯亮

LCALL DELAY1

MOV B,#04H 设置循环次数为4次

M:MOV P1,#51H

CLR P3.5

SETB P3.4 1,3路口红灯亮,2,4路口黄灯亮

LCALL DELAY2

MOV P1,#41H

CLR P3.41,3路口红灯亮,2,4路册皮口黄灯灭

LCALL DELAY2

DJNZ B,M

MOV P1,#0CH

SETB P3.2

SETB P3.3 1,3路口绿灯亮,2,4路口红灯亮

LCALL DELAY1

MOV B,#04H

N:MOV P1,#8AH

CLR P3.21,3路口黄灯亮,2,4路口红灯亮

LCALL DELAY2

MOV P1,#08H 1,3路口黄灯灭,2,4路口红灯亮

LCALL DELAY2

DJNZ B,N

AJMP L

黄灯闪

LP3: CLR P1.7

CLR P3.2

CLR P3.3

CLR P3.5

MOV P1,#92H

SETB P3.4 黄灯亮,其他的灯灭

LCALL DELAY2

MOV P1,#00H

CLR P3.4 所有的黄灯灭

LCALL DELAY2

AJMP L

循环亮

LP2: CLR P3.2

CLR P3.3

CLR P3.4

CLR P3.5

MOV A,#01H赋初值

MOV R0,#08 循环变量,循环7次,控制7个灯

LOOP:MOV P1,A 点亮第一个灯

LCALL DELAY2 延迟

RL A A的值加1,循环左移

DJNZ R0,LOOP RO的值减1不等于1则执行LOOP标号

SETB P3.2 P3.2灯亮

LCALL DELAY2 延迟

CLR P3.2 P3.2灯灭

SETB P3.3 下一个灯P3.3亮

LCALL DELAY2 延迟

CLRP3.3P3.3灯灭

SETB P3.4下一个灯P3.3亮

LCALL DELAY2 延迟

CLR P3.4 P3.4灯灭

SETB P3.5 P3.5灯亮

LCALL DELAY2 延迟

AJMP L

延神衡迟1

DELAY1 :

MOV R3,#200

DEL1: MOV R4,#250

DEL2: MOV R5,#50

DEL3: NOP 空 *** 作

DJNZ R5,DEL3

DJNZ R4,DEL2

DJNZ R3,DEL1 延长5秒

RET

延迟2

DELAY2 :

DEL4: MOV R3,#200

DEL5: MOV R4,#200

DEL6: NOP

DJNZ R4,DEL6

DJNZ R3,DEL5 延迟0.08秒

RET

END


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12355922.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存