凌阳科技大学计划论坛

首页 » 16位应用专题 » 毕业设计专区 » 高手救命啊:超声波测距可调测距程序怎么写啊
hejialiang2005 - 2008-4-23 19:00:00
我的毕业设计要求测距是10——220cm
但是我例子里面的只有短距和中距
麻烦高手帮我写一个10——20cm的测距程序
各位请给点意见啊
小弟感激不尽。
hejialiang2005 - 2008-4-23 19:01:00
在线等啊,很急。。。
hejialiang2005 - 2008-4-23 20:39:00
运用的是超声波测距模组v2.0
hejialiang2005 - 2008-4-24 22:18:00
是啊,但是我程序不懂啊,它只有短距离和中距离的
我的设计是10——220cm,我不知道哪里修改程序啊
谁能帮帮我啊
Stonech - 2008-4-28 14:36:00
我也需要,我甚至连原程序都没有,楼主能不能把你有的程序发给我?
falconzc - 2008-4-28 17:51:00
我也做超声毕设
hejialiang2005 - 2008-4-29 0:44:00
首先。。。这个测距程序怎么改啊
测距范围变为10-220cm
//========================================================================
//    文件名称:    ultrasonic_App.c
//    功能描述:    超声波测距模组V2.0的功能接口函数
//    维护记录:    2006-02-21    V2.0
//========================================================================
#include "SPCE061A.h"
#define LONG_SEND_TIMER        1000        //中距测距时的40KHz信号发射时长
#define LONG_SEND_TIMER2    3000        //中距测距的补充测距时的40KHz信号发射时长
#define LONG_WAIT_DELAY        600            //中距测距的防余波干扰延时时长
#define LONG_WAIT_DELAY2    1500        //中距测距的补充测距时的防余波干扰延时时长
#define LONG_RES_ADD        0x00B0        //中距测距的结果补偿值
#define LONG_RES_ADD2        0x0220        //中距测距的补充测距时的结果补偿值

#define LOW_SEND_TIMER        250            //短距测距时的40KHz信号发射时长
#define LOW_SEND_TIMER2        1000        //短距测距的补充测距时的40KHz信号发射时长
#define LOW_WAIT_DELAY        180            //短距测距的防余波干扰延时时长
#define LOW_WAIT_DELAY2        400            //短距测距的补充测距时的防余波干扰延时时长
#define LOW_RES_ADD            0x0034        //短距测距的结果补偿值
#define LOW_RES_ADD2        0x00B0        //短距测距的补充测距时的结果补偿值

unsigned int Counter_buf;                //超声波测距当中,用于保存TimerB计数的变量,相当于时长
unsigned int EXT1_IRQ_flag=0;            //外部中断标志变量,用于EXT1的IRQ中断程序和测距程序同步
//========================================================================
//    语法格式:    void Initial_ult(void)
//    实现功能:    超声波测距模组的初始化子程序
//    参数:        无
//    返回值:    无
//========================================================================
void Initial_ult(void)
{
    unsigned int uiTemp;
    //                                    初始化端口主要是IOB8和IOB9
    uiTemp = *P_IOB_Dir;
    uiTemp = uiTemp|0x0200;
    uiTemp = uiTemp&0xfeff;
    *P_IOB_Dir = uiTemp;
    uiTemp = *P_IOB_Attrib;
    uiTemp = uiTemp|0x0200;
    uiTemp = uiTemp&0xfeff;
    *P_IOB_Attrib = uiTemp;
    uiTemp = *P_IOB_Buffer;
    uiTemp = uiTemp|0x0300;
    *P_IOB_Data = uiTemp;
}
//========================================================================
//    语法格式:    void Delay_ult(unsigned int timers)
//    实现功能:    超声波测距模组的延时子程序
//    参数:        unsigned int timers    延时的时长(仅是一个相对量)
//    返回值:    无
//========================================================================
void Delay_ult(unsigned int timers)
{
    unsigned int i;
    for(i=0;i<timers;i++)
    {
        __asm("nop");
    }
}
//========================================================================
//    语法格式:    unsigned int Resoult_ult(unsigned int Counter)
//    实现功能:    超声波测距模组的测距数据处理程序,将TimerB的计数值换算为距离
//    参数:        Counter    需要换算的计数值
//    返回值:    计算后的距离,厘米为单位
//========================================================================
unsigned int Resoult_ult(unsigned int Counter)
{
    unsigned int uiTemp;
    unsigned long ulTemp;
    ulTemp = (unsigned long)Counter*33500;
    ulTemp = ulTemp/196608;
    ulTemp = ulTemp>>1;                    //除二
    uiTemp = (unsigned int)ulTemp;
    return uiTemp;
}
//========================================================================
//    语法格式:    unsigned int measure_ult(unsigned int type)
//    实现功能:    超声波测距模组的测距程序,完成一次测距
//    参数:        type    选择测距类型,
//                type=1        中距测距
//                type=0        短距测距
//    返回值:    所测得的距离,以厘米为单位
//========================================================================
unsigned int measure2_ult(unsigned int type);
unsigned int measure_ult(unsigned int type)
{
    unsigned int Exit_flag = 1;
    unsigned int uiTemp;
    unsigned int uiResoult;
    unsigned int uiSend_Timer,uiWait_Timer,uiRes_Add;
    unsigned int uiSystem_Clock;
    uiSystem_Clock = *P_SystemClock;    //将当前的系统时钟设置暂时保存起来
    *P_SystemClock = 0x0088;            //将系统时钟设置为49MHz,分频比为1,强振模式
    if(type)                            //根据type即测距类型,选择不同的测距参数
    {
        uiSend_Timer = LONG_SEND_TIMER;
        uiWait_Timer = LONG_WAIT_DELAY;
        uiRes_Add = LONG_RES_ADD;
    }
    else
    {
        uiSend_Timer = LOW_SEND_TIMER;
        uiWait_Timer = LOW_WAIT_DELAY;
        uiRes_Add = LOW_RES_ADD;
    }
    *P_TimerB_Data = 0xfed2;
    *P_TimerB_Ctrl = 0x03c0;            //enable 40KHz out
    Delay_ult(uiSend_Timer);            //delay for send the signal
    *P_TimerB_Ctrl = 0x0006;            //stop 40KHz out
    *P_TimerB_Data = 0x0000;
    *P_TimerB_Ctrl = 0x0001;            //TimerB work as a counter at 192KHz
    while(*P_TimerB_Data<uiWait_Timer)    //等待一定时间后再打开TimerA的计数(来源于EXT1)
    {                                    //以避开余波的干扰
        *P_Watchdog_Clear = 0x0001;
    }
    *P_INT_Clear = 0x0100;                    //开中断前先清中断
    *P_INT_Ctrl = *P_INT_Ctrl_New|0x0100;
    *P_INT_Clear = 0xffff;                //清除中断发生标志
    __asm("IRQ ON");                    //打开总中断使能
    EXT1_IRQ_flag = 0;                    //TimerA的溢出中断的标志变量置0
    while(Exit_flag)
    {
        if(EXT1_IRQ_flag==1)            //当该变量在timerA的FIQ中断中被置1时表示接收到了回波
        {
            Exit_flag = 0;                //exit
            Counter_buf = Counter_buf+uiRes_Add;//计数值加上一定的调整数据
            uiResoult = Resoult_ult(Counter_buf);//对计数值进行处理,得出距离值
        }
        if(*P_TimerB_Data>10000)        //如计数值大于10000,表示超时
        {
            Exit_flag = 0;                //exit
            uiResoult = measure2_ult(type);//再进行一次补充的测距,将会加长40KHz信号发射的量
            *P_TimerB_Ctrl = 0x0006;    //stop timerB
        }
        uiTemp = *P_TimerB_Data;
        *P_Watchdog_Clear = 0x0001;
    }
    *P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);    //关掉外部中断
    __asm("IRQ OFF");                    //关掉总中断
   
    *P_SystemClock = uiSystem_Clock;    //恢复系统时钟的设置
    return uiResoult;
}
//========================================================================
//    语法格式:    void EXT1_IRQ_ult(void)
//    实现功能:    超声波测距模组的测距程序的EXT1中断服务程序,在EXT1的IRQ中断
//                中调用
//    参数:        无
//    返回值:    无
//========================================================================
void EXT1_IRQ_ult(void)
{
    Counter_buf = *P_TimerB_Data;        //save the timerB counter
    *P_TimerB_Ctrl = 0x0006;            //stop timerB
    *P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);    //关掉外部中断
    *P_INT_Clear = 0xffff;                //清除中断发生标志
    EXT1_IRQ_flag = 1;                    //通知测距程序,外部中断已发生
}
//========================================================================
//    语法格式:    unsigned int measure2_ult(void)
//    实现功能:    补充进行一次远距的测量,以保证能够获取测量结果
//    参数:        type    选择测距类型,
//                type=1        中距测距
//                type=0        短距测距
//    返回值:    所测得的距离,以厘米为单位
//========================================================================
unsigned int measure2_ult(unsigned int type)
{
    unsigned int Exit_flag = 1;
    unsigned int uiResoult;
    unsigned int uiSend_Timer,uiWait_Timer,uiRes_Add;
    *P_TimerA_Ctrl = 0x0006;            //stop TimerA

    *P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);    //关掉外部中断
    __asm("IRQ OFF");                    //关掉总中断
    *P_INT_Clear = 0xffff;                //清除掉中断发生标志
   
    if(type)                            //根据type即测距类型,选择不同的测距参数
    {
        uiSend_Timer = LONG_SEND_TIMER2;
        uiWait_Timer = LONG_WAIT_DELAY2;
        uiRes_Add = LONG_RES_ADD2;
    }
    else
    {
        uiSend_Timer = LOW_SEND_TIMER2;
        uiWait_Timer = LOW_WAIT_DELAY2;
        uiRes_Add = LOW_RES_ADD2;
    }
    *P_TimerB_Data = 0xfed2;
    *P_TimerB_Ctrl = 0x03c0;            //enable 40KHz out
    Delay_ult(uiSend_Timer);            //delay for send the signal
    *P_TimerB_Ctrl = 0x0006;            //stop 40KHz out
    *P_TimerB_Data = 0x0000;
    *P_TimerB_Ctrl = 0x0001;            //TimerB work as a counter at 192KHz
    while(*P_TimerB_Data<uiWait_Timer)    //等待一定时间,以避开余波的干扰
    {
        *P_Watchdog_Clear = 0x0001;
    }

    *P_INT_Ctrl = *P_INT_Ctrl_New|0x0100;//打开外部中断
    *P_INT_Clear = 0xffff;                //清除中断发生标志
    __asm("IRQ ON");                    //打开总中断使能
   
    EXT1_IRQ_flag = 0;                    //TimerA的溢出中断的标志变量置0
    while(Exit_flag)
    {
        if(EXT1_IRQ_flag==1)            //当该变量在timerA的FIQ中断中被置1时表示接收到了回波
        {
            Exit_flag = 0;                //exit
            Counter_buf = Counter_buf+uiRes_Add;//计数值加上一定的调整数据
            uiResoult = Resoult_ult(Counter_buf);//对计数值进行处理,得出距离值
        }
        if(*P_TimerB_Data>10000)        //如计数值大于10000,表示超时
        {
            Exit_flag = 0;                //exit
            uiResoult = 0;                //error return data 0
            *P_TimerB_Ctrl = 0x0006;    //stop timerB
        }
    }
    return uiResoult;
}
//========================================================================
//    语法格式:    unsigned int measure_Times(unsigned int type)
//    实现功能:    组合进行共6次的测距程序,包括对6次测量结果的取平均值处理
//    参数:        type    选择测距类型,
//                type=1        中距测距
//                type=0        短距测距
//    返回值:    所测得的距离,以厘米为单位
//========================================================================
unsigned int measure_Times(unsigned int type)
{
    unsigned int uiResoult=0,uiMeasure_Index=0,i;
    unsigned int uiTemp_buf[6],uiTemp;
    unsigned int uiSystem_Clock;
   
    for(;uiMeasure_Index<6;uiMeasure_Index++)
    {                                            //循环进行四次测量
        uiTemp = measure_ult(type);                //进行一次测量,测量类型由type决定
        if(uiMeasure_Index==0)                    //如果为本次测量的第一次测距,则直接保存在缓冲区第一个单元
            uiTemp_buf[0] = uiTemp;       
        else
        {                                        //否,则对结果进行比较,进行排序,从大到小排
            i = uiMeasure_Index;
            while(i)                            //以下为排序的代码
            {
                if(uiTemp>uiTemp_buf[i-1])
                {
                    uiTemp_buf[i] = uiTemp_buf[i-1];
                    uiTemp_buf[i-1] = uiTemp;
                }
                else
                {
                    uiTemp_buf[i] = uiTemp;
                    break;                        //退出排序
                }
                i--;
            }
        }
        //两次测量之间的延时等待,利用以下代码软仿真时的cycles数结合设置的CPUCLK进行计算,大概72ms
        uiSystem_Clock = *P_SystemClock;        //将之前的系统时钟的设置用变量保存
        *P_SystemClock = 0x000b;                //设置为FSYS=24.576MHz  分频比为8
        for(i=0;i<5;i++)
        {
            Delay_ult(1000);                        //调用延时程序
            *P_Watchdog_Clear = 0x0001;
        }
        *P_SystemClock = uiSystem_Clock;        //恢复系统时钟设置
        //此处延时结束
    }
    //对6次测距的结果进行处理
    if(uiTemp_buf[5]==0)
    {                                            //如果缓冲区中的最小的测距值为0,则采用中间4个数据进行平均
        uiResoult = uiTemp_buf[1]+uiTemp_buf[2]+uiTemp_buf[3]+uiTemp_buf[4];
        uiResoult = uiResoult/4;
    }
    else
    {                                            //否则就取后5个数据进行平均
        uiResoult = uiTemp_buf[1]+uiTemp_buf[2]+uiTemp_buf[3]+uiTemp_buf[4]+uiTemp_buf[5];
        uiResoult = uiResoult/5;
    }
    return uiResoult;
}
heweiwei - 2008-5-11 9:42:00
ms不改也行
98008033 - 2008-5-11 10:34:00
程序运行时,分别使用不同的TYPE值,进行2次不同距离的测试,
模块上,把跳线冒接到SET,调节电位器,使比较电压处于短距和中距之间
这样试试
angel19861223 - 2008-10-6 15:29:00
你这个程序改了那里啊,没看出改的地方啊?
 1 
查看完整版本: 高手救命啊:超声波测距可调测距程序怎么写啊