欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机

程序员文章站 2022-06-08 20:46:24
...

蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机

题目如下:
蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机
蓝桥杯单片机学习过程记录(二十九)第八届国赛超声波测距机
已完成
应用的内容:
EEPROM、
定时器、数码管
led灯,独立按键
DA电压输出
超声波测距

/*
-----------------------------
第八届国赛超声波测距机
2020.3.22
DA输出电压未测量
*/
#include<stc15f2k60s2.h>
#include<intrins.h>
#include<iic.h>
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
sbit TX=P1^0;
sbit RX=P1^1;
sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
bit flag_1000,flag_200,flag_led1;
unsigned char eep[4];
unsigned char seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6,0x8e};
unsigned char yi,er,san,si,wu,liu,qi,ba;
unsigned char flag_yemian;
unsigned char count_wave=1,AD_read,count_eep,count_led1;
unsigned int distance,distance_last,distance_set,t_0,count_0;
void delayms(int ms);
void dislpay_12(yi,er);
void dislpay_34(san,si);
void dislpay_56(wu,liu);
void dislpay_78(qi,ba);
void allinit();
void send_wave();
unsigned char rect_wave();
void Timer0Init(void);
void Timer1Init(void);
void key_scan();
void DA_write(unsigned char dat);
unsigned char eeprom_read(unsigned char add);
void eeprom_write(unsigned char add,unsigned char dat);
void distance_write();
//主函数
void main(){
	allinit();
	Timer0Init();Timer1Init();
	EA=1;ET0=1;
	distance_set=eeprom_read(0x06);
	while(1){
		//测距显示界面
		if(flag_yemian==0){
			yi=12;er=11;san=distance/100;si=distance%100/10;wu=distance%10;liu=distance_last/100;qi=distance_last%100/10;ba=distance_last%10;
		}
		//数据回显界面
		else if(flag_yemian==1){
			eep[0]=eeprom_read(0x01);eep[1]=eeprom_read(0x02);
			eep[2]=eeprom_read(0x03);eep[3]=eeprom_read(0x04);
			yi=count_wave;er=11;san=11;si=11;wu=11;liu=eep[count_wave-1]/100;qi=eep[count_wave-1]%100/10;ba=eep[count_wave-1]%10;
		}
		//参数设置界面
		else if(flag_yemian==2){
			yi=13;er=11;san=11;si=11;wu=11;liu=11;qi=distance_set%100/10;ba=distance_set%10;
		}
		key_scan();
		dislpay_12(yi,er);
		dislpay_34(san,si);
		dislpay_56(wu,liu);
		dislpay_78(qi,ba);
	}
}	
//按键
void key_scan(){
	//s7控制调整
	if(s7==0){
		delayms(5);
		if(s7==0){
			//若为数据显示
			if(flag_yemian==1){
				count_wave++;
				if(count_wave==5)
					count_wave=1;
			}
			//若为盲区设置
			else if(flag_yemian==2){
				distance_set=distance_set+10;
				if(distance_set>30)
					distance_set=distance_set-30;
			}
		}
		while(!s7);
	}
	//s6控制盲区显示
	else if(s6==0){
		delayms(5);
		if(s6==0){
			//再次按下退出并保存
			if(flag_yemian==2){
				P2=0X80;P0=0XFF;
				flag_yemian=0;
				eeprom_write(0x06,distance_set);delayms(5);
				distance_set=eeprom_read(0x06);
			}
			else {
				flag_yemian=2;
				P2=0X80;P0=0XBF;
			}
		}
		while(!s6);
	}
	//s5控制测距显示
	else if(s5==0){
		delayms(5);
		if(s5==0){
			if(flag_yemian==1){
				flag_yemian=0;
				P2=0X80;P0=0XFF;
			}
			else{
				flag_yemian=1;
				P2=0X80;P0=0X7F;
			}
		}
		while(!s5);
	}
	//s4控制超声波测距
	else if(s4==0){
		delayms(5);
		if(s4==0){
			flag_yemian=0;
			distance=rect_wave();
			distance_write();
			count_eep++;
			flag_led1=1;count_led1=0;
			if(count_eep==4) count_eep=0;
			//进行盲区判断
			if(distance<distance_set)
				DA_write(0x00);
			else if((distance-distance_set)>250)
				DA_write(0xff);
			else 
				DA_write(distance-distance_set);
			
		}
		while(!s4);
	}
}
//超声波距离写入与读取
void distance_write(){
	if(count_eep==0){
		eeprom_write(0x01,distance);delayms(5);
		distance=eeprom_read(0x01);
		distance_last=eeprom_read(0x04);
	}
	else if(count_eep==1){
		eeprom_write(0x02,distance);delayms(5);
		distance=eeprom_read(0x02);
		distance_last=eeprom_read(0x01);
	}
	else if(count_eep==2){
		eeprom_write(0x03,distance);delayms(5);
		distance=eeprom_read(0x03);
		distance_last=eeprom_read(0x02);
	}
	else if(count_eep==3){
		eeprom_write(0x04,distance);delayms(5);
		distance=eeprom_read(0x04);
		distance_last=eeprom_read(0x03);
	}
}
//eeprom读取
unsigned char eeprom_read(unsigned char add){
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	return temp;
}
//eep写入
void eeprom_write(unsigned char add,unsigned char dat){
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//DA输出电压
void DA_write(unsigned char dat){
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//超声波发送,拉高40us
void send_wave(){
	unsigned char i=8;
	while(i--){
		TX=1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		TX=0;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	}
}
//超声波接收
unsigned char rect_wave(){
	unsigned int temp;
	//发送
	send_wave();
	TR1=1;
	//接收,接收到或溢出
	while((RX==1)&&(TF1==0));
	TR1=0;
	//如果溢出
	if(TF1==1){
		TF1=0;
		temp=999;
	}
	//如果接收到信号
	else {
		temp=TH1;
		temp=(temp<<8)|TL1;
		TH1=0;TL1=0;
		temp=(unsigned int)(temp*0.017/12);
	}
	return temp;
}
//定时器0计时200ms
void time0() interrupt 1{
	t_0++;
	if(t_0==100){
		t_0=0;
		count_0++;
		flag_200=!flag_200;
	}
	if(count_0==5){
		count_0=0;
		flag_1000=!flag_1000;
		count_led1++;
		if(count_led1==7){
			flag_led1=0;
			count_led1=0;
		}
		if(flag_led1==1){
			if(flag_1000==0){
				P2=0X80;P0=0XFE;
			}
			else {
				P2=0X80;P0=0XFF;
			}
		}
	}
}
//定时器0定时2毫秒
void Timer0Init(void)	
{
	AUXR |= 0x80;	
	TMOD &= 0xF0;
	TL0 = 0x9A;
	TH0 = 0xA9;
	TF0 = 0;
	TR0 = 1;
}
//定时器1用于超声波接收计时
void Timer1Init(void)	
{
	AUXR |= 0x40;
	TMOD &= 0x0F;	
	TL1 = 0;
	TH1 = 0;
}
//延时
void delayms(int ms){
	int q,w;
	for(q=0;q<ms;q++)
		for(w=0;w<845;w++);
}
//数码管
void dislpay_12(yi,er){
	P2=0XC0;P0=0X01;P2=0XE0;P0=seg[yi];delayms(1);
	P2=0XC0;P0=0X02;P2=0XE0;P0=seg[er];delayms(1);
}
void dislpay_34(san,si){
	P2=0XC0;P0=0X04;P2=0XE0;P0=seg[san];delayms(1);
	P2=0XC0;P0=0X08;P2=0XE0;P0=seg[si];delayms(1);
}
void dislpay_56(wu,liu){
	P2=0XC0;P0=0X10;P2=0XE0;P0=seg[wu];delayms(1);
	P2=0XC0;P0=0X20;P2=0XE0;P0=seg[liu];delayms(1);
}
void dislpay_78(qi,ba){
	P2=0XC0;P0=0X40;P2=0XE0;P0=seg[qi];delayms(1);
	P2=0XC0;P0=0X80;P2=0XE0;P0=seg[ba];delayms(1);
	P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;delayms(1);
}
//初始化
void allinit(){
	P2=0XA0;P0=0X00;
	P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
	P2=0X80;P0=0XFF;
}
相关标签: 单片机