蓝桥杯单片机——超声波补充
18号晚写的代码一觉起来又不能跑了,让我倍感疑惑,在经历了重重崩溃后发现了问题,
超声波模块所需要的发射周期是40khz,也就是周期需为25us,而代码里面的延时为12us*2,在经过多次实验后发现,也许是18号晚上的单片机晶振频率刚好契合
12us的延时函数,所以让发射的频率趋近于40khz所以测量距离可以测得很远,
因为第八届的超声波需要单次测量,所以延时不准的问题体现的很严重,运气好可以测量距离有40cm,运气不好测量结果就会一直卡在6cm,因为以前做的题目都是循环测量的,
所以数据看起来没有什么大问题,但放在单次测量就十分要命了,所以我使用下载软件生成了一个12us的函数和1us的函数,并将1us的函数对半砍,接近于0.5us,测试下来结果十分稳定
在这里记录下来,以免后面忘记。附上代码
`#include <STC15F2K60S2.H>
#include "intrins.h"
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int
bit caozuo=0;
sbit s4=P3^3;
sbit s5=P3^2;
sbit s6=P3^1;
sbit s7=P3^0;
sbit na1=P1^0;
sbit nb1=P1^1;
uchar maduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
uchar key_value;
uchar prc=0,smg_prc=0;
uint chao_time,rond;
uint now_rond,since_rond[10]={0},sum_rond,rond_cnt=0;
uint t1_cnt=0;
void delay_us(uint t)
{
t*=12;
while(t--);
}
void Delay12us() //@12.000MHz
{
unsigned char data i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void Delay0_5us() //@12.000MHz
{
_nop_();
_nop_();
}
void hc138(uchar x,y)
{
switch(x)
{
case 4:P2&=0x1f;P2|=0x80;
break;
case 5:P2&=0x1f;P2|=0xa0;
break;
case 6:P2&=0x1f;P2|=0xc0;
break;
case 7:P2&=0x1f;P2|=0xe0;
break;
}
P0=y;
}
void show_num(uchar x,num,d)
{
hc138(6,0x01<<x);
if(d){hc138(7,maduan[num]|0x7f);}
else {hc138(7,maduan[num]);}
delay_us(100);
hc138(7,0xff);
}
void smg_flash(uchar x)
{
switch(x)
{
case 0://测距显示界面
show_num(0,caozuo,0);
show_num(1,16,0);
show_num(2,sum_rond/100,0);
show_num(3,sum_rond/10%10,0);
show_num(4,sum_rond%10,0);
show_num(5,now_rond/100,0);
show_num(6,now_rond/10%10,0);
show_num(7,now_rond%10,0);
break;
case 1://数据回显界面
show_num(0,0,0);
show_num(1,rond_cnt+1,0);
show_num(2,16,0);
show_num(3,16,0);
show_num(4,16,0);
show_num(5,since_rond[rond_cnt]/100,0);
show_num(6,since_rond[rond_cnt]/10%10,0);
show_num(7,since_rond[rond_cnt]%10,0);
break;
case 2://参数设置界面
show_num(0,15,0);
show_num(1,1,0);
show_num(2,1,0);
show_num(3,1,0);
show_num(4,1,0);
show_num(5,1,0);
show_num(6,1,0);
show_num(7,1,0);
break;
}
}
uchar key_scanf()
{
uchar rec=0;
if(s4==0){smg_flash(smg_prc);if(s4==0){while(s4==0){smg_flash(smg_prc);}rec=4;}}
if(s5==0){smg_flash(smg_prc);if(s5==0){while(s5==0){smg_flash(smg_prc);}rec=5;}}
if(s6==0){smg_flash(smg_prc);if(s6==0){while(s6==0){smg_flash(smg_prc);}rec=6;}}
if(s7==0){smg_flash(smg_prc);if(s7==0){while(s7==0){smg_flash(smg_prc);}rec=7;}}
return rec;
}
void Timer0_Init(void) //10微秒@12.000MHz
{
AUXR &= ~0x40; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
}
void chao_init()
{
uchar i;
for(i=0;i<8;i++)
{
na1=1;
Delay12us();
Delay0_5us();
na1=0;
Delay12us();
Delay0_5us();
}
}
uint get_chao()
{
uint time=0;
/*
TMOD &= 0xf0; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x00; //设置定时初值
*/
Timer0_Init();
chao_init();
TR0=1;
while(nb1&&TF0==0);
TR0=0;
if(TF0==0)
{
time=TH0<<8|TL0;
return (uint)(time*0.017);
}
else
{
TF0=0;
time=0;
return time;
}
}
/*
void Timer0_Init(void) //10微秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
}
void chao_init()
{
uchar i;
for(i=0;i<8;i++)
{
na1=1;
Delay12us();
na1=0;
Delay12us();
}
}
uint get_chao()
{
uint time=0; //计算变量,通过return返回出去
TMOD &= 0xf0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时初值
chao_init(); //发送八个40k的方波
TR0=1; //迅速开启定时器
while(nb1&&TF0==0); //当NB1等于0时或者TF标志位中断时推出while循环
TR0=0; //关闭定时器
if(TF0==0) //如果未溢出则判定值有效
{
time=TH0<<8|TL0; //将定时器值高八位和低八位赋值给time
return time*0.017; //测试发现无论定时器以1t还是12t的频率下都是乘与0.017
}
else
{
TF0=0; //如果中断标志位超出,则清空中断标志位
time=0;
return time;
}
}
uint get_chao()
{
uint time=0;
/*
TMOD &= 0xf0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时初值
Timer0_Init();
chao_init();
TR0=1;
while(nb1&&TF0==0);
TR0=0;
if(TF0==0)
{
time=TH0<<8|TL0;
return (uint)(time*0.017);
}
else
{
TF0=0;
time=0;
return time;
}
}
*/
void sys_init()
{
hc138(4,0xff);
hc138(5,0x00);
hc138(6,0x00);
hc138(7,0x00);
}
void main()
{
//Timer1Init();
sys_init();
EA=1;
while(1)
{
key_value=key_scanf();
smg_flash(smg_prc);
switch(prc)
{
case 0:
if(key_value==4)
{
if(!caozuo){sum_rond=now_rond;}
else{sum_rond+=now_rond;}
now_rond=get_chao();
if(rond_cnt<10){rond_cnt++;}
else{rond_cnt=0;}
since_rond[rond_cnt]=now_rond;
}
if(key_value==7)
{
caozuo=~caozuo;
}
if(key_value==5)
{
prc=1;
smg_prc=1;
}
break;
case 1:
if(key_value==7)
{
if(rond_cnt<10)
{
rond_cnt++;
}
else
{
rond_cnt=0;
}
}
if(key_value==5)
{
prc=0;
smg_prc=0;
}
break;
}
}
}
`

浙公网安备 33010602011771号