标题:
单片机交通灯,请大家帮忙看看程序哪里有错误
[打印本页]
作者:
cocacool
时间:
2020-12-29 16:11
标题:
单片机交通灯,请大家帮忙看看程序哪里有错误
程序在Proteus上可以运行成功,在开发板连接之后中断返回有点问题(应该是功能函数那个地方),请大家帮忙看看是哪里有问题
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
//南北为次干道
sbit Blue_nb=P2^7; //南北左转标志
sbit Red_nb=P2^6; //南北红灯标志
sbit Yellow_nb=P2^5; //南北黄灯标志
sbit Green_nb=P2^4; //南北绿灯标志
//东西为主干道
sbit Blue_dx=P2^0; //东西左转标志
sbit Red_dx=P2^3; //东西红灯标志
sbit Yellow_dx=P2^2; //东西黄灯标志
sbit Green_dx=P2^1; //东西绿灯标志
sbit set=P3^6;
sbit key1=P3^4;
sbit key2=P3^5;
bit dx_nb=0; //东西南北控制位
bit Yellow_status=0; //黄灯闪烁标志位
unsigned int sec_dx; //东西方向时间存储变量
unsigned int sec_nb; //南北方向时间存储变量
float set_timedx=15; //东西方向的通行单次时间
float set_timenb=15; //南北方向的通行单次时间
unsigned char buf[4]; //秒显示的变量
unsigned char data countt0; //定时器0中断定时器
unsigned int Temp;
unsigned char flag_option=0; //功能选择: 紧急模式
sbit beep=P3^3; //蜂鸣器
sbit key_EP=P3^2; //紧急模式
unsigned char conut_ER; //紧急状态
unsigned char code led[11]={ //共阳极字型码
0xc0, //--0
0xf9, //--1
0xa4, //--2
0xb0, //--3
0x99, //--4
0x92, //--5
0x82, //--6
0xf8, //--7
0x80, //--8
0x90, //--9
0x00 //--NULL
};
/*延时函数*/
void delay(int time)
{
unsigned int j,k;
for(j=0;j<time;j++)
for(k=0;k<124;k++);
}
/*显示函数*/
void display(void)
{
buf[0]=sec_dx/10; //第1位 东西十位
buf[1]=sec_dx%10; //第2位 东西个位
P1=0x40; //LED1
P0=led[buf[0]]; //东西十位
delay(1);
P1=0x80; //LED2
P0=led[buf[1]]; //东西个位
delay(1);
buf[2]=sec_nb/10; //南北十位
buf[3]=sec_nb%10; //南北个位
P1=0x01;
P0=led[buf[2]];
delay(1);
P1=0x02;
P0=led[buf[3]];
delay(1);
}
/*功能函数*/
void function(void)
{
conut_ER=1-conut_ER;
if(conut_ER==1)
{
TR0=0; //关交通灯定时器
Temp=P2;
P2=0x00; //关全部信号灯
Red_dx=1; //全部置红灯
Red_nb=1;
beep=0;
}
if(conut_ER==0)
{
TR0=1; //开交通灯定时器
P2=Temp;
beep=1;
}
flag_option=0;
}
/*处理整个交通灯计时*/
void time0(void) interrupt 1 using 1 //定时中断子程序
{
TH0=0x4C; //重赋初值;11.0592m晶振50ms
TL0=0X00;
TR0=1; //开交通灯定时器
countt0++; //计数器数加1(用于计算时间)
if(countt0==20) //定时器中断次数=20时(即1秒时)
{
countt0=0; //清零计数器
sec_dx--; //东西时间减1
sec_nb--; //南北时间减1
if(sec_nb==5&&sec_dx==0&&(Yellow_status==0)) //当南北倒计时到5s时,用于黄灯闪烁时间
{
sec_dx=5;
Yellow_status=1;
}
if(sec_dx==5&&sec_nb==0&&(Yellow_status==0)) //当东西倒计时到5s时,用于黄灯闪烁时间
{
sec_nb=5;
Yellow_status=1; //启动黄灯开始倒计时
}
if((sec_nb<=5)&&(dx_nb==0)&&(Yellow_status==1)) //东西黄灯闪
{
Blue_dx=0;
Yellow_dx=~Yellow_dx;
}
if((sec_dx<=5)&&(dx_nb==1)&&(Yellow_status==1)) //南北黄灯闪
{
Blue_nb=0;
Yellow_nb=~Yellow_nb;
}
if(dx_nb==0&&sec_nb==0&&sec_dx==0) //东西通行:当黄灯时间、通行方向倒计时到0时
{
P2=0x00; //重置东西南背方向的红绿灯
Green_nb=1; //南北绿灯亮
Red_dx=1; //东西红灯亮
dx_nb=!dx_nb; //交换通行方向
Yellow_status=0; //关闭黄灯闪烁
sec_dx=set_timedx+25; //重赋东西方向的起始值
sec_nb=set_timenb+5; //重赋南北方向的起始值
}
if(dx_nb==1&&sec_dx==0&&sec_nb==0) //南北通行:当黄灯时间、通行方向倒计时到0时
{
P2=0X00; //重置东西南北的红绿灯状态
Green_dx=1; //东西绿灯亮
Red_nb=1; //南北红灯亮
dx_nb=!dx_nb; //交换通行方向
Yellow_status=0; //关闭黄灯闪烁
sec_dx=set_timedx+25; //重赋东西方向的起始值
sec_nb=set_timenb+45; //重赋南北方向的起始值
}
if(dx_nb==0&&sec_nb==20&&sec_dx==0) //东西通行:当东西直行绿灯倒数到0时
{
P2=0x00;
Blue_dx=1;
Red_nb=1;
sec_dx=set_timedx;
Yellow_status=0;
}
if(dx_nb==1&&sec_nb==0&&sec_dx==20) //南北通行:当南北直行绿灯倒数到0时
{
P2=0x00;
Blue_nb=1;
Red_dx=1;
sec_nb=set_timedx;
Yellow_status=0;
}
}
}
void key_to1()
{
TR0=0; //关定时器
if(set==0)
{sec_nb++; //南北加1S
sec_dx++;//东西加1S
}
else
TR0=1;
if(sec_dx==100&sec_nb==100) //东西黄灯闪烁
{
sec_nb=5;
sec_dx=5;
}
if(sec_nb==100) //东西直行,南北禁止
{
sec_nb=60;
sec_dx=40;
}
if(sec_dx==100) //南北直行,东西禁止
{
sec_nb=20;
sec_dx=40;
}
if(sec_nb==100&&sec_dx==95) //东西左转,南北禁止
{
sec_nb=20;
sec_dx=15;
}
if(sec_dx==100&&sec_nb==95) //南北左转,东西禁止
{
sec_nb=15;
sec_dx=20;
}
}
void key_to2()
{
TR0=0;//关定时器
if(set==0)
{sec_nb--; //南北减1S
sec_dx--; //东西减1S
}
else
TR0=1;
if(sec_dx==0&sec_nb==0) //南北黄灯闪烁
{
sec_nb=5;
sec_dx=5;
}
if(sec_nb==0) //东西直行,南北禁止
{
sec_nb=20;
sec_dx=40;
}
if(sec_dx==0) //南北直行,东西禁止
{
sec_nb=60;
sec_dx=40;
}
if(sec_nb==5&&sec_dx==0) //东西左转,南北禁止
{
sec_nb=20;
sec_dx=15;
}
if(sec_dx==5&&sec_nb==0) //南北左转,东西禁止
{
sec_nb=15;
sec_dx=20;
}
}
void key() //按键扫描子程序
{
if(key1!=1)
{
delay(10);
if(key1!=1)
{
while(key1!=1);
key_to1();
}
}
if(key2!=1)
{
delay(10);
if(key2!=1)
{
while(key2!=1);
key_to2();
}
}
}
//外部中断0
void int0(void) interrupt 0 using 1 //紧急模式
{
while(!key_EP)display();
flag_option=1;
}
/*初始化函数*/
void init()
{
TMOD=0X01; //定时器设置
TH0=0x4C; //TH0重赋初值;11.0592m晶振50ms
TL0=0X00;
TCON=0X10; //启动定时0
IE=0x83; //开总中断;定时器0中断开启;开外部中断
P2=0X42; //开始默认状态,东西红灯,南北绿灯
beep=1; //beep为1,蜂鸣器不响
sec_nb=60; //南北方向初始时间
sec_dx=40; //东西方向初始时间
conut_ER=0;
}
//主程序
void main()
{
init(); //初始化定时器、中断服务
while(1)
{ key(); //调用按键扫描程序
if(flag_option!=0)function(); //调用功能函数
display(); //调用显示函数
}
}
复制代码
作者:
csmyldl
时间:
2020-12-30 00:46
程序编译无错误,中断计时也无错误,但计时后的处理及信号灯的变化处理逻辑太混乱且复杂,可以简化
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1