51单片机超声波程序植入msp430F149单片机,求助!!!

2019-07-26 15:06发布

//超声波模块显示程序
#include "include.h"
#define uchar unsigned char //定义一下方便使用
#define uint  unsigned int
#define ulong unsigned long
#define CLR_Tx P1OUT&=~BIT5;    //sbit Tx  = P1^5; 产生脉冲引脚,低
#define SET_Tx P1OUT|=BIT5;      //高
//#define CLR_Rx P2OUT&=~BIT2;    sbit Rx  = P2^2; 回波引脚,捕获上升沿,0
//#define SET_Rx P2OUT|=BIT2;     
uchar *s1 = "CHAO SHENG BO";
uchar *s2 = "juli:";
unsigned char digit[ ]={"0123456789"}; //定义字符数组显示数字
uint distance[4];  //测距接收缓冲区
uchar ge,shi,bai,temp,flag,outcome,i;  //自定义寄存器
uint succeed_flag;  //测量成功标志
void conversion(uint temp_data);
void delay_20us();
void pai_xu();
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j;       
         for(i=0;i<10;i++)
          for(j=0;j<33;j++)
           ;                 
}
void csb(void)   // 主程序
{  uint distance_data,a,b;
   uchar CONT_1;
          P2DIR = 0x01;                   //设置P2.0,1方向为输出
    P2OUT = 0x01;
  uchar k;   //定义变量i指向字符串数组元素
     LcdReset();         //调用LCD初始化函数  
   delay(10);             //延时10ms,给硬件一点反应时间
   DispStr(1,0,s1);   // 从第1行第3列开始显示
   flag=0;
        CLR_Tx;       //首先拉低脉冲输入引脚
         TACTL = TASSEL_1  + MC_1; //定时器A的时钟源选择ACLK,增计数模式
         TACCTL0 = CCIE;                   //使能CCR0中断
         TACCR0 = 134 ;                    //65.535s进入中断
         _EINT();                        //使能全局中断 GIE
while(1)         //程序循环
        {
                  DispStr(1,1,s2);   // 从第2行第3列开始显示
                   LcdWriteData(digit[bai]);  //将万位数字的字符常量写入LCD
                   LcdWriteData(digit[shi]);  //将千位数字的字符常量写入LCD
                   LcdWriteData('.');  //将万位数字的字符常量写入LCD
                   LcdWriteData(digit[ge]);  //将百位数字的字符常量写入LCD
                   LcdWriteData(' ');  //将百位数字的字符常量写入LCD
                   LcdWriteData('C');  //将万位数字的字符常量写入LCD
                   LcdWriteData('M');  //将万位数字的字符常量写入LCD
        SET_Tx ;//P1.5引脚就是L5灯,置1=点亮L5
        delay_20us();
        CLR_Tx;        //产生一个超过10us的脉冲,在Tx引脚  
        while((P2IN & BIT2)==0); //等待Rx回波引脚变高电平,Rx为0一直执行空语句
             succeed_flag=0; //清测量成功标志
        TACTL=TACLR;
        TACCTL0 = CM_2 + SCS + CAP + CCIE+CCIS_0;//捕获模式,同步捕获,中断打开,下降沿捕获
        _EINT();//开总中断
        while(CCR0<134)
          TACCTL0|= CCIE+CCIFG;      //关闭外部中断
        if(succeed_flag==1)
          {        
                  
           distance_data=(outcome*344/(1024*2*2*58));                   //微秒的单位除以58等于厘米
          }                                      //为什么除以58等于厘米,  Y米=(X秒*344)/2
                                                               // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
    if(succeed_flag==0)
                   {
            distance_data=0;                    //没有回波则清零

                   }

           distance[i]=distance_data; //将测量结果的数据放入缓冲区
            i++;
                     if(i==3)
                       {
                         distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
            pai_xu();
             distance_data=distance[1];     
           a=distance_data;
       if(b==a) CONT_1=0;
       if(b!=a) CONT_1++;
       if(CONT_1>=3)
                   { CONT_1=0;
                          b=a;
                          conversion(b);
                        }      
                           i=0;
                          }          
        }
}
//外部中断0,用做判断回波电平
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{   
     outcome=CCR0;    //取出定时器的值
     succeed_flag=1;   //至成功测量的标志
      TACCTL0|= CCIE+CCIFG;      //关闭外部中断
     P2OUT ^= 0x01;
  }
//显示数据转换程序
void conversion(uint temp_data)  
{  
    uchar ge_data,shi_data,bai_data ;
    bai_data=temp_data/100 ;
    temp_data=temp_data%100;   //取余运算
    shi_data=temp_data/10 ;
    temp_data=temp_data%10;   //取余运算
    ge_data=temp_data;
    bai = bai_data;
    shi = shi_data;
    ge  = ge_data ;
       
}
void delay_20us()
{  uchar bt ;
    for(bt=0;bt<60;bt++);
}
   void pai_xu()
  {  uint t;
  if (distance[0]>distance[1])
    {t=distance[0];distance[0]=distance[1];distance[1]=t;}
  if(distance[0]>distance[2])
    {t=distance[2];distance[2]=distance[0];distance[0]=t;}
  if(distance[1]>distance[2])
    {t=distance[1];distance[1]=distance[2];distance[2]=t;}  
  }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
飞肥飞飛
1楼-- · 2019-07-26 20:41
上面的是我自己编的430单片机的程序,数码管显示无误,触发信号也有,但是就是不能提取距离的时间。
下面的是51的主程序+外部中断:
void main(void)   // 主程序
{  uint distance_data,a,b;
   uchar CONT_1;  
  uchar k;   //定义变量i指向字符串数组元素
    LcdInitiate();         //调用LCD初始化函数  
   delay(10);             //延时10ms,给硬件一点反应时间
   WriteAddress(0x01);   // 从第1行第3列开始显示
   k = 0;               //指向字符数组的第1个元素
        while(string[k] != '')
                {                                       
                        WriteData(string[k]);
                        k++;             //指向下字符数组一个元素                               
                }         
   i=0;

   flag=0;
        Tx=0;       //首先拉低脉冲输入引脚
        TMOD=0x10;    //定时器1,16位工作方式
//        TR0=1;             //启动定时器0
   IT0=0;        //由高电平变低电平,触发外部中断,外部中断0触发
        //ET0=1;        //打开定时器0中断
        EX0=0;        //关闭外部中断,禁止外部中断0中断
        EA=1;         //打开总中断
  
       
while(1)         //程序循环
        {
         WriteAddress(0x41);    // 从第2行第6列开始显示
                WriteData('J');  //将万位数字的字符常量写入LCD
                         WriteData('U');  //将万位数字的字符常量写入LCD
                          WriteData('L');  //将万位数字的字符常量写入LCD
                           WriteData('I');  //将万位数字的字符常量写入LCD
                            WriteData(':');  //将万位数字的字符常量写入LCD
                  WriteData(digit[bai]);  //将万位数字的字符常量写入LCD
                  WriteData(digit[shi]);  //将千位数字的字符常量写入LCD
                  WriteData('.');  //将万位数字的字符常量写入LCD
                  WriteData(digit[ge]);  //将百位数字的字符常量写入LCD
                  WriteData(' ');  //将百位数字的字符常量写入LCD
                  WriteData('C');  //将万位数字的字符常量写入LCD
                  WriteData('M');  //将万位数字的字符常量写入LCD
  EA=0;        //禁止所有的中断请求
             Tx=1;         //P1.5引脚就是L5灯,置1=点亮L5
        delay_20us();
        Tx=0;         //产生一个超过10us的脉冲,在Tx引脚  
        while(Rx==0); //等待Rx回波引脚变高电平,Rx为0一直执行空语句
             succeed_flag=0; //清测量成功标志
             EX0=1;          //打开外部中断
                   TH1=0;          //定时器1清零
        TL1=0;          //定时器1清零
             TF1=0;          //定时器T1溢出标志位
        TR1=1;          //启动定时器1
   EA=1;                           //开总中断

      while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)  
                  TR1=0;          //关闭定时器1
        EX0=0;          //关闭外部中断

    if(succeed_flag==1)
             {        
                   distance_data=outcomeH;                //测量结果的高8位
           distance_data<<=8;                   //放入16位的高8位
                     distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
            distance_data*=12;                  //因为定时器默认为12分频
           distance_data/=58;                   //微秒的单位除以58等于厘米
         }                                      //为什么除以58等于厘米,  Y米=(X秒*344)/2
                                                               // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
    if(succeed_flag==0)
                   {
            distance_data=0;                    //没有回波则清零

           }

           distance[i]=distance_data; //将测量结果的数据放入缓冲区
            i++;
                     if(i==3)
                       {
                         distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
            pai_xu();
             distance_data=distance[1];     
           a=distance_data;
       if(b==a) CONT_1=0;
       if(b!=a) CONT_1++;
       if(CONT_1>=3)
                   { CONT_1=0;
                          b=a;
                          conversion(b);
                        }      
                           i=0;
                          }             
         }
}
//***************************************************************
//外部中断0,用做判断回波电平
INTO_()  interrupt 0   // 外部中断是0号
{   
     outcomeH =TH1;    //取出定时器的值
     outcomeL =TL1;    //取出定时器的值
     succeed_flag=1;   //至成功测量的标志
     EX0=0;            //关闭外部中断
  }
dirtwillfly
2楼-- · 2019-07-26 22:38
 精彩回答 2  元偷偷看……
dirtwillfly
3楼-- · 2019-07-26 23:03
定时器A在增计数模式下TA0CCR0比较特殊,不作为比较捕获作用,可以用TA0CCR1或者TA0CCR2
尤彼卡
4楼-- · 2019-07-27 03:10
楼主现在是什么情况,调出来了吗
可可球
5楼-- · 2019-07-27 05:49
定时器A在增计数模式下TA0CCR0比较特殊,不作为比较捕获作用

赞同

一周热门 更多>