//Ultrasonic wave Module 超声波模块
//#include <avr/io.h>
//#include <util/delay.h>
//#include <avr/interrupt.h>
#include "ATmega128_HC-SR04.h"
#include "taskfun.h"
#include "timer.h"
#include "led.h"
#include "cc1000.h"
#include "spi.h"
#include "adc.h"
#include "io.h"
//#include "ds18b20.h"
#include "delay.h"
#include "usart.h"
#include "atmega128.h"
#include <string.h>
#include <stdio.h>
//#include "led.h"
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
//#pragma interrupt_handler External_INT_4:6
//#define USWTrig_H PORTE |= (1 << PE4) //触发脚输出高电平
//#define USWTrig_L PORTE &= ~(1 << PE4) //触发脚输出低电平
//#define TRIG PORTE.4
//#define ECHO PORTE.3
//***********************************************
//sbit Trig = PE^4; //产生脉冲引脚
//sbit Echo = PE^3; //回波引脚
//sbit test = P1^1; //测试用引脚
volatile uint USWDist; //测距接收缓冲区
volatile uchar ge_data, shi_data, bai_data, qian_data,wan_data;
volatile uint ICData[2] = {0, 0}; //记录每次输入捕捉上升沿及下降沿的捕捉时间
volatile uchar SucceedFlag, ICFlag, OVFNum, RevFailFlag; //测量成功标志、捕获次数标志、定时器1溢出次数标志、接收失败标志
volatile uint USW_C,outcomeH,outcomeL; //超声波的速度
//volatile uint DS18B20_Temp; //空气的温度,用来校正超声波的速度的
void SR04_configure(void)
{
set_io_dir(PORT_TRIG, PIN_TRIG, IO_DIRECTION_OUT);
set_io_dir(PORT_ECHO, PIN_ECHO, IO_DIRECTION_IN);
// set_io_dir(LED_PORT_GREEN, LED_PIN_GREEN, IO_DIRECTION_OUT);
//set_io_dir(LED_PORT_YELLOW, LED_PIN_YELLOW, IO_DIRECTION_OUT);
}
void TRIG_H(void)
{
set_io_level(PORT_TRIG, PIN_TRIG, IO_LEVEL_HIGH);
}
void TRIG_L(void)
{
set_io_level(PORT_TRIG, PIN_TRIG, IO_LEVEL_LOW);
}
void ECHO_H(void)
{
set_io_level(PORT_ECHO, PIN_ECHO, IO_LEVEL_HIGH);
}
void ECHO_L(void)
{
set_io_level(PORT_ECHO, PIN_ECHO, IO_LEVEL_LOW);
}
/*************************************************************************
*
超声波模块初始化
*
说明:PD4为输入捕获引脚,PD5是输出触发电平引脚
*************************************************************************/
void InitUSW(void)
{
//PORTE|= (1 << PE3); //将输入捕捉引脚启用上拉电阻
//PORTE&= ~(1 << PE4); //将超声波触发引脚输出低电平,这个要比方向先设置
ECHO_H();
TRIG_L();
DDRE |= (1 << PE3); //将超声波触发引脚设置为输出模式
DDRE &= ~(1 << PE4); //将输入捕捉引脚设置为输入模式
TCCR1A = 0x00;
TCNT1 = 0; //定时器1计数清零
TCCR1B = (1 << ICNC1)|(1 << ICES1)|(1 << CS10); //开启减噪器,上升沿触发,1分频
TIMSK = (1 << TICIE1)|(1 << TOIE1); //开启输入捕捉,定时器溢出中断
sei(); //开启全局中断
}
void INT_initialize(void)
{
cli();//EICRA = 0xaa; //fall edge trigger
//SREG|=(1<<I);
EICRB|=(1<<ISC41)|(1<<ISC40); //no influence
EIMSK|=(1<<INT4);
//EIFR|=(1<<INT4);
sei();
//SEI();
}
/*************************************************************************
*
禁止超声波模块
*
*************************************************************************/
void StopUSW(void)
{
TCCR1B &= ~(1 << CS10); //关闭输入时钟
TIMSK &= ~((1 << TICIE1)|(1 << TOIE1)); //关闭输入捕捉,定时器溢出中断
}
/*************************************************************************
*
函数名: GetUSWDist
*
说明:通过超声波模块获取距离数据
*
返回值:unsigned int,表示距离,单位毫米(mm)
*
*************************************************************************/
void GetUSWDist()
{
//SucceedFlag=1;
volatile uint i;
InitUSW();
USWDist = 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微秒
//
// TCCR1B = (1 << ICNC1)|(1 << ICES1)|(1 << CS10); //开启减噪器,上升沿触发,1分频
// TIMSK = (1 << TICIE1)|(1 << TOIE1); //开启输入捕捉,定时器溢出中断
// TCNT1 = 0; //定时器1计数清零,要附上该语句,否则可能造成数据出错
//InitUSW();
INT_initialize();
OVFNum = 0;
ICFlag = 0;
RevFailFlag = 0;
//while(1)
TRIG_H();
udelay(15); //输出一个持续时间超过10us的触发电平
TRIG_L();
InitUSW();
// TCNT1 = 0x00;
// led_on(LED_R);
//led_toggle(LED_R, 1000);
//while(!SucceedFlag && !RevFailFlag) ; //等待接收完成
// while(0)
while(SucceedFlag==0);
// usart_sendbyte(USWDist ,USART1);
SucceedFlag = 0; //清测量成功标志
RevFailFlag = 0;
TCCR1B = 0x00; //关闭定时器
TIMSK = 0x00; //关闭输入捕捉,定时器溢出中断
if(RevFailFlag) //如果接收超时
{
//led_on(LED_R);
}
else
{
//ICData[1]=0xA391;
//ICData[0]=0x0298;
USW_C = 332;
// 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微秒
USWDist = (unsigned int)((((unsigned long)65536 * (unsigned long)OVFNum
+ (unsigned long)TCNT1) *(unsigned long)USW_C / 2
/ (unsigned long)1000 )>> 4); //转换成1微秒
USWDist=USWDist/58;
conversion(USWDist);
//usart_sendbuff(UART1_Tab, strlen(UART1_Tab), USART1);
//led_on(LED_R);
usart_sendbyte(USWDist ,USART1);
}
//微秒的单位除以58等于厘米
//为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58 */
mdelay(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);
//led_on(LED_R);
//return DistData;
}
/***************************************************************************
*
输入捕捉中断,用于捕捉上升沿及下降沿时的定时器时间,来获取某电平持续时间
*
*****************************************************************************/
/*void __attribute((signal)) __vector_11(void) //输入捕捉中断服务程序
{
led_off(LED_R);
ICData[ICFlag] = ICR1; //记录捕捉寄存器时间
if(ICFlag)
{
SucceedFlag = 1; //至成功测量的标志
TCCR1B |= (1 << ICES1); //切换到上升沿触发
}
else
{
SucceedFlag = 0;
TCCR1B &= ~(1 << ICES1); //切换到下降沿触发
}
ICFlag = !ICFlag;
}*/
void __attribute((signal)) __vector_5(void)
{ //led_on(LED_R);
// TCCR1B = 0x00;
// led_toggle(LED_R, 3000);
SucceedFlag = 0;
ICData[0] = TCNT1;
//ICData[ICFlag] = TCNT1; //记录捕捉寄存器时间
if(ICFlag)
{ // led_on(LED_R);
SucceedFlag = 1; //至成功测量的标志
EICRB|=(1<<ISC40)|(1<<ISC41); //切换到上升沿触发
}
else
{ led_toggle(LED_R, 3000);
// TCCR1B = 0x00;
//TCCR1B &= ~(1 << CS10);
SucceedFlag = 0;
// EIMSK &= ~(1 << INT4);
// EICRB|=(1<<ISC41); //切换到下降沿触发
// EIFR &= ~(1 << INT4);
// EIMSK|=(1<<INT4);
}
ICFlag = !ICFlag;
}
/***************************************************************************
*
定时器1溢出中断,用于记录定时器1的溢出次数
*
*****************************************************************************/
void __attribute((signal)) __vector_14(void)
{ // led_off(LED_R);
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)
{
// wan_data = temp_data / 10000 ;
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';
}
}
|