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

}

源程序如下:

CODE SEGMENT

ASSUME CS:CODE

ORG 1000H

START:MOV DX,73H

MOV AL,80H

OUT DX,AL

MOV DX,71H

MOV AL,1110B

OUT DX,AL

MOV DX,72H

MOV AL,01111001B

OUT DX,AL

CALL DELAYED1

MOV BX,5H

L1:

MOV DX,71H

MOV AL,1110B

OUT DX,AL

MOV DX,72H

MOV AL,10111010B

OUT DX,AL

CALL DELAYED2

MOV DX,71H

MOV AL,1110B

OUT DX,AL

MOV DX,72H

MOV AL,11111011B

OUT DX,AL

CALL DELAYED2

DEC BX

JNZ L1

MOV DX,71H

MOV AL,0011B

OUT DX,AL

MOV DX,72H

MOV AL,11001111B

OUT DX,AL

CALL DELAYED1

MOV BX,5H

L2:

MOV DX,71H

MOV AL,0101B

OUT DX,AL

MOV DX,72H

MOV AL,11010111B

OUT DX,AL

CALL DELAYED2

MOV DX,71H

MOV AL,0111B

OUT DX,AL

MOV DX,72H

MOV AL,11011111B

OUT DX,AL

CALL DELAYED2

DEC BX

JNZ L2

JMP START

DELAYED1: MOV AX,10

L3: MOV CX,0FFFFH

LOOP $

DEC AX

JNZ L3

RET

DELAYED2:MOV CX,0FFFFH

LOOP $

RET

CODE ENDS

END START

8255CS插孔连译码输出070H-07FH插孔

我说的B 就是你看到的PB C就是实验版上的PC

如果你 b3--L1 b2--L2 B1--L3 B0--L4 C7--L5 C6--L6

c5--L7 c4--L8 c3--L9 c2--L10 c1--L11 C0--L12不对的话

可能你的实验板和我见到的不同

你再试一下

C7--L1 C6--L2 c5--L3 c4--L4 c3--L5 c2--L6 C1--L7 C0--L8

B3--L9 B2--L10 B1--L11 B0——L12

还有 灯的延迟时间你要自己调 因为个人的芯片时钟不一样

源程序我调过

还有 标号你自己改一下

五、设计说明

1. 因为本设计是交通灯控制设计,所以要先了解实际交通灯的变化规律。假设一个十字路口为东西南北走向。初始状态0为东西红灯,南北红灯,然后转状态l南北绿灯通车,东西红灯;过一段时间转状态2,南北绿灯闪几次转亮黄灯,延时3秒,东西仍然红灯;再转状态3,东西绿灯通车,南北红灯;过一段时间转状态4,东西绿灯闪几次转亮黄灯,延时3秒,南北仍然红灯;然后在循环至状态1,依次类推。

2. 中断服务程序的关键是:(1)保护进入中断时的状态,并在退出中断之前恢复进入时的状态。(2)必须在中断程序中设定是否允许中断重入。

ORG 0000H

AJMP MAIN

ORG 0003H

LJMP INT

ORG 0040H

MAIN:MOV SP,#60H

SETB EA

SETB EX0

SETB PX0

SETB IT0

MOV P1,#09H

ACALL DELAY1S

ABC:MOV R0,#3

MOV R1,#3

MOV P1,#0CH

ACALL DELAY1S

DEF:

CLR P1.2

ACALL DELAY2S

SETB P1.2

ACALL DELAY2S

DJNZ R0,DEF

MOV P1,#0AH

ACALL DELAY1S

MOV P1,#11H

ACALL DELAY1S

MOV P1,#21H

ACALL DELAY1S

GHI:CLR P1.5

ACALL DELAY2S

SETB P1.5

ACALL DELAY2S

DJNZ R1,GHI

MOV P1,#11H

AJMP ABC

INT: CLR EA

PUSH PSW

PUSH ACC

PUSH 05H

PUSH 06H

PUSH 07H

PUSH P1

SETB EA

MOV P1,#09H

ACALL DELAY1S

CLR EA

POP P1

POP 07H

POP 06H

POP 05H

POP ACC

POP PSW

SETB EA

RETI

DELAY1S:MOV R7,#5

DEL:MOV R6,#255

DE:MOV R5,#255

DJNZ R5,$FOSC=6MHZ

DJNZ R6,DE

DJNZ R7,DEL

RET

DELAY2S:MOV R4,#250

DELL:MOV R3,#250

DJNZ R3,$FOSC=6MHZ

DJNZ R4,DELL

RET

END


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存