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 1000HL: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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)