蓝桥杯STC基础代码-超声波与频率测量

上一章-蓝桥杯STC基础代码-EEPROM和数模转换

文章地址

超声波

简介

这里是引用

板子超声波是以 P10-发送端 P11-接收端
通过控制 发送端 ,我们制造40khz占空比为 50 的超声波。
这个过程其实就是P10在高低电平不断的切来切去。

sbit tx = P1^0;
sbit rx = P1^1;

#define  somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
	u8 i ;
	
	
	for(i = 0 ; i< 8 ;i ++)
	{
		tx = 1;
		somenop;somenop;somenop;somenop;
		tx = 0;
		somenop;somenop;somenop;somenop;
	}

具体过程如上,可以记住是拉高后停止40个 NOP 然后拉低再停止 40个NOP
循环八次是为了加强超声波。

超声波的计时

在这里我是用定时器0,配置过程比较简单,可以直接在STC-ISP找到

这里是引用

void ulr_TIM0_Init(void)
{
	AUXR |= 0x80;	
	TMOD &= 0xF0;		
	TL0 = 0;		
	TH0 = 0;		
	TF0 = 0;		
	TR0 = 0;			

	ET0 = 0;   //关闭中断 可加可不加
}

使用超声波流程

Created with Raphaël 2.2.0 初始化定时器 制造40khz超声波 定时器数值清0 ,开启定时器 等待接收端接收到超声波或者定时器溢出 是否正常 计算结果 结束 yes no

超声波代码

sbit tx = P1^0;
sbit rx = P1^1;

#define  somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}

void ulr_TIM0_Init(void)
{
	AUXR |= 0x80;		
	TMOD &= 0xF0;		
	TL0 = 0;		
	TH0 = 0;		
	TF0 = 0;	
	TR0 = 0;	

	ET0 = 0;
}

float distance;

void Get_ulr_distance(void)
{
	u8 i ;
	
	for(i = 0 ; i< 8 ;i ++)
	{
		tx = 1;
		somenop;somenop;somenop;somenop;
		tx = 0;
		somenop;somenop;somenop;somenop;
	}
	TL0 = 0;
	TH0 = 0;
	TR0 = 1;
	
	while((rx == 1) &&( TF0 == 0))
	{
		
	}
	TR0 = 0;
	
	if(TF0)
	{
		TF0 = 0;
		distance = 255;
	}
	
	else
	{
		distance = ( (TH0 <<8 ) | TL0 ) * 0.00153; //cm
	}
	
	
}

定时器初始化放在系统初始化里面
获取超声波函数可以放在100ms时间轴里面,最好不要太快。

乘0.00153的原因:
定时器每走满一次 即 走了 65536次则大约是 1/168.5s
(TH0 <<8 ) | TL0 是定时器的值

(TH0 <<8 ) | TL0 / 65536 = T / 1/168.5s
得到时间T为 (TH0 <<8 ) | TL0 / (65536 * 168.5 )
声的传播速度340 ,一来一回我们算的是距离的两倍。
所以距离为 (TH0 <<8 ) | TL0 * 340 * T /2 = 0.00153 cm

频率测量

简介

频率测量可以看成是1s内有多少个脉冲,所以我们只要配置定时器为计数模式,然后计算1秒内有多少个脉冲,在这里我们还要考虑定时器计数会溢出的问题,所以我们就要利用到定时器中断了。
我的代码是用定时器0,跟上面的超声波一样,但是如果有些题两个都要用到的话,那也可以改成定时器1。

定时器的初始化

我们也可以利用烧录器的代码
不过要记得加上把定时器配置成计数器模式

void FRE_TIM0_Init(void)
{
	AUXR |= 0x80;;		  //12T
	TMOD &= 0xF0;	   
	TMOD |= 0x04;		   
	TL0 = 0x00;		
	TH0 = 0x00;	
	TF0 = 0;	
	
	ET0 = 1;   
	
	TR0 = 1;		
}

u16 fre_cnt;
void TIM0_interrupt(void) interrupt 1
{
	fre_cnt ++;
}

这里我用fre_cnt存储计数器溢出的次数。

频率计算

频率计算比较简单,把溢出的次数65536 加上现在计数器的次数,就等于总的次数了,溢出的次数乘65536的原因是每次溢出都是已经计数了65536*

u16 tim1_fre;

void  Get_fre(void)
{
	TR0 = 0;
	tim1_fre =( TH0 << 8 ) | TL0 + fre_cnt * 65536;
	TL0 = 0x00;		
	TH0 = 0x00;		
	fre_cnt = 0;	
	TR0 = 1;
}

这个函数一定要放在 1s时间轴里 。

总代码

void FRE_TIM0_Init(void)
{
	AUXR |= 0x80;;		  //12T
	TMOD &= 0xF0;	   
	TMOD |= 0x04;		    //
	TL0 = 0x00;		
	TH0 = 0x00;	
	TF0 = 0;	
	
	ET0 = 1;   //¿ªÆôÖжÏ
	
	TR0 = 1;		
}

u16 fre_cnt;
void TIM0_interrupt(void) interrupt 1
{
	fre_cnt ++;
}

u16 tim1_fre;

void  Get_fre(void)
{
	TR0 = 0;
	tim1_fre =( TH0 << 8 ) | TL0 + fre_cnt * 65536;
	TL0 = 0x00;		
	TH0 = 0x00;		
	fre_cnt = 0;	
	TR0 = 1;
}

关于基础的代码到这就完结了,谢谢关注

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值