标题:
带左转的单片机红绿灯proteus仿真与源码分享
[打印本页]
作者:
doudou2292
时间:
2018-1-4 14:24
标题:
带左转的单片机红绿灯proteus仿真与源码分享
单片机红绿灯仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
]@2[8$WP{QLJ39GOH`UW2JJ.png
(115.25 KB, 下载次数: 78)
下载附件
仿真图片
2018-1-4 14:24 上传
带左转灯
单片机源程序如下:
#include "use.h"
#include "main.h"
uchar code seg_du[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //七段管段码真值表 共阴 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
uchar code seg_we[]={0x01,0x02,0x04,0x08}; //共阴位码 0x01,0x02,0x04,0x08 0xfe,0xfd,0xfb,0xf7
uchar BackupGreen,BackupRed,CopyLight,CopyLLight,backupLGreen;
void Seg_Display(uchar number,uchar wei) //数码管动态显示程序
{
P0=0X00; //0XFF
we=1; //2.7
we=0;
P0=seg_du[number];
du=1; //2.6
du=0;
P0=seg_we[wei];
we=1;
we=0;
}
void UrgentScan() //设置 ???情况运行扫描
{
Seg_Display(BackupGreen/10,0);
Seg_Display(BackupGreen%10,1);
Seg_Display(BackupRed/10,2);
Seg_Display(BackupRed%10,3);
}
void SetLGreen()
{
Seg_Display(backupLGreen/10,0);
Seg_Display(backupLGreen%10,1);
}
void SetModel() //红绿灯设置模式
{
if(StaSysterm==NormalRun) //正常情况下修改为设置状态
{
StaSysterm=ResetGreen;
BackupGreen=GreenTime;
BackupRed=RedTime;
backupLGreen = GreenLTime;
CopyLight=P2; //对数据进行备份
CopyLLight = P1;
P2=0X09;
}
else if(StaSysterm==ResetGreen) //优先设置绿灯时间
{
StaSysterm=ResetRed;
}
else if(StaSysterm==ResetRed) //后设置红灯时间 设置完成后按键退出设置状态
{
StaSysterm=ResetLGreen;
}
else if(StaSysterm==ResetLGreen) //后设置红灯时间 设置完成后按键退出设置状态
{
StaSysterm=NormalRun;
P2=CopyLight; //恢复数据
P1=CopyLLight;
}
}
void ADDTime() //红绿灯时间加
{
if(StaSysterm==ResetGreen)
{
BackupGreen++;
if(BackupGreen>=BackupRed) BackupGreen=BackupRed; //绿灯时间不能大于红灯时间
}
else if(StaSysterm==ResetRed)
{
BackupRed++;
}
else if(StaSysterm==ResetLGreen)
{
backupLGreen++;
}
}
void SUBTime() //红绿灯时间减
{
if(StaSysterm==ResetGreen)
{
BackupGreen--;
}
else if(StaSysterm==ResetRed)
{
BackupRed--;
if(BackupGreen>=BackupRed) BackupRed=BackupGreen;
}
else if(StaSysterm==ResetLGreen)
{
backupLGreen--;
}
}
void UrgentModel() //紧急模式
{
if(StaSysterm==NormalRun)
{
StaSysterm=UrgentRun;
CopyLight=P2; //对数据进行备份
CopyLLight=P1;
P0=0XFF; //关闭数码管
we=1; //产生下降沿 锁存数据
we=0;
}
else if(StaSysterm==UrgentRun)
{
StaSysterm=NormalRun;
P2=CopyLight; //恢复数据
P1=CopyLLight;
}
else if(StaSysterm==ResetGreen || StaSysterm==ResetRed ||StaSysterm==ResetLGreen)
{
StaSysterm=NormalRun;
GreenTime=BackupGreen;
RedTime=BackupRed;
GreenLTime = backupLGreen ; //重新设置红绿灯时间
}
}
复制代码
#define _MAIN_C
#include "use.h"
#include "main.h"
#include "time.h"
#include "key.h"
bit flag1s; //0时时间不变 1时时间减小
uchar count1s,NS_time,WE_time;
uchar GreenTime=30,RedTime=50,GreenLTime = 10; //30s和35s
uchar index=0; //状态
enum eStaSysterm StaSysterm=NormalRun;
void main()
{
EA=1; //开总中断
InintTimer0(); //初始化定时器0
while(1)
{
LEDScan(); //数码管即LED扫描
KeyDriver(); //键盘驱动扫描
if(flag1s) //判断时间是否到 1s
{
flag1s=0;
NS_time--; //红绿灯倒计时时间减
WE_time--;
}
}
}
void InintTimer0() //初始化T0定时器
{
TMOD=0X01;
TH0=0X4C; // 初始化为50ms
TL0=0X00;
ET0=1; //开TO中断
TR0=1; //开始计数
}
void Timer0() interrupt 1
{
TH0=0XB8; //0.019 s 约为20ms
TL0=0X00;
KeyScan();
if(++count1s<50) return; //判断定时是否到1S
count1s=0;
if(StaSysterm==NormalRun) flag1s=1; //非正常运行时,不红绿灯数值不减一
}
void LEDScan()
{
if(StaSysterm==NormalRun) //正常运行
{
if(NS_time==0 || WE_time==0)
{
switch(index) //改变红绿灯的状态,状态机
{
case 0:
{
index = 1; //东西红灯
NS_time = GreenTime; //南北绿灯30
WE_time = RedTime; //红灯50
P2 = 0X09;
P1 = 0X0C; //输出
}break;
case 1:
{
index = 2;
NS_time=5; //南北黄灯东西红灯
P2 = 0X0A;
P1 = 0X0C;
}break;
case 2:
{
index = 3;
NS_time=GreenLTime; //南北左转东西红灯
P2 = 0X0C;
P1 = 0X09;
}break;
case 3:
{
index = 4;
NS_time=5; //南北黄灯东西红灯
P2 = 0X0C;
P1 = 0X0A;
}break;
case 4:
{
index=5;
NS_time = RedTime;
WE_time = GreenTime;
P2 = 0X24;
P1 = 0X0C;
}break;
case 5:
{
index = 6;
WE_time=5;
P2 = 0X14;
P1 = 0X0C;
}break;
case 6:
{
index = 7;
WE_time = GreenLTime;
P2 = 0X0C;
P1 = 0X24;
}break;
case 7:
{
index = 0;
WE_time=5; //南北黄灯东西红灯
P2 = 0X0C;
P1 = 0X14;
}break;
default:break;
}
}
Seg_Display(NS_time/10,0);
Seg_Display(NS_time%10,1);
Seg_Display(WE_time/10,2);
Seg_Display(WE_time%10,3);
}
else if(StaSysterm==UrgentRun)
{ //紧急情况运行 黄灯闪烁
P2=0x12;
P1 = 0X12; //所有黄灯亮
Delayms(200); //延迟200毫秒
P2=0x00;
P1 = 0X00; //所有黄灯灭
Delayms(200);
}
else if(StaSysterm==ResetGreen || StaSysterm==ResetRed) //设置调整红绿灯时间
{
index=0;
NS_time=0;
WE_time=0; //重新初始化红绿灯并运行
UrgentScan();
}
else
{
SetLGreen();
}
}
复制代码
#include "use.h"
#include "time.h"
sbit KEY1=P3^4; //设置 退出设置
sbit KEY2=P3^5; //加
sbit KEY3=P3^6; //减
sbit KEY4=P3^7; //紧急情况 退出紧急情况
uchar keystr[]={1,1,1,1},backup[]={1,1,1,1};
void KeyScan() //键盘扫描
{
static uchar keybuf[4]={0XFF,0XFF,0XFF,0XFF};
uchar i;
keybuf[0]=(keybuf[0]<<1)|KEY1;
keybuf[1]=(keybuf[1]<<1)|KEY2;
keybuf[2]=(keybuf[2]<<1)|KEY3;
keybuf[3]=(keybuf[3]<<1)|KEY4;
for(i=0;i<4;i++)
{
if(keybuf[i]==0X00) keystr[i]=0; //连续8次扫描值为0
else if(keybuf[i]==0XFF) keystr[i]=1;
}
}
void KeyAction(uchar key) //键盘执行
{
switch(key)
{
case 0: SetModel(); break;
case 1: ADDTime(); break;
case 2: SUBTime(); break;
case 3: UrgentModel(); break;
default:break;
}
}
void KeyDriver() //键盘驱动
{
uchar i;
for(i=0;i<4;i++)
{
if(keystr[i]!=backup[i])
{
if(keystr[i]==0)
KeyAction(i);
}
backup[i]=keystr[i];
}
}
复制代码
全部资料51hei下载地址:
Proteus 仿真.rar
(150.83 KB, 下载次数: 84)
2018-1-4 14:22 上传
点击文件名下载附件
仿真文件
下载积分: 黑币 -5
作者:
51heidian23
时间:
2018-3-22 13:26
东西不错,代码也很工整,给老哥打电话
作者:
Keil是我爸爸
时间:
2018-3-22 19:35
东西挺好的,谢谢分享
作者:
ftmovie
时间:
2018-3-25 20:50
学习学习 支持一下
作者:
公羽木水
时间:
2019-9-4 23:40
很好,辛苦了,谢谢
作者:
公羽木水
时间:
2019-9-4 23:42
感激不尽
作者:
18339196096
时间:
2019-12-28 13:44
总说code前少分号,怎么回事?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1