分享一个赛车跑道自动触发计时系统_程序&仿真工程文件
可按键设置圈数,传感器感应赛车后自动触发计时
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- //---重定义关键词---//
- #ifndef uchar
- #define uchar unsigned char
- #endif
- #ifndef uint
- #define uint unsigned int
- #endif
- //--定义使用的IO口--//
- #define GPIO_DIG P0
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit K1=P3^5; //圈数设置
- sbit K2=P3^6; //圈数确定
- sbit K3=P3^7; //清零
- unsigned int Time;
- unsigned int sec=0;
- unsigned char countset=1;
- char count;
- //--定义全局变量--//
- unsigned char code DIG_PLACE[8] = {
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制 查表的方法控制
- unsigned char code DIG_CODE[17] = {
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
- //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
- unsigned char DisplayData[8];
- //用来存放要显示的8位数的值
- uchar state=0;
- void Delay10ms(); //延时10ms
- void KeyDown(); //检测按键函数
- void Display()
- {
- if(state==3)
- {
- DisplayData[7]=DIG_CODE[countset/10%10]; //设置圈数
- DisplayData[6]=DIG_CODE[countset%10];
- DisplayData[5]=0x00; //不显示
- DisplayData[4]=0x00;
- DisplayData[3]=0x00;
- DisplayData[2]=0x00;
- DisplayData[1]=0x00;
- DisplayData[0]=0x00;
- }
- else if(state==2)
- {
- DisplayData[7]=0x00; //不显示
- DisplayData[6]=0x00;
- DisplayData[5]=DIG_CODE[sec/1000%10]; //秒
- DisplayData[4]=DIG_CODE[sec/100%10];
- DisplayData[3]=DIG_CODE[sec/10%10];
- DisplayData[2]=DIG_CODE[sec%10]|0x80;
- DisplayData[1]=DIG_CODE[Time/10%10]; //秒小数
- DisplayData[0]=DIG_CODE[Time%10];
- }
- else
- {
- DisplayData[7]=DIG_CODE[count/10%10]; //圈数
- DisplayData[6]=DIG_CODE[count%10];
- DisplayData[5]=DIG_CODE[sec/1000%10]; //秒
- DisplayData[4]=DIG_CODE[sec/100%10];
- DisplayData[3]=DIG_CODE[sec/10%10];
- DisplayData[2]=DIG_CODE[sec%10]|0x80;
- DisplayData[1]=DIG_CODE[Time/10%10]; //秒小数
- DisplayData[0]=DIG_CODE[Time%10];
- }
- }
- //--声明全局函数--//
- void DigDisplay(); //动态显示函数
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main(void)
- {
- unsigned char i=0;
- //设置INT0
- IT0=1;//跳变沿出发方式(下降沿)
- EX0=1;//打开INT0的中断允许。
- TMOD=0X11; //设置计数器工作方式1
- TH1 = 0xD8; //10ms
- TL1 = 0xF0;
- EA = 1; //打开总中断
- // ET1 = 1;TR1 = 1; //打开定时器1中断//启动定时器1
- count=countset;
- while(1)
- {
- if((state==0)||(state==3))
- {
- if(K1==0)
- {
- Delay10ms();
- if(K1==0)
- {
- state=3;
- countset++;
- if(countset>9)
- countset=1;
- while(K1==0);
- }
- }
- if(K2==0)
- {
- state=0;
- count=countset;
- }
- }
- // if(state==2)
- {
- if(K3==0)
- {
- ET1 = 0;TR1 = 0;
- state=0;
- count=countset;
- sec=0;
- Time=0;
- }
- }
- Display();
- DigDisplay();
- }
- }
- /*******************************************************************************
- * 函 数 名 : DigDisplay
- * 函数功能 : 使用数码管显示
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void DigDisplay()
- {
- unsigned char i;
- unsigned int j;
- for(i=0;i<8;i++)
- {
- switch(7-i) //位选,选择点亮的数码管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- GPIO_DIG=DisplayData[i];//发送段码
- j=100; //扫描间隔时间设定
- while(j--);
- GPIO_DIG=0x00;//消隐
- }
- }
- void Delay10ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void Int0() interrupt 0 //外部中断0的中断函数
- {
- if(state==1)
- {
- count--;
- if(count<=0)
- {
- state=2;
- ET1 = 0;TR1 = 0;
- }
- }
- if(state==0)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
赛车跑道自动触发计时系统_程序&仿真.zip
(106.99 KB, 下载次数: 43)
|