打印
[AVR单片机]

128超声波测距求助

[复制链接]
1203|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ddeann|  楼主 | 2015-5-21 11:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//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';

        }


}


相关帖子

沙发
ddeann|  楼主 | 2015-5-21 11:23 | 只看该作者
有没有哪位大神帮我看看哪里有问题,现在while(SucceedFlag==0);那一步就进不去了,谢谢大家,我急着要用

使用特权

评论回复
板凳
luofeng2g| | 2015-5-21 11:24 | 只看该作者
不说问题,发大段代码!没人会帮你看的。。。。

使用特权

评论回复
地板
ddeann|  楼主 | 2015-5-21 11:28 | 只看该作者
luofeng2g 发表于 2015-5-21 11:24
不说问题,发大段代码!没人会帮你看的。。。。

你好,谢谢你,我这个就是中断那部分有问题,我现在在串口收不到数据,你可以帮我看看吗,谢谢了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

9

帖子

0

粉丝