打印

430f149超声测距

[复制链接]
996|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
开始吧|  楼主 | 2016-8-24 19:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下是超声测距的程序,大神们能解释一下,其中测距部分的语句么?应该是这部分吧,求解释
//#pragma vector=PORT1_VECTOR
__interrupt void port1_int(void)
  {
    if((P1IN&BIT5)==BIT5)
      {
        TACTL|=MC_1+TACLR;
        P1IES|=BIT5;
      }
    else
      {
        TACTL&=~MC_3;
        P1IES&=~BIT5;
        distance=TAR*5/3;
        //P2OUT=TAR;
      }
        P1IFG&=~BIT5;
}
//



#include "msp430f149.h"
#define uint unsigned int
#define uchar unsigned char
/**************宏定义***************/
#define DataDir     P2DIR
#define DataPort    P2OUT                               
#define Busy            0x80
#define CtrlDir     P6DIR
#define CLR_RS P6OUT&=~BIT3;        //RS = P6.3
#define SET_RS P6OUT|=BIT3;       
#define CLR_RW P6OUT&=~BIT4;        //RW = P6.4
#define SET_RW P6OUT|=BIT4;       
#define CLR_EN P6OUT&=~BIT5;        //EN = P6.5       
#define SET_EN P6OUT|=BIT5;       


//   Trig-->P1.0     Echo-->P1.1    下载时断开P1.1口,下载后在连接P1.1  

void DispStr(unsigned char x,unsigned char y,unsigned char *ptr);
void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr);
void LocateXY(unsigned char x,unsigned char y);
void Disp1Char(unsigned char x,unsigned char y,unsigned char data);
void LcdReset(void);
void LcdWriteCommand(unsigned char cmd,unsigned char chk);
void LcdWriteData( unsigned char data );
void WaitForEnable(void);
void Delay5ms(void);
void timeinit();
void delay(uint y);

long static uint distance;
uchar table[]={"Distance:"};

void main()
{
   WDTCTL = WDTPW + WDTHOLD;
   P1DIR|=BIT4;
   P2DIR=0XFF;
   timeinit();
   LcdReset();
   P1IE=BIT5;
   P1IES&=~BIT5;  //上升沿触发
   DispNChar(0,0, 9,table);
  
   while(1)
   {
      P1OUT|=BIT4;
      delay(1);
      P1OUT&=~BIT4;
     // delay(10);
  
      Disp1Char(2,1,(distance/100000)%10+0x30);
      Disp1Char(3,1,(distance/10000)%10+0x30);
      Disp1Char(4,1,(distance/1000)%10+0x30);
      Disp1Char(5,1,(distance/100)%10+0x30);
      
      Disp1Char(6,1,'.');
      Disp1Char(7,1,(distance/10)%10+0x30);
      Disp1Char(8,1,distance%10+0x30);
      Disp1Char(9,1,'c');
      Disp1Char(10,1,'m');
   }
}
void timeinit()
  {
    TACTL=TASSEL_2+ID_3+MC_1;   //ID_2表示八分频!  MC_1表示连续计数模式!
    BCSCTL2=0x88;               //选择SMCLK的信号源XT2CLK(8MHz)
    CCR0=65535;
    _EINT();                    //打开总中断!
  }

#pragma vector=PORT1_VECTOR
__interrupt void port1_int(void)
  {
    if((P1IN&BIT5)==BIT5)
      {
        TACTL|=MC_1+TACLR;
        P1IES|=BIT5;
      }
    else
      {
        TACTL&=~MC_3;
        P1IES&=~BIT5;
        distance=TAR*5/3;
        //P2OUT=TAR;
      }
        P1IFG&=~BIT5;
}

void delay(uint y)
  {
     uint x;
     for(;y>0;y--)
       for(x=100;x>0;x--);   //用8MHz的总频率!!!
  }


/***********************************************
函数名称:DispStr
功    能:让液晶从某个位置起连续显示一个字符串
参    数:x--位置的列坐标
          y--位置的行坐标
          ptr--指向字符串存放位置的指针
***********************************************/
void DispStr(uchar x,uchar y,uchar *ptr)
{
    uchar *temp;
    uchar i,n = 0;   
    temp = ptr;
    while(*ptr++ != '\0')   n++;    //计算字符串有效字符的个数   
    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,temp[i]);
        if (x == 0x0f)
        {
           x  = 0;
           y ^= 1;
        }
    }
}
/*******************************************
函数名称:DispNchar
功    能:让液晶从某个位置起连续显示N个字符
参    数:x--位置的列坐标
          y--位置的行坐标
          n--字符个数
          ptr--指向字符存放位置的指针
返回值  :无
********************************************/
void DispNChar(uchar x,uchar y, uchar n,uchar *ptr)
{
    uchar i;
    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,ptr[i]);
        if (x == 0x0f)
        {
           x = 0;
           y ^= 1;
        }
    }
}
/*******************************************
函数名称:LocateXY
功    能:向液晶输入显示字符位置的坐标信息
参    数:x--位置的列坐标
          y--位置的行坐标
返回值  :无
********************************************/
void LocateXY(uchar x,uchar y)
{
    uchar temp;
    temp = x&0x0f;
    y &= 0x01;
    if(y)   temp |= 0x40;  //如果在第2行
    temp |= 0x80;
    LcdWriteCommand(temp,1);
}
/*******************************************
函数名称:Disp1Char
功    能:在某个位置显示一个字符
参    数:x--位置的列坐标
          y--位置的行坐标
          data--显示的字符数据
返回值  :无
********************************************/
void Disp1Char(uchar x,uchar y,uchar data)
{
    LocateXY( x, y );                       
    LcdWriteData( data );               
}
/*******************************************
函数名称:LcdReset
功    能:对1602液晶模块进行复位操作
参    数:无
返回值  :无5
********************************************/
void LcdReset(void)
{
    CtrlDir |= 0x38;                 //控制线端口设为输出状态
    DataDir  = 0xFF;                 //数据端口设为输出状态
    LcdWriteCommand(0x38, 0);            //规定的复位操作
    Delay5ms();
    LcdWriteCommand(0x38, 0);               
    Delay5ms();
    LcdWriteCommand(0x38, 0);
    Delay5ms();
    LcdWriteCommand(0x38, 1);                 //显示模式设置
    LcdWriteCommand(0x08, 1);                 //显示关闭
    LcdWriteCommand(0x01, 1);                //显示清屏
    LcdWriteCommand(0x06, 1);                 //写字符时整体不移动
    LcdWriteCommand(0x0c, 1);                 //显示开,不开游标,不闪烁
}
/*******************************************
函数名称:LcdWriteCommand
功    能:向液晶模块写入命令
参    数:cmd--命令,
          chk--是否判忙的标志,1:判忙,0:不判
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk)
{

    if (chk) WaitForEnable();         // 检测忙信号?
    CLR_RS;       
    CLR_RW;
    _NOP();

    DataPort = cmd;                  //将命令字写入数据端口
    _NOP();                                       
   
    SET_EN;                         //产生使能脉冲信号
    _NOP();
    _NOP();
    CLR_EN;                       
}
       
/*******************************************
函数名称:LcdWriteData
功    能:向液晶显示的当前地址写入显示数据
参    数:data--显示字符数据
********************************************/
void LcdWriteData( uchar data )
{
    WaitForEnable();        //等待液晶不忙

    SET_RS;
    CLR_RW;
    _NOP();

    DataPort = data;        //将显示数据写入数据端口
    _NOP();

    SET_EN;                 //产生使能脉冲信号
    _NOP();
    _NOP();
    CLR_EN;               
}
/*******************************************
函数名称:WaitForEnable
功    能:等待1602液晶完成内部操作
********************************************/
void WaitForEnable(void)
{
    P2DIR &= 0x00;             //将P4口切换为输入状态

    CLR_RS;
    SET_RW;
    _NOP();
    SET_EN;
    _NOP();
    _NOP();
       
    while((P2IN & Busy)!=0);  //检测忙标志

    CLR_EN;

    P2DIR |= 0xFF;           //将P4口切换为输出状态
}       


                       
/*******************************************
函数名称:Delay5ms
功    能:延时约5ms
********************************************/
void Delay5ms(void)
{
    uint i=40000;
    while (i != 0)
    {
        i--;
    }
}

相关帖子

沙发
dirtwillfly| | 2016-8-24 20:19 | 只看该作者
汗,貌似不是官方的例程阿

使用特权

评论回复
板凳
开始吧|  楼主 | 2016-8-24 21:39 | 只看该作者
dirtwillfly 发表于 2016-8-24 20:19
汗,貌似不是官方的例程阿

超声测距也有官方例程么?

使用特权

评论回复
地板
开始吧|  楼主 | 2016-8-24 21:42 | 只看该作者
dirtwillfly 发表于 2016-8-24 20:19
汗,貌似不是官方的例程阿

请问这几句什么意思?
TACTL&=~MC_3;
         P1IES&=~BIT5;
         distance=TAR*5/3;

TAR是时间么?原程序是f149的,但是我149的板子烧入不进程序。应该是没有驱动,,,所以想改用5529的

使用特权

评论回复
5
dirtwillfly| | 2016-8-24 21:49 | 只看该作者
TAR是定时器的计数器

使用特权

评论回复
6
迪卡| | 2016-8-25 10:15 | 只看该作者
超声波测距是算的声波发出到接收之间的时间间隔,乘以声速,在除以2

使用特权

评论回复
7
开始吧|  楼主 | 2016-8-25 10:52 | 只看该作者
迪卡 发表于 2016-8-25 10:15
超声波测距是算的声波发出到接收之间的时间间隔,乘以声速,在除以2

请问这个时间间隔怎么得到的

使用特权

评论回复
8
火山LF| | 2016-8-25 14:40 | 只看该作者
本帖最后由 火山LF 于 2016-8-25 14:42 编辑
开始吧 发表于 2016-8-24 21:42
请问这几句什么意思?
TACTL&=~MC_3;
         P1IES&=~BIT5;

你得看芯片规格书,和datasheet去了解是什么寄存器实现什么功能,定时器那块不难,你看一下就造了,官网例程也有助于你理解

举个例子
我找的是我自己的MSP430FR5969的定时器那块(不过很多是通用的)
MC_3就是选择定时器模式的
Mode control. Setting MC = 00h when Timer_A is not in use conserves power.
00b = Stop mode: Timer is halted
01b = Up mode: Timer counts up to TAxCCR0
10b = Continuous mode: Timer counts up to 0FFFFh
11b = Up/down mode: Timer counts up to TAxCCR0 then down to 0000h


P1IES :Interrupt Edge Select Registers (PxIES)选择中断触发沿
PxIES PxIN PxIFG
0 → 1 0 Will be set
0 → 1 1 Unchanged
1 → 0 0 Unchanged
1 → 0 1 Will be set

所以,我个人建议,先看规格书和Datasheet,看不懂再来问人
学习是个过程,学习解决问题的能力和查找资料的能力

使用特权

评论回复
评论
angus118 2016-8-25 17:22 回复TA
777 
数码小叶 2016-8-25 17:19 回复TA
666 
评分
参与人数 1威望 +10 收起 理由
dirtwillfly + 10 很给力!
9
航天的鱼| | 2016-8-25 17:26 | 只看该作者
火山LF 发表于 2016-8-25 14:40
你得看芯片规格书,和datasheet去了解是什么寄存器实现什么功能,定时器那块不难,你看一下就造了,官网例 ...

请接收我的膝盖

使用特权

评论回复
10
火山LF| | 2016-8-25 17:26 | 只看该作者

你的膝盖太大了,收不下啊

使用特权

评论回复
11
航天的鱼| | 2016-8-25 17:31 | 只看该作者
火山LF 发表于 2016-8-25 17:26
你的膝盖太大了,收不下啊

妹纸太谦虚了

使用特权

评论回复
12
vivilzb1985| | 2016-8-25 22:40 | 只看该作者
超声波测距的关键是发出的信号跟返回的信号的处理的

使用特权

评论回复
13
拉克丝| | 2016-8-27 20:46 | 只看该作者
楼主是不知道什么时候发出的波,什么时候又接收到回波吧

使用特权

评论回复
14
开始吧|  楼主 | 2016-9-2 17:36 | 只看该作者
拉克丝 发表于 2016-8-27 20:46
楼主是不知道什么时候发出的波,什么时候又接收到回波吧

嗯,中断部分没搞明白

使用特权

评论回复
15
开始吧|  楼主 | 2016-9-2 17:37 | 只看该作者
拉克丝 发表于 2016-8-27 20:46
楼主是不知道什么时候发出的波,什么时候又接收到回波吧

嗯,中断部分没搞明白

使用特权

评论回复
16
kkzz| | 2016-9-2 22:39 | 只看该作者
这个最简单还是中断触发。

使用特权

评论回复
17
kkzz| | 2016-9-2 22:44 | 只看该作者
以前做过超声波,直接中断启动定时器,然后就读取下降沿。

使用特权

评论回复
18
Rangar| | 2016-9-10 21:09 | 只看该作者
149的板子烧入不进程序?怎么会这样

使用特权

评论回复
19
Soraka| | 2016-9-11 22:04 | 只看该作者
请问这个时间间隔怎么得到的

这就是超声波的发射和接收端得到的信号啊

使用特权

评论回复
20
cehuafan| | 2016-9-12 16:11 | 只看该作者
定时器采样吗?

使用特权

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

本版积分规则

12

主题

68

帖子

0

粉丝