Quantcast
Channel: MSP 低功耗微控制器论坛 - 最近的话题
Viewing all articles
Browse latest Browse all 3634

使用MSP430F5529实现超声波测距的时候中断死循环如何解决?

$
0
0

如题,在Init_cap函数过后会直接进入中断且TBIV的值一直是12

测距模块输入是P3.5+P3.6

#include <msp430f5529.h>
#include "cap.h"
#include "delay.h"


#define FILTER_NUM 2

unsigned char choice=0;
//char table[30];
unsigned long channel[2];//存放时间
unsigned long channel_count[4]={0};//存放计数值
unsigned char channel_flag[2]={0};
unsigned char yichu_flag=0;//溢出标志
float distance[3];
float distance_temp1;
float distance_temp2;
float ArrDataBuffer[2][FILTER_NUM];//行表示3个通道,列表示需要滤波的次数
/************************************/
#define Trig_H_1  P3OUT|=BIT7                //端口P3.7输出高电平
#define Trig_L_1  P3OUT&=~BIT7              //端口P3.7输出低电平

#define Trig_H_2  P8OUT|=BIT2                //端口P8.2输出高电平
#define Trig_L_2  P8OUT&=~BIT2              //端口P8.2输出低电平


/**************变量定义****************/
unsigned char flag=1;
long time;
/****************************************/
void XT1_init(void)
{
    P5SEL |= BIT4+BIT5; //配置为XT1功能,电路板上晶振接于这两脚
    UCSCTL6 |= XCAP_3; //配置电容为12pF
    UCSCTL6 &= ~XT1OFF; //使能XT1
    while(SFRIFG1&OFIFG)//如果有时钟错误
    {
        UCSCTL7&=~(XT2OFFG+DCOFFG+XT1LFOFFG);//清除3种时钟错误标志
        SFRIFG1&=~OFIFG;//清除时钟错误标志位
    }
    UCSCTL4&=UCSCTL4&~(SELS_7+SELM_7) + SELS_0 + SELM_0;//将SMCLK和MCLK时钟源配置为XT1
}

/*******************************************
函数名称:void init_dvice(void)
函数功能:超声波模块初始化
入口参数:无
返回值:无
*******************************************/
void Init_cap(void)
{
    P3DIR|=BIT7;                    //输出方向(用来产生大于10us的脉冲)
    P8DIR|=BIT2;
    Trig_L_1;
    Trig_L_2;

    P3DIR&=~(BIT5+BIT6);                    //P3.5-3.6的管脚为输入
    P3SEL|=(BIT5+BIT6);                      //CCI0B输入
    TB0CTL=TBSSEL_2+TBCLR+ID_3+MC_2;    //MCLK,清除TAR,八分频,连续计数模式
                                 //工作在捕捉模式,捕获/比较中断使能
    TB0CCTL5 |= CM_1 + SCS + CAP + CCIE + CCIS_1;//捕获模式,同步捕获,中断打开,上降沿捕获
    TB0CCTL6 |= CM_1 + SCS + CAP + CCIE + CCIS_1;//捕获模式,同步捕获,中断打开,上降沿捕获
    _EINT();                       //使能GIE(总中断)
 }
/*******************************************
函数名称:void start(void)
函数功能:超声波开始信号,产生10us的脉冲
入口参数:无
返回值:无
*******************************************/
void start_1(void)
{
    Trig_L_1;
    delay_us(20);
    Trig_H_1;
    delay_us(20);
    Trig_L_1;
}
void start_2(void)
{
    Trig_L_2;
    delay_us(20);
    Trig_H_2;
    delay_us(20);
    Trig_L_2;
}

/*******************************************
函数名称:void count_distance(void)
函数功能:计算距离
入口参数:无
返回值:无
*******************************************/
float count_distance( unsigned long ti1)
{
    float dista;
    dista = ti1*0.000173;
    return dista;
}

void ULTRASONIC(void)
{
     if(choice==0)
     start_1();   //
     if(channel_flag[0]==1)//通道1捕获完成
     {
        channel_flag[0]=0;
        if(channel_count[1]>channel_count[0])
        channel[0]=channel_count[1]-channel_count[0];
        else
        {
            channel[0]=65535-channel_count[0]+channel_count[1];
            yichu_flag=0;
        }
        distance_temp1=count_distance(channel[0]);
    }
    if(choice==1)
    start_2();
    if(channel_flag[1]==1)//通道2捕获完成
    {
        channel_flag[1]=0;
        if(channel_count[3]>channel_count[2])
        channel[1]=channel_count[3]-channel_count[2];
        else
        {
            channel[1]=65535-channel_count[2]+channel_count[3];
            yichu_flag=0;
        }
        distance_temp2=count_distance(channel[1]);
    }
    delay_ms(1);    
    choice++;   
    if(choice>=2)choice=0;
}
   

void MiddleValueFilter(void)
{
    unsigned char i,j,k;
    float temp;
    unsigned char channel_num;
    for(i=0;i<FILTER_NUM;i++)           //一次采集N个数据放入数组中
    {
        ULTRASONIC();
        ArrDataBuffer[0][i] = distance_temp1;
        ArrDataBuffer[1][i] = distance_temp2;
    }
    for(channel_num=0;channel_num<2;channel_num++)
    {
        for(j=0;j<FILTER_NUM-1;j++)//采样值由小到大排列
            {
                for(k=0;k<FILTER_NUM-j-1;k++)
                {
                    if(ArrDataBuffer[channel_num][k]>ArrDataBuffer[channel_num][k+1])
                        {
                            temp=ArrDataBuffer[channel_num][k];
                            ArrDataBuffer[channel_num][k]=ArrDataBuffer[channel_num][k+1];
                            ArrDataBuffer[channel_num][k+1]=temp;
                        }
                }
            }
    distance[channel_num] = ArrDataBuffer[channel_num][(FILTER_NUM-1)/2];//取中间值
    }
}

#pragma vector = TIMERB1_VECTOR 
__interrupt void timera1_vec() 
{ 

    switch(TBIV)
    {
    case 10:
        if(TBCCTL5 & CM_1)//上升沿
        {
            TBCCTL5 = (TBCCTL5 & (~CM_1) | CM_2);//改成下降沿
            channel_count[0]=TBCCR5;
            TBCCTL5 &= ~CCIFG;//清除中断标志
        }
        else //下降沿
        {
            TBCCTL5 = (TBCCTL5 &(~CM_2) | CM_1);//改成上升沿
            channel_count[1]=TBCCR5;
            channel_flag[0]=1;
            TBCCTL5 &= ~CCIFG;//清除中断标志
        }
        break;
    case 12:
        if(TBCCTL6 & CM_1)//上升沿
        {
            TBCCTL6 = (TBCCTL6 & (~CM_1) | CM_2);//改成下降沿
            channel_count[2]=TBCCR6;
            TBCCTL6 &= ~CCIFG;//清除中断标志
        }
        else //下降沿
        {
            TBCCTL6 = (TBCCTL6 &(~CM_2) | CM_1);//改成下降沿
            channel_count[3]=TBCCR6;
            channel_flag[1]=1;
            TBCCTL6 &= ~CCIFG;//清除中断标志
        }
        break;
    case 14:
    	yichu_flag++;break;
    default:
    	break;
    }
}




Viewing all articles
Browse latest Browse all 3634

Trending Articles