蓝桥杯13届单片机省赛超声波 手撸程序


题目和完整程序  !!!!

13届.zip - 蓝奏云

一、函数声明

#include <STC15F2K60S2.H>
#include <IIC.H>
#include <intrins.H>

#define u8 unsigned char
#define u16 unsigned int

sbit TX=P1^0;
sbit RX=P1^1;                //超声波

sbit S7=P3^0; sbit L1=P0^0;  //LED位变量 和 按键位变量
sbit S6=P3^1; sbit L2=P0^1;
sbit S5=P3^2; sbit L3=P0^2;
sbit S4=P3^3; sbit L8=P0^7;



u16 distance;       //超声波距离
u8 SMG_mode;        //数码管模式 
u8 Rparm=45;        //上限参数
u8 Dparm=5;					//下限参数
u8 F_setwave;       //超声波启动标志位
code u8 tab1[10] =      //没有小数点的段码
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
};
code u8 tab2[10] =   //有小数点的段码
{
0x40, //0
0x79, //1
0x24, //2
0x30, //3
0x19, //4
0x12, //5
0x02, //6
0x78, //7
0x00, //8
0x10, //9带点
};

三、数据读取函数


//============================数据读取函数===================================
u16 ReadADC()     //电压读取
{
  u16 val;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();
	I2CStop();
	I2CStart();
  I2CSendByte(0x91);
	I2CWaitAck();
	val=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	val=5.0/255*100*val;
	return val;    //返回值  电压放大100倍,方便处理
}
void setDA(float digtal)  //DA转换
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();	
	I2CSendByte(digtal);
	I2CWaitAck();	
	I2CSendAck(1);
	I2CStop();	
}


void Sendwave()  //发送方波信号
{
	u8 i;
	for(i=0;i<8;i++)
	{
		TX=1;
		Delay14us();
		TX=0;
		Delay14us();	
	}	
}
void setwave()      //超声波测距
{
   u16 time;
	AUXR &= 0xBF;	   //定时器1模式0,16位,最大85535个计数脉冲
	TMOD &= 0x0F;	
	TL1 = 0x00;		
	Sendwave();      //发送超声波信号
	TR1 = 1;				 //启动定时器	
	while((RX==1)&&(TF1==0));    //等待超声波信号返回或者等到测量超出范围
	TR1=0;  				 //停止定时器	
	if(TF1==0)       //正常测量范围,根据定时器溢出标志位来判断是否有效		           
	{
		time=TH1;
		time=(time<<8)| TL1;
		distance =(time*17/1000 )  + 3;    //(time/2/1000 000 * 340 ) *100 + 3
	}                                    //单位cm
	else          //超出测量范围
	{
		TF1 = 0;
		distance = 99;
	}

}

三、初始化函数


//============================初始化函数===================================
void Delay1ms()		//@12.000MHz
{
	u8 i, j;

	i = 22;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}
void Delay14us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 39;
	while (--i);
}

 
void SMGbit(u8 pos,u8 val)   //数码管位选
{
	P2=(P2 &0x1f) |0xc0;
	P0=(1<<pos);
	P2=(P2 &0x1f) |0xe0;
	P0=val;
	Delay1ms();
	P2=(P2 &0x1f) |0xc0;
	P0=0xff;
	P2=(P2 &0x1f) |0xe0;
	P0=0xff;		
}

void IintSystem()           //系统初始化
{
  P2=(P2 &0x1f) |0x40;
	P0=0xff;
	P2=(P2 &0x1f) |0xa0;
	P0=0x00;
	P2=(P2 &0x1f) |0xc0;
	P0=0xff;
	P2=(P2 &0x1f) |0xe0;
	P0=0xff;	
}

四、数码管显示模块

//============================数码管显示模块===================================
void setSMG()
{
	switch(SMG_mode)
	{
		case 0:	    //上电显示电压
	  SMGbit(0,0xc1);
		SMGbit(1,0xff);
		SMGbit(2,0xff);
		SMGbit(3,0xff);
		SMGbit(4,0xff);
		SMGbit(5,tab2[ReadADC()/100]);
		SMGbit(6,tab1[ReadADC()/10%10]);
		SMGbit(7,tab1[ReadADC()%10]);  break;
		case 1:	   //参数界面
	  SMGbit(0,0x8c);
		SMGbit(1,0xff);
		SMGbit(2,0xff);
		SMGbit(3,tab2[Rparm/10]); //上限参数
		SMGbit(4,tab1[Rparm%10]);
		
		SMGbit(5,0xff);
		SMGbit(6,tab2[Dparm/10]);//下限参数
		SMGbit(7,tab1[Dparm%10]);  break;
		case 2:	  //超声波界面
		if((Dparm*10 <ReadADC()) &&( ReadADC()< Rparm*10 )  )//电压放大了100倍,电压放大了10倍
		{F_setwave=1; setwave();}  //电压输出是否大于下限参数小于上限参数
		else  	F_setwave=0;      // 超声波启动标志位位置1,且开始测量距离
	  SMGbit(0,0xc3);
		SMGbit(1,0xff);
		SMGbit(2,0xff);
		SMGbit(3,0xff);
		SMGbit(4,0xff);
		if(F_setwave)      //启动了测量
		{
		SMGbit(5,0xff);
		SMGbit(6,tab1[distance/10%10]);
		SMGbit(7,tab1[distance%10]);  
		}
		else              //没有启动测量
		{
		SMGbit(5,0x88);
		SMGbit(6,0x88);
		SMGbit(7,0x88);  
		}
		break;
  }	
}

五、按键控制模块


//============================按键控制模块===================================
u8 S4sta;  //S4状态机位
u8 S5sta;  //S5状态机位
u8 S5flag; //S5标志位

void Scankey()
{
if(S4==0) {   //切换界面
	setSMG();
	if(S4==0)  {
	 switch(S4sta)   
	 {
		 case 0 :SMG_mode=2; S4sta=1; break;
		 case 1 :SMG_mode=1; S4sta=2; break; 
		 case 2 :SMG_mode=0; S4sta=0; break;
	 }
	 while(S4==0) setSMG(); 
	}  }
if(S5==0) {    //选择上限参数还是下限参数
	
	setSMG();
	if(S5==0)  {
	 switch(S5sta)
	 {
		 case 0 : S5flag=1; S5sta=1; break;
		 case 1 : S5flag=0; S5sta=0; break; 
	 }
	 while(S5==0) setSMG();  
	}  }
if(S6==0) {   //对选择的上/下限参数,进行加
	setSMG();
	if(S6==0)  {
	 switch(S5flag)
	 { 						//限制最大值不超过5V,或者回到0.5V
		 case 0 :   if(Rparm>=50) Rparm=5;else Rparm +=5;   break;
		 case 1 :  if(Dparm>=50) Dparm=5; else Dparm +=5;  break; 
	 }
	 while(S6==0) setSMG(); 
	}  }
	if(S7==0) { //对选择的上/下限参数,进行减
	setSMG();
	if(S7==0)  {
	 switch(S5flag)
	 {            //限制最大值不低于0.5V,或者回到5V
		 case 0 : if(Rparm<=5)  Rparm=50;else  Rparm -=5;  break;
		 case 1 :  if(Dparm<=5)  Dparm=50;else  Dparm -=5; break; 
	 }
	 while(S7==0) setSMG(); 
	}  }
	
}

六、LED控制模块

//============================led控制模块===================================
u8  L8shineflag;
u8  cont;                                             
void Timer0Init(void)		//50毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xB0;		//设置定时初值
	TH0 = 0x3C;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1; ET0=1;
}

void Timer0Service(void) interrupt 1 //L8专属
{
	cont++;
	if(cont==2)
	{
	cont=0;
  L8shineflag=~ L8shineflag;  //L8每隔0.1闪亮标志位
	}
}
void led()
{
	if(F_setwave)  //超声波启动标志位
	{
		if(L8shineflag) {  //L8每隔0.1闪亮标志位
		P2=(P2&0x1f)|0x80;
  	L8=0;  }
	
	}
	else  {
   P2=(P2&0x1f)|0x80;  //没启动则熄灭
   L8=1; }	
		
	if(SMG_mode==0){   //电压界面
	P2=(P2&0x1f)|0x80;
	L1=0;
	}
	
	else if(SMG_mode==2) {//超声波界面
	P2=(P2&0x1f)|0x80;
	L2=0; 

	}
	
	
	else if(SMG_mode==1){//参数界面
	P2=(P2&0x1f)|0x80;
	L3=0; 

  }
	
		else   //取消位选
	{
		P2 = (P2 & 0x1f);
	}
	
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值