单片机仿真交通灯实验
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告实验名称:交通灯实验
姓名
班级
日期
实验要求:
1. 请使用单片机系统主机板和单片机系统键盘、显示板设计一个硬件系统,最终实
现一个交通路口红绿灯的控制。用两个数码管显示秒,8个LED灯分成四组,分别作为十字交叉路口的红绿灯。
2. 相对双向绿灯的最后几秒时,绿灯要闪烁,即亮灭交替,亮灭时间均为0.5秒,
然后变成红灯。
3. 每组同学可自行设计进行连接,形成一个单片机硬件系统。
4. 模拟调试完成后,用STC-ISP下载编程软件将生成的*。HEX文件在线下载到单片
机中。
5.下载后,按复位键执行程序,检验程序运行结果。
硬件连线方案:
程序流程图:
源代码:
#include
unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //定义无符号数组,定义的数据要放在ROM(程序存储区)里面
sbit dula=P1^3; //特殊功能位定义,数码管段码控制信号
sbit G1=P1^4; //数码管位选控制信号
sbit c=P1^5; //c表示P1.0口,地址最高位
sbit b=P1^6; //地址次高位
sbit a=P1^7; //地址最低位
sbit xl=P2^0; //特殊功能位声明,xl表示P2.0口
sbit xh=P2^1; //
sbit yl=P2^2;
sbit yh=P2^3;
sbit sl=P2^4;
sbit sh=P2^5;
sbit zl=P2^7;
sbit zh=P2^6;
char count=100; //定时时间取10ms,循环100次即为1s
unsigned char ssx=14; //秒上下,为上下绿灯亮时倒计数
unsigned char szy=10; //秒左右,为左右绿灯亮时倒计数
char sx=1; //方向标志,上下绿灯亮
void delay(char x) //延时函数,通过for循环进行延时
{
char a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
void shumaguanxianshi() //数码管显示函数
{
if(sx==1) //方向标志假如为上下
{ P0=tab[ssx/10]; dula=1; //选择2号管显示秒十位(上下) c=0;b=1;a=0; G1=1;
delay(2); //在晶振频率12MHz,延时2ms。
G1=0;
P0=tab[ssx%10]; dula=1; //选择3号管显示秒个位(上下)c=0;b=1;a=1; G1=1;
delay(2);
G1=0;
}
if(sx==0) //方向标志假如为左右
{ P0=tab[szy/10]; dula=1; //选择4号管显示秒十位(左右) c=1;b=0;a=0; G1=1;
delay(2);
G1=0;
P0=tab[szy%10]; dula=1; //选择5号管显示秒个位(左右)c=1;b=0;a=1; G1=1;
delay(2);
G1=0;
}
}
void xiaodeng() //小灯函数
{
if(sx==1) //判断方向是否为上下
{ xl=0; xh=1; sl=0; sh=1;
yl=1; yh=0; zl=1; zh=0; //红绿灯亮灭,0表示亮,1表示灭。上下绿灯,左右红灯 if(ssx<=5) //当左数码管显示5秒,控制绿灯闪烁
{ if(count<=50) //计数器时间小于0.5s
{xl=1;sl=1;} //绿灯灭
}
}
if(sx==0)
{ xl=1; xh=0; sl=1; sh=0;
yl=0; yh=1; zl=0; zh=1;
if(szy<=5)
{if(count<=50)
{yl=1;zl=1;}
}
}
}
initial() //初始化函数
{
TMOD=0x01; //设置定时器为工作方式1
TH0=0xD8; //在晶振频率12MHz下,赋初值
TL0=0xF0;
EA=1; //允许CPU中断
G1=0; //位选信号G1无效
TR0=1; //启动定时器T0
ET0=1; //允许定时器T0中断
}
main() //主函数
{
initial();//调用初始化函数
while(1) //无限循环,用于循环点亮小灯和显示数码管{
shumaguanxianshi(); //调用数码管显示函数xiaodeng(); //调用小灯函数
}
}
t0_int() interrupt 1 //中断函数,T0中断
{
TH0=0xD8; //重新赋初值
TL0=0xF0;
count--; //计数器减1
if(count==0) //判断计数器是否记满100次
{
count=100; //定时时间重新取值
if(sx==1) //假如方向标志是上下
{
ssx--; //时间倒记时
if(ssx==0) //左数码管显示0
{
sx=0; //方向标志取反,方向为左右
szy=10; //右数码管取值10s
}