#define uint unsigned int #define uchar unsigned charuchar night_flag=0; //紧急标志位
uchar time_cl=0; //定义时间控制标志位 取0 uchar flag=0; //方向通行标志位
uchar B_N_D_flag=1; //定义北南通灯行标志位 uchar X_D_D_flag=1; //定义西东通灯行标志位 uchar i,j; //定义变量i
uchar t=3; //数码管动态扫描延时时间基数 uchar num=0; //时间基数初始化为0 //uchar num_night=0; //紧急模式时间基数为0 uchar time=35; //time初始化定为35秒 int bei,nan,xi,dong; //定义 北 南 西 东 uchar
code
Data[]={0x18,0x7B,0x,0x49,0x6A,0x4C,0x0C,0x79,0x08,0x48,0xEF};
//定义数组 数码管 0 1 2 3 4 5 6 7 8 9 -
/***************定义 红黄绿灯**************/
sbit M=P0^3;
sbit B_R=P1^2; //北面 红灯 sbit B_Y=P1^1; //北面 黄灯 sbit B_G=P1^0; //北面 绿灯 sbit N_R=P2^0; //南面 红灯 sbit N_Y=P2^1; //南面 黄灯 sbit N_G=P2^2; //南面 绿灯 sbit X_R=P2^5;//西面 红灯
sbit X_Y=P2^6; //西面 黄灯 sbit X_G=P2^7; //西面 绿灯 sbit D_R=P3^7; //东面 红灯 sbit D_Y=P3^6; //东面 黄灯 sbit D_G=P3^5; //东面 绿灯 sbit s1=P3^4;//时间减 sbit s2=P3^3;//时间加
sbit s3=P3^1;//紧急模式控制切换口
sbit s4=P3^2;//进入时间可以设置状态的切换口 /***************定义 数码管*****************/ #define SMG_XS P0 //数码管数据显示 #define SMG_KZ P2 //数码管控制显示 sbit smg1=P2^4;//定义数码管1控制口 sbit smg2=P2^3;//定义数码管2控制口
void delay(uint time);// 定义延时程序 void disp_init();//显示初始化 void disp(bei,nan,xi,dong);
void Time0_init() //定时器0初始化函数 {
TMOD=0x01; //定时器0为方式1 TL0=(65536-50000)%256;
TH0=(65536-50000)/256; //12M晶振 定时时间50ms ET0=1; //开定时器0中断 EA=1; //开总中断 TR0=1; //启动定时器0 }
void night_mode() //紧急模式 { B_R=1;
B_R=~B_R; //北 红灯取反 B_G=1; N_R=1;
N_R=~N_R; //南 红灯取反 N_G=1;
X_R=1;
X_R=~X_R; //西 红灯取反
X_G=1; D_R=1;
D_R=~D_R; D_G=1; }
void B_N_G() {
B_G=0; N_G=0; B_R=1; B_Y=1; N_R=1; N_Y=1;
X_R=0; D_R=0; X_Y=1; X_G=1; D_Y=1; D_G=1; }
void X_D_G() {
//东 红灯取反 //北南通(绿灯) //北 绿灯亮 //南 绿灯亮 //西 红灯亮 //东 红灯亮 //西东通(绿灯) (红灯) (红灯) 西东北南 B_G=1; N_G=1;
B_R=0; B_Y=1;
N_R=0; N_Y=1; X_R=1; D_R=1; X_Y=1;
X_G=0; D_Y=1;
D_G=0; }
void B_N_tong() {
if(B_N_D_flag==1) {
B_N_G(); B_N_D_flag=0; }
while(num==20) {
//北 红灯亮 //南 红灯亮 //西 绿灯亮 //东 绿灯亮 //北南 通行 //当北南通灯行标志位为1 //北南通(绿灯) 西东(红灯) //北南通灯行标志位置0 //当1s时间到 M=0;
num=0; //num清0 bei--; //北时间 减1 nan--; //南时间 减1 xi--; //西时间 减1 dong--; //东时间 减1 M=1;
if(bei<=6&&bei>=0||nan<=6&&nan>=0) //当北和南时间在0到6秒之间 {
if(bei<=6&&bei>5||nan<=6&&nan>5) //进一步判断北和南时间是否在5到6秒之间 {
B_G=~B_G; //北 绿灯取反 N_G=~N_G; //南 绿灯取反 }
if(bei<=5&&nan<=5) //进一步判断北和南时间是否在5秒以内 {
B_G=1; //北 绿灯不亮 N_G=1; //南 绿灯不亮 B_Y=0; //北 黄灯亮
N_Y=0; } }
else 0到6秒之间) {
B_G=0; N_G=0; B_Y=1; N_Y=1; } } }
void X_D_tong() {
if(X_D_D_flag==1) 为1 {
X_D_G(); 灯)
X_D_D_flag=0; 0
//南 黄灯亮 //否则(即北和南时间不在 //北 绿灯亮 //南 绿灯亮 //北 黄灯不亮 //南 黄灯不亮 //西东 通行 //当西东通灯行标志位//西东通(绿灯) 北南(红 //西东通灯行标志位置 }
while(num==20) //当1s时间到 { M=0;
num=0; //num清0 bei--; //北时间 减1 nan--; //南时间 减1 xi--; //西时间 减1 dong--; //东时间 减1 M=1;
if(xi<=6&&xi>=0||dong<=6&&xi>=0) //当西和东时间在0到6秒之间 {
if(xi<=6&&xi>5||dong<=6&&dong>5) //进一步判断西和东时间是否在5到6秒之间 {
X_G=~X_G; //西 绿灯取反 D_G=~D_G; //东 绿灯取反 }
if(xi<=5&&dong<=5) //进一步判断西和东时间是否在5秒以内 {
X_G=1; D_G=1; X_Y=0; D_Y=0; } }
else 0到6秒之间) {
X_G=0; D_G=0; X_Y=1; D_Y=1;//东 黄灯不亮 } } }
void Time0() interrupt 1 务函数 {
TH0=(65536-50000)/256; 置50ms中断一次
TL0=(65536-50000)%256;
//西 绿灯不亮 //东 绿灯不亮 //西 黄灯亮 //东 黄灯亮 //否则(即西和东时间不在 //西 绿灯亮 //东 绿灯亮 //西 黄灯不亮 //定时器0中断服 //重新载装初值,设 num++; //时间基数加1 }
void main() //主函数入口 {
bei=nan=xi=dong=time; //把time值赋给北 南 西 东
disp_init(); //显示初始化
Time0_init(); //定时器0初始化函数 while(1) //无限循环
if(s3==0) //当P3.7按下(开/关 紧急模式) {
delay(5); //延时去抖 s3=1; //关闭数码管显示 if(s3==0) {
night_flag=~night_flag; //紧急标志位取反(开/关紧急模式),1表示开,0表示关
if(night_flag==1) //如果紧急模式开 {
TR0=0; //关闭定时器0 num=0; //时间基数清0
TL0=(65536-50000)%256;
TH0=(65536-50000)/256; //12M晶振 定时时间50ms
TR0=1; //开启定时器0 SMG_KZ=0xff; //关闭数码管显示 }
else //否则night_flag=0表示紧急模式关(红绿灯正常运行) void disp_init() //显示初始化 {
for(i=0;i<3;i++) {
SMG_XS=Data[10]; //数码管显示\"--\" smg1=0;
smg2=0;//允许数码管显示 B_R=0; //北面 红灯 B_Y=0; //北面 黄灯 B_G=0; //北面 绿灯 N_R=0; //南面 红灯 N_Y=0; //南面 黄灯 N_G=0; //南面 绿灯 X_R=0;//西面 红灯
X_Y=0; //西面 黄灯 X_G=0; //西面 绿灯 D_R=0; //东面 红灯 D_Y=0; //东面 黄灯 D_G=0; //东面 绿灯 delay(300); //延时 B_R=1; //北面 红灯 B_Y=1; //北面 黄灯 B_G=1; //北面 绿灯 N_R=1; //南面 红灯 N_Y=1; //南面 黄灯 N_G=1; //南面 绿灯 X_R=1;//西面 红灯
X_Y=1; //西面 黄灯 X_G=1; //西面 绿灯 D_R=1; //东面 红灯 D_Y=1; //东面 黄灯 D_G=1; //东面 绿灯 delay(300); //延时 } }
void delay(uint time)
{
uint x,y;
for(x=time;x>0;x--) for(y=110;y>0;y--); }
五、调试
1. Proteus软件仿真:在此次设计中,用Proteus对硬件部分进行模式。在Proteus中输入原理图后,在单片机中载入汇编程序生成的hex文件,运行仿真,结果如下:
2. 调试过程:调试时老师询问了时钟电路,以及最小系统等问题,并随机选择了程序中的句子叫我及其他组员做答辩。最后验收附带要求我们添加时钟跟随LED,于是我们在159行时钟满一秒添加了E=1,在随后的下一秒关闭额外的LED灯即E=0。在Proteus实际仿真中我们的E放置的是显色明显的黄色LED。
六、心得体会
通过这次交通灯的课程设计,使我得到了一次用专业知识、专业技能分析和解决现实问题的能力。使我在单片机的基本原理、单片机应用学习过程中,以及在常用编程设计思路技巧的掌握方面都能向前迈了一大步,为日后成为一名合格的应用型人才打下良好的基础。综合课程设计让我把以前学习到的知识得到巩固和进一步的提高认识,对已有知识有了更深层次的理解和认识。在此,由于自身能力有限,在课程设计中碰到了很多的问题,我通过查阅相关书籍、资料以及和周围同学交流得到解决。
通过合作,我们的合作意识得到加强。合作能力得到提高。上大学后,很多同学都没有过深入的交流,在设计的过程中,我们用了分工与合作的方式,每个人互责一定的部分,同时在一定的阶段共同讨论,以解决分工中个人不能解决的问题,在交流中大家积极发言,和提出意见,同时我们还向别的同学请教。在此过程中,每个人都想自己的方案得到实现,积极向同学说明自己的想法。能过比较选出最好的方案。在这过程也提高了我们的表过能力。