//Ultrasonic wave Module 超声波模块
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "ATmega128_HC-SR04.h"
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
//***********************************************
//sbit Trig = P1^0; //产生脉冲引脚
//sbit Echo = P3^2; //回波引脚
//sbit test = P1^1; //测试用引脚
volatile uint USWDist[FILTER_N]; //测距接收缓冲区
volatile uchar ge_data, shi_data, bai_data, qian_data;
volatile uint ICData[2] = {0, 0}; //记录每次输入捕捉上升沿及下降沿的捕捉时间
volatile uchar SucceedFlag, ICFlag, OVFNum, RevFailFlag; //测量成功标志、捕获次数标志、定时器1溢出次数标志、接收失败标志
volatile uint USW_C; //超声波的速度
volatile uint DS18B20_Temp; //空气的温度,用来校正超声波的速度的
/*************************************************************************
*
超声波模块初始化
*
说明:PD4为输入捕获引脚,PD5是输出触发电平引脚
*************************************************************************/
void InitUSW(void)
{
DDRD &= ~(1 << PD4); //将输入捕捉引脚设置为输入模式
PORTD &= ~(1 << PD5); //将超声波触发引脚输出低电平,这个要必方向先设置
DDRD |= (1 << PD5); //将超声波触发引脚设置为输出模式
PORTD |= (1 << PD4); //将输入捕捉引脚启用上拉电阻
TCCR1A = 0x00;
TCNT1 = 0; //定时器1计数清零
TCCR1B = (1 << ICNC1)|(1 << ICES1)|(1 << CS10); //开启减噪器,上升沿触发,1分频
TIMSK = (1 << TICIE1)|(1 << TOIE1); //开启输入捕捉,定时器溢出中断
sei(); //开启全局中断
}
/*************************************************************************
*
禁止超声波模块
*
*************************************************************************/
void StopUSW(void)
{
TCCR1B &= ~(1 << CS10); //关闭输入时钟
TIMSK &= ~((1 << TICIE1)|(1 << TOIE1)); //关闭输入捕捉,定时器溢出中断
}
/*************************************************************************
*
函数名: GetUSWDist
*
说明:通过超声波模块获取距离数据
*
返回值:unsigned int,表示距离,单位毫米(mm)
*
*************************************************************************/
uint GetUSWDist(void)
{
volatile uint DistData, i;
InitUSW();
for(i = 0; i < FILTER_N; i++) //距离数据暂存器清零
USWDist[i] = 0;
// ICData[1] = 65535;
// ICData[0] = 0;
// USWDist[0] = (unsigned int)((((unsigned long)65536 * (unsigned long)OVFNum
// + (unsigned long)ICData[1] - (unsigned long)ICData[0]) *(unsigned long)172 / (unsigned long)1000 )>> 4); //转换成1微秒
for(i = 0; i < FILTER_N; i++)
{
// TCCR1B = (1 << ICNC1)|(1 << ICES1)|(1 << CS10); //开启减噪器,上升沿触发,1分频
// TIMSK = (1 << TICIE1)|(1 << TOIE1); //开启输入捕捉,定时器溢出中断
// TCNT1 = 0; //定时器1计数清零,要附上该语句,否则可能造成数据出错
InitUSW();
OVFNum = 0;
ICFlag = 0;
RevFailFlag = 0;
USWTrig_H;
_delay_us(15);
USWTrig_L; //输出一个持续时间超过10us的触发电平
while(!SucceedFlag && !RevFailFlag); //等待接收完成
SucceedFlag = 0; //清测量成功标志
RevFailFlag = 0;
TCCR1B = 0x00; //关闭定时器
TIMSK = 0x00; //关闭输入捕捉,定时器溢出中断
if(RevFailFlag) //如果接收超时
{
//
}
else
{
DS18B20_Temp = ReadTemperature(); //从DS18B20获取温度
USW_C = (unsigned int)((float)332 + (float)0.0607 * (float)DS18B20_Temp);
USWDist[i] = (unsigned int)((((unsigned long)65536 * (unsigned long)OVFNum
+ (unsigned long)ICData[1] - (unsigned long)ICData[0]) *(unsigned long)USW_C / 2
/ (unsigned long)1000 )>> 4); //转换成1微秒
}
//微秒的单位除以58等于厘米
//为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
_delay_ms(60);
}
StopUSW();
// DistData = (unsigned int)((unsigned long)((unsigned long)USWDist[0] + (unsigned long)USWDist[1] + (unsigned long)USWDist[2]
// + (unsigned long)USWDist[3])/4);
DistData = MedianFilter(USWDist);
return DistData;
}
/***************************************************************************
*
输入捕捉中断,用于捕捉上升沿及下降沿时的定时器时间,来获取某电平持续时间
*
*****************************************************************************/
ISR(TIMER1_CAPT_vect) //输入捕捉中断服务程序
{
ICData[ICFlag] = ICR1; //记录捕捉寄存器时间
if(ICFlag)
{
SucceedFlag = 1; //至成功测量的标志
TCCR1B |= (1 << ICES1); //切换到上升沿触发
}
else
{
SucceedFlag = 0;
TCCR1B &= ~(1 << ICES1); //切换到下降沿触发
}
ICFlag = !ICFlag;
}
/***************************************************************************
*
定时器1溢出中断,用于记录定时器1的溢出次数
*
*****************************************************************************/
ISR(TIMER1_OVF_vect)
{
if(!SucceedFlag)
++OVFNum;
else
OVFNum = 0;
if(OVFNum > 13) //13次 表示超声波接收超时
RevFailFlag = 1;
}
/***************************************************************************
*
显示数据转换程序
*
*****************************************************************************/
void conversion(uint temp_data)
{
//temp_data = USWDist[3];
if(temp_data <60000)
{
qian_data = temp_data / 1000 ;
bai_data = (temp_data % 1000) /100;
shi_data = (temp_data % 100) / 10 ;
ge_data = temp_data % 10;
UART1_Tab[0] = qian_data + '0';
UART1_Tab[1] = bai_data + '0';
UART1_Tab[2] = shi_data + '0';
UART1_Tab[3] = ge_data + '0';
}
else
{
UART1_Tab[0] = 'F';
UART1_Tab[1] = 'F';
UART1_Tab[2] = 'F';
UART1_Tab[3] = 'F';
}
}
unsigned int MedianFilter(unsigned int * value_buf)
{
volatile unsigned char i,j;
volatile unsigned int temp;
for (j=0; j< FILTER_N-1; j++)
{
for (i=0; i<FILTER_N-j-1; i++)
{
if ( value_buf[i] > value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(FILTER_N-1)/2];
}
ATmega128_HC-SR04.rar_ATMEGA SR04_atmega16 sr04_hc sr04 gcc_hc-s
版权申诉
32 浏览量
2022-09-24
03:40:19
上传
评论
收藏 3KB RAR 举报
weixin_42653672
- 粉丝: 93
- 资源: 1万+
最新资源
- HM2305B-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 基于52单片机、ADC0832、LCD1602、两个74HC393和一个74HC08的频率测量计 不能用,请私我
- HM2302-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- python实战项目-学生成绩管理系统(基础版)
- 微信小程序源码 实现查公交 滴滴公交 app 源码下载
- HM2302E-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 基于C#图片相似度比较,感知哈希算法
- VR开发的概要介绍与分析
- 自动驾驶定位系列教程七:点云畸变补偿.pdf
- HM2302D-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0