void send_wave() { c_send = 1; //10us的高电平触发 delay(); c_send = 0; TH0 = 0; //给定时器0清零 TL0 = 0; TR0 = 0; //关定时器0定时 while(!c_recive); //当c_recive为零时等待 TR0=1; while(c_recive) //当c_recive为1计数并等待 { flag_time0 = TH0 * 256 + TL0; if((flag_time0 > 40000)) //当超声波超过测量范围时,显示3个888 { TR0 = 0; flag_csb_juli = 2; distance = 888; break ; } else { flag_csb_juli = 1; } } if(flag_csb_juli == 1) { TR0=0; //关定时器0定时 distance =flag_time0; //读出定时器0的时间 distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米 if((distance > 500)) //距离 = 速度 * 时间 { distance = 888; //如果大于3.8m就超出超声波的量程 } } }请详细解释以上程序
时间: 2024-04-09 08:32:35 浏览: 14
以上程序是一个发送超声波信号并接收回波的函数。函数的作用是测量超声波的传输时间,并计算出距离。
函数的具体步骤如下:
1. 将发送引脚c_send置高电平,触发超声波的发送。发送持续10微秒。
2. 将发送引脚c_send置低电平。
3. 清零定时器0的计数值,准备开始计时。
4. 关闭定时器0。
5. 当接收引脚c_recive为0时,等待。
6. 打开定时器0,开始计时。
7. 当接收引脚c_recive为1时,进行计数并等待。
8. 读取定时器0的计数值,保存在变量flag_time0中。该值表示超声波传输的时间。
9. 如果flag_time0大于40000(超过测量范围),则表示超声波信号超出了测量范围,将距离distance设为888,并跳出循环。
10. 如果flag_time0在测量范围内,则将flag_csb_juli设为1。
11. 如果flag_csb_juli为1,则关闭定时器0。
12. 将distance赋值为flag_time0乘以0.017,得到距离的单位是米。这里的0.017是通过声速340米/秒除以2得到的。
13. 如果距离大于500米,则将distance设为888,表示超出了超声波的量程。
以上就是该函数的具体实现。它通过测量超声波传输时间来计算距离,并考虑了超声波的测量范围和量程。
相关问题
请详细解释以下程序void send_wave() { c_send = 1; //10us的高电平触发 delay(); c_send = 0; TH0 = 0; //给定时器0清零 TL0 = 0; TR0 = 0; //关定时器0定时 while(!c_recive); //当c_recive为零时等待 TR0=1; while(c_recive) //当c_recive为1计数并等待 { flag_time0 = TH0 * 256 + TL0; if((flag_time0 > 40000)) //当超声波超过测量范围时,显示3个888 { TR0 = 0; flag_csb_juli = 2; distance = 888; break ; } else { flag_csb_juli = 1; } } if(flag_csb_juli == 1) { TR0=0; //关定时器0定时 distance =flag_time0; //读出定时器0的时间 distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米 if((distance > 500)) //距离 = 速度 * 时间 { distance = 888; //如果大于3.8m就超出超声波的量程 } } }
这段程序是一个函数定义,函数名为"send_wave",返回类型为void,即没有返回值。
程序的主要功能是发送超声波信号,并接收反射回来的信号,并计算出距离。
具体解释如下:
1. `c_send = 1;` 设置c_send为1,产生一个高电平触发超声波信号。
2. `delay();` 延时一段时间,这里可能是为了确保超声波信号发送完成。
3. `c_send = 0;` 将c_send设置为0,停止发送超声波信号。
4. `TH0 = 0;` 给定时器0的高字节TH0清零。
5. `TL0 = 0;` 给定时器0的低字节TL0清零。
6. `TR0 = 0;` 关闭定时器0,停止计时。
7. `while(!c_recive);` 当c_recive为0时,等待。
8. `TR0=1;` 打开定时器0,开始计时。
9. `while(c_recive)` 当c_recive为1时,继续执行循环。这里可能是在等待接收到超声波反射回来的信号。
10. `flag_time0 = TH0 * 256 + TL0;` 将定时器0的值读取到flag_time0变量中。
11. `if((flag_time0 > 40000))` 如果flag_time0大于40000,表示超声波超过了测量范围。
12. `TR0 = 0;` 关闭定时器0。
13. `flag_csb_juli = 2;` 将flag_csb_juli设置为2,表示超出测量范围。
14. `distance = 888;` 将distance设置为888,表示超出测量范围。
15. `break ;` 跳出循环。
16. `else` 如果flag_time0不大于40000,即在测量范围内。
17. `flag_csb_juli = 1;` 将flag_csb_juli设置为1,表示在测量范围内。
18. `TR0=0;` 关闭定时器0。
19. `distance =flag_time0;` 将flag_time0赋值给distance,表示距离的计算结果。
20. `distance *= 0.017;` 将distance乘以0.017,计算出距离,其中0.017是通过速度和时间计算得到的。
21. `if((distance > 500))` 如果distance大于500,表示距离超出了超声波的量程。
22. `distance = 888;` 将distance设置为888,表示超出量程。
23. `}` 结束if语句。
24. `}` 结束while循环。
25. `}` 结束函数定义。
unsigned char ADC0804_Read(void) { unsigned char dat; ADC0804_Port = 0xff; ADC0804_CS = 1; ADC0804_WR = 1; ADC0804_CS = 0; ADC0804_WR = 0; //Delay_xus(100); ADC0804_CS = 1; ADC0804_WR = 1; //Delay_xus(500); ADC0804_CS = 0; ADC0804_RD = 0; //Delay_xus(50); dat = ADC0804_Port; ADC0804_RD = 1; ADC0804_CS = 1; return dat; } unsigned int ADC0804_Convert(void) { unsigned char n; unsigned int sum = 0; unsigned int temp; for(n = 0;n < 3;n++) { sum = sum + ADC0804_Read(); Seg_dis(temp); } temp = sum / 3; //temp = temp * 19.60784; //5/255=0.01960784313 return temp; }将代码注释
```
//定义一个函数,用于从ADC0804模数转换器中读取数据
unsigned char ADC0804_Read(void) {
unsigned char dat; //定义一个8位无符号整型变量dat用于存储读取到的数据
ADC0804_Port = 0xff; //将ADC0804的端口设置为输入状态
ADC0804_CS = 1; //设置片选端口为高电平
ADC0804_WR = 1; //设置写端口为高电平
ADC0804_CS = 0; //设置片选端口为低电平
ADC0804_WR = 0; //设置写端口为低电平
//Delay_xus(100); //延时100微秒
ADC0804_CS = 1; //设置片选端口为高电平
ADC0804_WR = 1; //设置写端口为高电平
//Delay_xus(500); //延时500微秒
ADC0804_CS = 0; //设置片选端口为低电平
ADC0804_RD = 0; //设置读端口为低电平
//Delay_xus(50); //延时50微秒
dat = ADC0804_Port; //将读取到的数据存储到dat中
ADC0804_RD = 1; //设置读端口为高电平
ADC0804_CS = 1; //设置片选端口为高电平
return dat; //返回读取到的数据
}
//定义一个函数,用于将多次读取到的数据进行平均值运算,得到数字量输出
unsigned int ADC0804_Convert(void) {
unsigned char n; //定义一个8位无符号整型变量n,用于循环计数
unsigned int sum = 0; //定义一个16位无符号整型变量sum,用于存储多次读取到的数据的累加和
unsigned int temp; //定义一个16位无符号整型变量temp,用于存储平均值输出
for(n = 0; n < 3; n++) { //进行3次循环,每次读取一次数据
sum = sum + ADC0804_Read(); //调用ADC0804_Read()函数读取数据,并将读取到的数据累加到sum中
Seg_dis(temp); //将temp的值显示在数码管上
}
temp = sum / 3; //将多次读取到的数据的累加和除以3,得到平均值
//temp = temp * 19.60784; //将数字量转换为模拟量输出,但是这行代码被注释掉了
return temp; //返回平均值
}
```