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

}

采用51单片机作为系统的MCU,基本完成控制两组交通指示灯交替亮

每个街口有左拐、直行及行人三种指示灯。直行灯每个灯有红、黄、绿三种颜色。自行车与汽车共用左拐和直行灯。

首先东西向直行绿灯和行人灯亮1分钟,左转灯亮30秒,黄灯亮5秒(同时南北向红灯亮95秒),然后东西向红灯亮95秒钟(同时首先南北向直行绿灯和行人灯亮1分钟,左转灯亮30秒,黄灯亮5秒),然后东西向的绿灯亮,依次类推。

每次绿灯亮的时候,对应的行人灯亮。

60S/30S/5S/60S/30S/5S

东西道

绿和行人/左转/黄/红/红/红

南北道

红/红/红/绿和行人/左转/黄

行人灯亮的时候有声音提示盲人能通过。

突发交通事故的时候能够紧急全红灯。

在有重要人物通过的时候能手动改为绿灯。

ORG 0000H 主程序的入口地址

LJMP MAIN 跳转到主程序的开春键始处

ORG 0003H 外部中断0的中断程序入口地址

ORG 000BH 定时器0的中断程序入口地址

LJMP T0_INT 跳转到中断服务程序处

ORG 0013H 外部中断1的中断程序入口地址

MAIN : MOV SP,#50H

MOV IE,#8EH CPU开中断,允许T0中断,T1中断和外部中断1中断

MOV TMOD,#51H 设置T1为计数方式,T0为定时方式,且都工作于模式1

MOV TH1,#00H T1计数器清零

MOV TL1,#00H

SETB TR1 启动T1计时器

SETB EX1 允许INT1中断

SETB IT1 选择边沿触发方式

MOV DPTR ,#0003H

MOV A, #80H 给8255赋初值,8255工作于方式0

MOVX @DPTR, A

AGAIN: JB P3.1,N0 判断是否要设定东西方向红绿灯时间的初值,若P3.1为1 则跳转

MOV A,P1

JB P1.7,RED 判断P1.7是否为1,辩春若为1则设定红灯时间,否则设定绿灯时间

MOV R0,#00H R0清零

MOV R0,A 存入东西方向绿灯初始时间

MOV R3,A

LCALL DISP1

LCALL DELAY

AJMP AGAIN

RED: MOV A,P1

ANL A,#7FH P1.7置0

MOV R7,#00H R7清零

MOV R7,A 存入东西方向红灯初始时间

MOV R3,A

LCALL DISP1

LCALL DELAY

AJMP AGAIN

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

N0: SETB TR0 启动T0计时器

MOV 76H,R7 红灯时间存入76H

N00: MOV A,76H 东西方向禁止,南北方向通行

MOV R3,A

MOV DPTR,#0000H 置8255A口,东西方向红灯亮,南北方向绿灯亮

MOV A,#0DDH

MOVX @DPTR, A

N01: JB P2.0,B0

N02: SETB P3.0

CJNE R3,#00H,N01 比较R3中的值是否为0,不为0转到当前指令处执行

------黄灯闪烁5秒程序------

N1: SETB P3.0

MOV R3,#05H

MOV DPTR,#0000H 置8255A口,东西,南北方向黄灯亮

MOV A,#0D4H

MOVX @DPTR,A

N11: MOV R4,#00H

N12: CJNE R4,#7DH,$ 黄灯持续亮0.5秒

N13: MOV DPTR,#0000H 置8255A口,南北方向黄灯灭

MOV A,#0DDH

MOVX @DPTR,A

N14: MOV R4,#00H

CJNE R4,#7DH,$ 黄灯持续灭0.5秒

CJNE R3,#00H,N1 闪烁时间达5秒则退出

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

N2: MOV R7,#00H

MOV A,R0 东西扒灶巧通行,南北禁止

MOV R3,A

MOV DPTR,#0000H 置8255A口,东西方向绿灯亮,南北方向红灯亮

MOV A,#0EBH

MOVX @DPTR,A

N21: JB P2.0,T03

N22: CJNE R3,#00H,N21

------黄灯闪烁5秒程序------

N3: MOV R3,#05H

MOV DPTR,#0000H 置8255A口,东西,南北方向黄灯亮

MOV A,#0E2H

MOVX @DPTR,A

N31: MOV R4,#00H

CJNE R4,#7DH,$ 黄灯持续亮0.5秒

N32: MOV DPTR,#0000H 置8255A口,南北方向黄灯灭

MOV A,#0EBH

MOVX @DPTR,A

N33: MOV R4,#00H

CJNE R4,#7DH,$ 黄灯持续灭0.5秒

CJNE R3,#00H,N3 闪烁时间达5秒则退出

SJMP N00

------闯红灯报警程序------

B0: MOV R2,#03H 报警持续时间3秒

B01: MOV A,R3

JZ N1 若倒计时完毕,不再报警

CLR P3.0 报警

CJNE R2,#00H,B01 判断3秒是否结束

SJMP N02

------1秒延时子程序-------

N7: RETI

T0_INT:MOV TL0,#9AH 给定时器T0送定时10ms的初值

MOV TH0,#0F1H

INC R4

INC R5

CJNE R5,#0FAH,T01 判断延时是否够一秒,不够则调用显示子程序

MOV R5,#00H R5清零

DEC R3 倒计时初值减一

DEC R2 报警初值减一

T01: ACALL DISP 调用显示子程序

RETI 中断返回

------显示子程序------

DISP: JNB P2.4,T02

DISP1: MOV B,#0AH

MOV A,R3 R3中值二转十显示转换

DIV AB

MOV 79H,A

MOV 7AH,B

DIS: MOV A,79H 显示十位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0F7H

MOVX @DPTR,A

LCALL DELAY

DS2: MOV A,7AH 显示个位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0FBH

MOVX @DPTR,A

RET

------东西方向车流量检测程序------

T03: MOV A,R3

SUBB A,#00H 若绿灯倒计时完毕,不再检测车流量

JZ N3

JB P2.0,T03

INC R7

CJNE R7,#64H,E1

MOV R7,#00H 中断到100次则清零

E1: SJMP N22

------东西方向车流量显示程序------

T02: MOV B,#0AH

MOV A,R7 R7中值二转十显示转换

DIV AB

MOV 79H,A

MOV 7AH,B

DIS3: MOV A,79H 显示十位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0F7H

MOVX @DPTR,A

LCALL DELAY

DS4: MOV A,7AH 显示个位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0FBH

MOVX @DPTR,A

LJMP N7

------延时4MS子程序----------

DELAY: MOV R1,#0AH

LOOP: MOV R6,#64H

NOP

LOOP1: DJNZ R6,LOOP1

DJNZ R1,LOOP

RET

------字符表------

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

END

交通灯模拟实验程序

GEWEI EQU 21H 个位数据

SHIWEI EQU 23H十位数据

SCANLED EQU 25H

SCANMODE EQU 26H

RED EQU 28H 定义灯的缓冲区

GREEN EQU 29H

YELLOW EQU 32H

NUMTIM EQU 33H

LED EQU 34H

ORG 000H

JMP START

ORG 0BH

JMP TIMER0 定时器0中断入口

ORG 100H

START:MOV SP,#50H

MOV R0,#20H

MOV R5,#20

CLR0:MOV @R0,#00H

INC R0

DJNZ R5,CLR0

MOV TMOD,#01H 设置定时器

MOV TH0,#HIGH(65536-5000)

MOV TL0,#LOW(65536-5000)

SETB TR0

MOV IE,#10000010B端口初始化

MOV P0,#0FFH

MOV P1,#0FFH

MOV P2,#00H

MOV P3,#0FFH

MOV R3,#10

MOV R2,#3

MOV R1,#10

MOV R7,#200

MOV RED,#10

MOV YELLOW,#3

MOV GREEN,#10

MOV NUMTIM,#10

MOV LED,#0FFH

AJMP $

============================================================= TIMER0:PUSH ACC 定时器部分,负责交通灯的及时和数码管动态扫描

PUSH PSW

MOV TH0,#HIGH(65536-5000) 重新赋初值

MOV TL0,#LOW(65536-5000)

DJNZ R7,RET0

MOV R7,#200

MOV A,SCANMODE 调用扫描

MOV B,#4

DIV AB

MOV A,B

RLA

MOV DPTR,#TAB_SCAN

JMP @A+DPTR

TAB_SCAN: AJMP RED_LIGHT

AJMP YEL_LIGHT

AJMP GRE_LIGHT

AJMP YEL_LIGHT

RET0: MOV A,NUMTIM

LCALL BIN_BCD

MOV SHIWEI,A

MOV GEWEI,B

INC SCANLED

MOV A,SCANLED

MOV B,#4

DIV AB

MOV A,B

RLA

MOV DPTR,#TAB_SCAN0

JMP @A+DPTR

TAB_SCAN0:AJMP SCAN_L1

AJMP SCAN_L2

SCAN_L1: MOV P2,#0

MOV A,SHIWEI

JMP END_SCAN

SCAN_L2: MOV P2,#1

MOV A,GEWEI

JMP END_SCAN

END_SCAN:MOV DPTR,#TABLE

MOVC A,@A+DPTR

MOV P0,A

MOV A,LED

MOV P1,A

POP PSW

POP ACC

RETIRED_LIGHT:MOV LED,#11111100B

MOV NUMTIM,RED

DEC RED

MOV A,RED

CJNE A,#0FFH,RET0

MOV RED,#10

MOV A,SCANMODE

ADD A,#01H

MOV SCANMODE,A

JMP RET0

YEL_LIGHT:MOV LED,#11110011B

MOV NUMTIM,YELLOW

DEC YELLOW

MOV A,YELLOW

CJNE A,#0FFH,RET0

MOV YELLOW,#3

MOV A,SCANMODE

ADD A,#01H

MOV SCANMODE,A

JMP RET0

GRE_LIGHT:MOV LED,#11001111B

MOV NUMTIM,GREEN

DEC GREEN

MOV A,GREEN

CJNE A,#0FFH,RET1

MOV GREEN,#10

MOV A,SCANMODE

ADD A,#01H

MOV SCANMODE,A

RET1:JMP RET0 BIN_BCD:MOV B,#10

DIV AB

RET DELAY: MOV R5,#02

D1: MOV R6,#200

D2: MOV R7,#200

DJNZ R7,$

DJNZ R6,D2

DJNZ R5,D1

RETTABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH共阴字码表

DB 07H,7FH,6FH,77H,7CH,39H,5EH

DB 79H,71H,76H,73H,3EH,00HEND


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

原文地址:https://54852.com/yw/12452532.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存