蓝桥杯单片机超声波测距

考超声波实际上就是考定时器,关于信号的传输与接收如何实现的硬件知识我们不需要掌握,首先来了解一下定时器;

跳线帽短接2,4  1,3,选用定时器1,采用12T模式

比赛设置的频率为12MHZ,12T模式相当于对1T模式进行计数,即计数器每计数一次,时间过去了1*10^-6S,即1us

首先我们来理一下顺序,first,发送脉冲信号,开始计数;second,接收到脉冲信号(假设在可测距范围内),停止计数;

完成这两部后,我们得到了一个计数值;

该计数值,设为count,也就是脉冲信号在所测距离里传播两次所需的时间t,根据音速v=340m/s,vt/2也就是所测距离。

整理如下:

发送脉冲,开始计数,接收脉冲,停止计数,计数值count,distance=(count/(10^6)*(3.4*(10^2)))/2,简化为count*1.7/10000,受限于数据类型的问题,我们可以改成count/100*17/100/10

开始进入敲代码环节:

#include <STC15F2K60S2.H>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit Tx=P1^0;
sbit Rx=P1^1;
float dis=0;
u8 dv=0;
u8 flag_csb=0;
u8 flag_display=0;
u8 a[8]={10,10,10,10,10,10,10,10};
void ctrl(u8 ctrl)
{
   u8 p2data=P2;
	 P2=ctrl<<5|(P2&0x1f);
	 P2=p2data&0x1f;

}

void get(u8 a0,u8 a1,u8 a2,u8 a3,u8 a4,u8 a5,u8 a6,u8 a7)
{
   a[0]=a0;a[1]=a1;a[2]=a2;a[3]=a3;a[4]=a4;a[5]=a5;a[6]=a6;a[7]=a7;
	
}

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	i = 3;
	while (--i);

}

void csb(void)
{
	u8 i;
	AUXR &= 0x7F;
	TMOD &= 0xF0;			
	TMOD |= 0x01;
	TL0=0X00;
	TH0=0X00;
	
  for(i=0;i<8;i++)
	{
	Tx=1;
	Delay12us();
	Tx=0;
	Delay12us();
	}
	TR0=1;
	while(Rx&&!TF0);
	TR0=0;
	if(TF0)
	{
	TF0=0;
	dis=0;
	dv=255;
	
	}
	else
	{
	dis=(TH0*256+TL0)*0.017;
	dv=(int)dis;
	}
	TL0=0X00;
  TH0=0X00;
	
}



void display(u8 site,u8 light)
{
	P0=0xff;
	ctrl(7);
	P0=0x01<<site;
	ctrl(6);
	switch(light%20)
	{
		case 0:P0=0xc0;break;
		case 1:P0=0xf9;break;
		case 2:P0=0xa4;break;
		case 3:P0=0xb0;break;
		case 4:P0=0x99;break;
		case 5:P0=0x92;break;
		case 6:P0=0x82;break;
		case 7:P0=0xf8;break;
		case 8:P0=0x80;break;
		case 9:P0=0x90;break;
		case 10:P0=0xff;break;
		default:break;
	}
	if(light>=20)P0=P0&0x7f;
  ctrl(7);



}
void Timer2_Init(void)		//1??@12.000MHz
{
	AUXR &= 0xFB;			//?????12T??
	T2L = 0x18;				//???????
	T2H = 0xFC;				//???????
	AUXR |= 0x10;			//???2????
	IE2|=0x04;
	EA=1;
}

void main()
{
  P0=0x00;ctrl(5);
	P0=0xff;ctrl(4);
	Timer2_Init();
	while(1)
	{
	 if(flag_csb>200){flag_csb=0;csb();}
	 get(10,10,10,10,10,dv/100,dv%100/10,dv%10);  
	
	}

}
void t2isr(void)  interrupt 12
{
  flag_csb++;
	flag_display++;
	flag_display=flag_display%8;
  display(flag_display,a[flag_display]);
  

}

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
超声波测距中,我们通常会使用定时器来计时,以便在一定时间内测量超声波的往返时间。如果定时器溢出,就会导致测距的准确性下降,同时也会影响数码管的闪动效果。下面是一些代码示范,用于解决定时器溢出的问题并实现数码管的闪动效果。 首先,我们需要设置一个定时器,并在定时器中断中进行计数和处理。例如,我们可以使用定时器0,并设置其为8位自动重载模式,以便在计数到255时自动重新计数。 ``` void init_timer0() { // 设置定时器0为8位自动重载模式 T0CON = 0b00000100; // 设置定时器0计数初值为0 TMR0 = 0; // 开启定时器0中断 INTCONbits.T0IE = 1; // 设置定时器0中断优先级为高 INTCONbits.PEIE = 1; INTCONbits.GIE = 1; } ``` 然后,在定时器中断中,我们需要进行计数和处理。例如,我们可以在每次定时器中断时将计数器加1,并检查是否已经溢出。如果已经溢出,则重新计数,并在此时更新数码管的显示值,以实现闪动效果。 ``` void interrupt isr() { // 定时器0中断 if (INTCONbits.T0IF) { // 清除定时器0中断标志 INTCONbits.T0IF = 0; // 将计数器加1 count++; // 如果计数器已经溢出 if (count == 0) { // 重新计数 TMR0 = 0; // 更新数码管的显示值 display_num(); } } } ``` 最后,我们需要实现数码管的显示函数,用于在定时器溢出时更新数码管的显示值。例如,我们可以使用一个全局变量来保存当前需要显示的数值,并在每次更新时将其转换为数码管的显示格式。 ``` void display_num() { // 将当前需要显示的数值转换为数码管的显示格式 int num = convert_num(display_value); // 在数码管上显示该数值 show_num(num); } ``` 注意,这些代码示范仅供参考,具体的实现方式可能因使用的单片机和外设而有所不同。在实际应用中,还需要根据具体的需求和场景进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值