简单的交通灯焊接与程序设计用时:5天
本课程设计报告的word版本及完整的程序代码下载地址:
http://www.51hei.com/bbs/dpj-77888-1.html
1 设计目的:设计一个东西方向和南北方向十字路口的简单交通灯控制系统。 2 设计要求:2.1 可以按键设置交通灯东西、南北的倒计时时间第一次按设置键是设置东西方向的时间,第二次按设置键是设置南北方向的时间,再按加减键就可以设置对应的时间。 22 东西和南北方向各有两个数码管分别显示时间东西和南北的时间相差5秒,这5秒为黄灯亮的时间。 2.3 当有特殊情况时,可以按紧急模式进行调整.2.4 紧急模式:当消防车、救护车等特殊车辆通行时按下”紧急模式键”全部亮红灯,待紧急车辆通过后,再恢复后再退出。 2.5 夜间模式:4个方向黄灯亮起。 2.6 禁止通行第1次按紧急键4个方向全部亮红灯. 2.7 夜间模式第2次东西南北4个方向黄灯闪烁 2.8 南北优先通行第3次南北绿灯亮东西红灯亮 2.9 东西优先通行第4次南北红灯亮东西绿灯亮 2.10 再按一次回到正常显示不同的模式适合不同的交通情况(如夜间模式,有交通事故的时候)
3 材料准备:10*15洞洞板1块, 51芯片(STC89C51RC), 母座(或者40pin芯片座或zip座), 红色LED灯1个, 103上拉排阻1个(九个引脚), 10K电阻1个, 1K电阻1个, 30pf瓷片电容2个, 10uf电解电容1个, 单排针, 轻触按键4个, 12.288 MHz晶振1个, 自锁开关(六脚), 杜邦线, USB转TTL线(下载与供电), 红黄绿LED灯各2个, 3641AH数码管(共阴四位数码管) 4 电路图:*注:关于EA:我使用的STC89C52RC单片机芯片(EA管脚已内部上拉到Vcc) - 如外部不加上拉,或外部上拉到Vcc,上电复位后单片机从内部开始执行程序;
- 如外部下拉到地,上电复位后单片机从外部开始执行程序。
根据网上找到的资料画的电路图: 1)去掉了复位电路和电源插孔:2)再修改后: 5 时钟电路:
5.1 关于单片机的XTAL1和XTAL2单片机的XTAL1和XTAL2内部有一片内振荡器结构但仍需要在XTAL1和XTAL2两端连接一个晶振和两个电容才能组成时钟电路,这种使用晶振配合产生信号的方法是内部时钟方式; 5.2 晶振说明无源晶振是有2个引脚的无极性元件,需要借助于时钟电路才能产生振荡信号,自身无法振荡起来; 5.3 时钟电路的重要性时钟电路在单片机系统中很重要,它能控制着单片机工作的节奏,是必不可少的部分。单片机运行需要时钟支持——就像计算机的CPU一样,如果没有时钟电路来产生时钟驱动单片机,那单片机就不能执行程序。 6 自锁开关:六引脚自锁开关是一个双刀双掷开关,除了图上用黑线相连的部分,其他部分均不相连。 7 A103J排阻:排阻是具有极性,在焊接的时候一定需要注意,如果方向弄错可能导致显示不了。 从图上可以看到排阻左边有一个点标记和103数值。那个点表示那一端的第一个引脚为公共引脚。,而103表示该排阻,前两位数表示数值,最后一位表示倍数即10X10 3=10K。 排阻在原理图中的符号表示:根据图可以发现排阻内部的所有电阻都连接到第一个引脚上,所以第一个引脚肯定就是公共端,见下图。 8 四脚开关:
9 3641AH数码管引脚图:
对应的字母段码排列: 10 仿真图:11 电路连接测试1)正面图:2)背面图:
12 程序分析:
- #include
- #define uint unsigned int
- #define uchar unsigned char
- /* I/O口的定义 */
- sbit w1_NS=P1^0; //数码管南北时间的位选
- sbit w2_NS=P1^1;
- sbit w1_WE=P1^4; //数码管东西时间的位选
- sbit w2_WE=P2^7;
- sbit k1=P3^2; //按键的定义
- sbit k2=P3^5;
- sbit k3=P3^6;
- sbit k4=P3^7;
- sbit red_NS=P2^1; //南北红绿黄灯的定义
- sbit yellow_NS=P1^6;
- sbit green_NS=P1^5;
- sbit red_WE=P2^6; //东西红绿黄灯的定义
- sbit yellow_WE=P2^4;
- sbit green_WE=P2^3;
-
- uchar seconds_NS,seconds_WE,seconds_WE_set,seconds_NS_set,flag_NS,flag_WE,t0,k1num,k4num;
- uchar code table[]={
- 0xeb,0x28,0xb3,0xba,0x78, //数码管译码:分别对应数字0~9
- 0xda,0xdb,0xa8,0xfb,0xfa
- };
-
- void delay(uint z); //延时函数
- void init(); //初始化函数
- void display_NS(); //南北时间显示函数
- void display_WE(); //东西时间显示函数
- void LED_display(); //红路灯的正常模式函数
- void keyscan(); //按键扫描函数
-
- void main()
- {
- init();
- while(1)
- {
- keyscan();
- display_NS();
- display_WE();
- LED_display();
- }
- }
-
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
-
- void init() //初始化函数
- {
- t0=0;
- flag_NS=0;
- flag_WE=0;
- seconds_NS_set=10;
- seconds_WE_set=15;
- seconds_NS=seconds_NS_set;
- seconds_WE=seconds_WE_set;
- TMOD=0x01; //设置定时器的工作方式为1,定时器工作方式
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0的中断
- TR0=1; //开启定时器0的运行开关
-
- }
-
- void display_NS() //南北时间显示函数
- {
- P0=0x00;
- w1_NS=0;
- P0=table[seconds_NS/10]; //显示南北时间的十位
- delay(1);
- w1_NS=1;
-
- P0=0x00;
- w2_NS=0;
- P0=table[seconds_NS%10]; ////显示南北时间的个位
- delay(1);
- w2_NS=1;
-
- }
-
- void display_WE() //东西时间显示函数
- {
- P0=0x00;
- w1_WE=0;
- P0=table[seconds_WE/10]; //显示东西时间的十位
- delay(1);
- w1_WE=1;
-
- P0=0x00;
- w2_WE=0;
- P0=table[seconds_WE%10]; //显示东西时间的个位
- delay(1);
- w2_WE=1;
-
- }
-
- void timer0() interrupt 1 //中断函数,16位加1计数器
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- t0++;
- if(t0==20)
- {
- t0=0;
- seconds_NS--;
- seconds_WE--;
- }
- }
-
- void LED_display() //红路灯的正常模式
- {
- if(flag_NS==0) //flag_NS为0时
- {
- if(seconds_NS>5) //南北时间大于5s
- {
- red_NS=1; //红灯灭
- yellow_NS=1; //黄灯灭
- green_NS=0; //绿灯亮
- }
- else
- { //5s内亮黄灯5s
- red_NS=1;
- yellow_NS=0;
- green_NS=1;
- if(seconds_NS==0)
- {
- seconds_NS=seconds_WE_set;
- flag_NS=1;
- }
- }
- }
- if(flag_NS==1) // flag_NS为1时
- {
- if(seconds_NS>5)
- {
- red_NS=0; //红灯亮
- yellow_NS=1; //黄灯灭
- green_NS=1; //绿灯灭
- }
- else
- { //5s内亮黄灯5s
- red_NS=1;
- yellow_NS=0;
- green_NS=1;
- if(seconds_NS==0)
- {
- seconds_NS=seconds_NS_set;
- flag_NS=0;
- }
- }
- }
-
- if(flag_WE==0) //flag_WE为0时
- {
- if(seconds_WE>5)
- {
- red_WE=0; //红灯亮
- yellow_WE=1; //黄灯灭
- green_WE=1; //绿灯灭
- }
- else
- { //5s内黄灯亮5s
- red_WE=1;
- yellow_WE=0;
- green_WE=1;
- if(seconds_WE==0)
- {
- seconds_WE=seconds_NS_set;
- flag_WE=1;
- }
- }
- }
- if(flag_WE==1)
- {
- if(seconds_WE>5)
- {
- red_WE=1; //红灯灭
- yellow_WE=1; //黄灯灭
- green_WE=0; //绿灯亮
- }
- else
- { //黄灯亮5s
- red_WE=1;
- yellow_WE=0;
- green_WE=1;
- if(seconds_WE==0)
- {
- seconds_WE=seconds_WE_set-3;
- flag_WE=0;
- }
- }
- }
- }
-
- void keyscan() //按键扫描
- {
- if(k1==0)
- {
- while(!k1); //等待按键释放(消抖)
- k1num++;
- TR0=0;
- }
- if(k1num==1)
- {
- if(k2==0)
- {
- while(!k2);
- seconds_NS_set++;
- seconds_NS=seconds_NS_set;
- // display_NS();
- if(seconds_NS==100)
- seconds_NS=0;
- }
- if(k3==0)
- {
- while(!k3);
- seconds_NS_set--;
- seconds_NS=seconds_NS_set;
- // display_NS();
- if(seconds_NS==0)
- seconds_NS=99;
- }
- }
- if(k1num==2)
- {
- if(k2==0)
- {
- while(!k2);
- seconds_WE_set++;
- seconds_WE=seconds_WE_set;
- // display_WE();
- if(seconds_WE==100)
- seconds_WE=0;
- }
- if(k3==0)
- {
- while(!k3);
- seconds_WE_set--;
- seconds_WE=seconds_WE_set;
- // display_WE();
- if(seconds_WE==0)
- seconds_WE=99;
- }
- }
- if(k1num==3)
- {
- k1num=0;
- TR0=1;
- }
-
- if(k4==0)
- {
- while(!k4);
- k4num++;
- }
-
- /*特殊情况选择模式*/
- switch(k4num)
- {
- case 1: //按第1次为紧急模式,禁止通行
- red_WE=0;
- yellow_WE=1;
- green_WE=1;
- red_NS=0;
- yellow_NS=1;
- green_NS=1;
- TR0=0;
- flag_NS=-1;
- flag_WE=-1;
- seconds_NS=99;
- seconds_WE=99;
- break;
复制代码 13 心得体会本次是第一次焊接,刚开始出现许多错误,修改修改再修改;上网查资料,请教师兄,最后做出来了。这次从中收获许多,学会从网上检索有用的资料,这对我们学习有很大的帮助。对单片机也有了进一步的了解,动手能力、分析能力也增强了,实践很重要,再好的理论如果不能用于实践,那么它就是没有用的。 纸上得来终觉浅,绝知此事要躬行。 感谢。
参考资料: 1、单片机最小系统电路图:
|