设计为交通灯仿真实验,有AD电路图。网上下载的资源,进行了修改,道路分为主道路和次干道,主干道作为主要交通线,通行时间比次干道多5秒左右。可以从程序进行修改
模拟真实生活中的交通灯情况,配有三个按钮,用来控制灯的状态。暂停/驱动,时间增加,时间减少。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
电路原理图如下:
原理图
单片机源程序如下:
- #include<stc10.h>
- #define D P1
- #define uchar unsigned char
- #define uint unsigned int
- /*******************************************函数声明*****************************************/
- void z1(void);//南北通行
- void z2(void);//南北注意
- void z3(void);//东西通行
- void z4(void);//东西注意
- void gb(void); //关闭所有
- void jinji(void);//紧急状态,红灯全亮
- void sm(void); //扫描键盘
- void plus(); //通行时间加1扫描
- void minus(); //通行时间减1扫描
- void plus2();
- void minus2();
- void timer(void);//定时器T1初始化
- void time1(void);//定时器T1中断服务程序
- void display(void);//显示函数
- void delay(uint a);//10ms延时
- /*************************************数组及全局变量的定义***************************************/
- uint duan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9的段码
- uint y,gw,sw,gw2,sw2; //全局变量
- int time,s,times,time2,times2,time3;
- /*********************************定义交通灯、数码管的位选、按键对应的引脚*********************************/
- sbit d1 =P2^0; sbit d2 =P2^1; sbit d3= P2^2; sbit w1=P0^0; sbit H1 =P3^6; sbit H2=P3^7;
- sbit d4 =P2^3; sbit d5 =P2^4; sbit d6= P2^5; sbit w2=P0^1; sbit key1 =P0^5;
- sbit d7 =P2^6; sbit d8 =P2^7; sbit d9= P3^2; sbit w3=P0^2; sbit key2 =P0^6;
- sbit d10=P3^3; sbit d11=P3^4; sbit d12=P3^5; sbit w4=P0^3; sbit key3 =P0^7;
- /*********************************************主函数***********************************************/
- void main(void)
- {
- times=18;
- time=15;
- time2=10;
- times2=12;
- y=0,s=0; //定时器溢出计数初始化
- P1M1=0X00; //设置推挽输出,增加数码管亮度
- P1M0=0XFF;
- timer(); //启动定时器T1
- while(1)
- {
- z1(); //主干道通行,绿灯15秒
- z2(); //主干道注意,黄灯3秒
- z3(); //次干道通行,绿灯10秒
- z4(); //次干道注意。黄灯2秒
- }
- }
- /******************不同状态函数、定时器初始化、定时器中断服务函数************************/
- void z1(void)//南北通,东西禁
- {
- while(s<time)
- {
- sm();
- plus();
- minus();
- if(TR1==1)
- {
- //绿 /黄 /红
- d4 =0;d5 =1;d6 =1;//北
- d10=0;d11=1;d12=1;//南
- d7 =1;d8 =1;d9 =0;//东
- d1 =1;d2 =1;d3 =0;//西
- }
- sw2=(time-s)/10; //数码管十位(南北主干道)
- gw2=(time-s)%10; //数码管个位
- sw=(times-s)/10;
- gw=(times-s)%10;
- display(); //数码管显示
- gb(); //全关
- } s=0;//置零定时时间标志位
- }
- void z2(void)//南北黄灯注意,东西禁
- {
- time3=3;
- while(s<time3)
- {
- sm();
- if(TR1==1)
- {
- //绿 /黄 /红
- d4 =1;d5 =0;d6 =1;
- d10=1;d11=0;d12=1;
- d7 =1;d8 =1;d9 =0;
- d1 =1;d2 =1;d3 =0;
- }
- sw2=(time3-s)/10;
- gw2=(time3-s)%10;
- sw=sw2;
- gw=gw2;
- display();
- gb();
- } s=0;
- }
- void z3(void)//东西通行,南北禁止
- {
- while(s<time2)
- {
- sm();
- plus2();
- minus2();
- //绿 /黄 /红
- d4 =1;d5 =1;d6 =0;
- d10=1;d11=1;d12=0;
- d7 =0;d8 =1;d9 =1;
- d1 =0;d2 =1;d3 =1;
- sw2=(times2-s)/10;;
- gw2=(times2-s)%10;
- sw=(time2-s)/10;
- gw=(time2-s)%10;
- display();
- gb();
- } s=0;
- }
- void z4(void)//东西注意,南北禁止
- {
- time3=2;
- while(s<time3)
- {
- sm();
- //绿 /黄 /红
- d4 =1;d5 =1;d6 =0;
- d10=1;d11=1;d12=0;
- d7 =1;d8 =0;d9 =1;
- d1 =1;d2 =0;d3 =1;
- sw=(time3-s)/10;
- gw=(time3-s)%10;
- sw2=sw;
- gw2=gw;
- display();
- gb();
- } s=0;
- }
- void jinji(void)//红灯全亮,其余全灭,表示进入紧急状态
- {
- //绿 /黄 /红
- d4 =1;d5 =1;d6 =0;
- d10=1;d11=1;d12=0;
- d7 =1;d8 =1;d9 =0;
- d1 =1;d2 =1;d3 =0;
- }
- void gb(void)//全部关闭
- {
- //绿 /黄 /红
- d4 =1;d5 =1;d6 =1;
- d10=1;d11=1;d12=1;
- d7 =1;d8 =1;d9 =1;
- d1 =1;d2 =1;d3 =1;
- }
- void delay(uint a) //@11.0592MHz 10ms延时
- {
- for(a;a>0;a--)
- {
- unsigned char i, j;
- i = 18;
- j = 235;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- void display() //数码管显示
- {
- w1=0; //十位
- D=duan[sw];
- delay(1);
- w1=1;
- D=0X00;
- w2=0; //个位
- D=duan[gw];
- delay(1);
- w2=1;
- D=0x00;
- w3=0; //十位
- D=duan[sw2];
- delay(1);
- w3=1;
- D=0X00;
- w4=0; //个位
- D=duan[gw2];
- delay(1);
- w4=1;
- D=0x00;
- }
- void timer(void)
- {
- TMOD=0X10;
- TH1=(65536-50000)/256; //50ms延时
- TL1=(65536-50000)%256;
- EA=1;
- ET1=1;
- TR1=1;
- }
- void time1(void) interrupt 3
- {
- TH1=(65536-50000)/256; //50ms延时
- TL1=(65536-50000)%256;
- y++;
- if(y==20)
- {s++; y=0;}
- }
- void sm(void)//紧急状态扫描函数
- {
- H1=0; //按键另一端置零,当按键按下相当于接地,没有按下,经上拉电阻拉高了
- if(key1==0) //是否按下
- {
- delay(2); //消抖
- while(!key1) //松手检测
- TR1=!TR1; //关闭定时器
- while(key1==1) //进入紧急状态
- {
- gb();
- jinji();
- gw=gw2=sw=sw2=8;
- display();
- }
- while(key1==0) //松手检测
- display();
- TR1=1; //打开定时器,跳出
- }
- }
- void plus()
- {
- H1=0; //按键另一端置零,当按键按下相当于接地,没有按下,经上拉电阻拉高了
- if(key2==0) //是否按下
- delay(2); //消抖
- if(key2==0)
- {
- time+=1;
- times+=1;}
- while(!key2); //松手检测
- }
- void minus()
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码 Keil代码与Proteus仿真下载:
仿真和代码.7z
(244.62 KB, 下载次数: 29)
|