[求助] 如何让接收数据缓存同时接收两个字节

黛丝滢芸   2012-5-1 14:28 楼主

#include<msp430x16x.h>


void UARTSnd(unsigned char dat);
void UART_init();
void clock_int();


unsigned long LastRcvData;
unsigned char GLength;
unsigned char RcvIndex;
unsigned char GLengthHigh,GLengthLow;
//********************时钟初始化*******************//
void clock_int()

    unsigned int i;
    P5DIR|=0x70;
    P5SEL|=0x70;                               //P5.4 MCLK输出,P5.5 SMCLK输出,P5.6 ACLK输出4KHZ
   
    BCSCTL1 |= ~XT2OFF+XTS;                               //XT2和LFXT1全部打开
    do
    {
        IFG1 &= ~OFIFG;                                // 清除振荡器失效标志
        for (i = 0xFF; i > 0; i--);                    // 稳定时间
    }
    while ((IFG1 & OFIFG)!=0);                            // 若振荡器失效标志存在
     BCSCTL2 |=SELM1+SELM0+SELS+DIVS_3;                // SMCLK = XT2/8 = 1MHz,MCLK=LFXT1=32.768KHZ
   
}

 

//********************波特率初始化*******************//
void UART_init()
{
 // UCTL0|=SWRST;                                  //这之后才能对串口模块其它寄存器做修改
 
  UTCTL0=SSEL1;                                 //UCLK=SMCLK=1MHZ
  UBR00=0x68;
  UBR10=0x00;                                   //在1000000HZ下进行9600波特率的通信
  UMCTL0=0x01;                                  //波特率分频因子

  UCTL0=CHAR;                                   //8位字符长度
 
 
 // UCTL0&=~SWRST;                                  //使能USART,这之后发送模块才能工作
 
  ME1|=URXE0+UTXE0;                              //允许USART0 TXD/RXD
  IE1|=URXIE0;                             //使能接收中断
 
  P3SEL|=0x30;                                   //p3.4,5用作USART0 TXD/RXD
  P3DIR|=0x10;                                   //p3.4输出

 
 
 
  
}

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx(void)
{
  //while(!(IFG1&UTXIFG0));                              //TX or RX?

  while((IFG1 & UTXIFG0)==0);                     //USART0接收缓存有数据吗,UTXIFG0发送中断标志,TX缓存空闲否?
  //TXBUF0=RXBUF0;                                 //读出接收到的数据
  //IFG1|=~URXIFG0; 
  LastRcvData=RXBUF0;                              //输入缓存器转换成字符
  if(RcvIndex==0)
   
  {
    GLengthHigh=LastRcvData;
    RcvIndex++;
   
  }
  
 else if(RcvIndex==1)
        {
          GLengthLow=LastRcvData;
          RcvIndex=0;
        }
 
   
}

 


//********************发超声波脉冲*******************//

void MeterLenByUART()
{      
       
     
       
        TXBUF0=0x55;            //向缓冲区写入字符
       
        while((UTCTL1&0x01)==0);//正在传输数据或发送
                                //缓冲器UTXBUF有数据循环
                                //跳出则发送移位寄存器和UTXBUF为空
                                //查询等待一次发送完毕
                                      
       
 //UARTSnd(0X55);
        //串口模式下只需要在Trig/TX 管脚输入0X55(波特率9600),
        //系统便可发出8 个40KHZ 的超声波脉冲,然后检测回波信号。
       //当检测到回波信号后,模块还要进行温度值的测量,然后根据
        //当前温度对测距结果进行校正,将校正后的结果通过Echo/RX管脚输出
}


 
 
 


//********************主函数*******************//
void main(void)
{    

        WDTCTL=WDTPW+WDTHOLD;
         
 clock_int();
 UART_init();
 
 _EINT();                  //通用中断允许
 
 while(1)
 {   
               unsigned long PreLength;
               MeterLenByUART();
               
             
                  PreLength=GLengthHigh;
                  PreLength<<=8;
                  PreLength+=GLengthLow;
              
 
  }
}
串口发送0x55波特率,超声波测距模块返回2个字节的数据,如何将两个字节都接收到而不是仅有一个低字节的返回值,向各位前辈请教喽~本人是刚刚学习430有什么表达不清楚或者不对的地方请各位能否尽量帮小女子指点一二

回复评论 (9)

如果超声测距模块返回的是标准的两个8bits的uart数据,就像你的代码中写的,先接受高8位,然后接受低8位;将高8位数据左移8位后与低8位相加,这样就把16为的返回数据拼接出来了。
但是如果是按照UART的格式返回一个16位的数据,那就需要用软件模拟UART的接收时序了
点赞  2012-5-2 13:33

回复 沙发 wstt 的帖子

我用IAR看了一下超声波测距模块的返回值它只有低位的返回值,也就是近距离能测量准确,稍微远一点返回值就不停地变化。即使先将高位移位也不正确。还有版主说的用软件模拟UART的接收时序怎么弄可否具体说说。谢谢咯~
点赞  2012-5-2 21:03
引用: 原帖由 黛丝滢芸 于 2012-5-2 21:03 发表 我用IAR看了一下超声波测距模块的返回值它只有低位的返回值,也就是近距离能测量准确,稍微远一点返回值就不停地变化。即使先将高位移位也不正确。还有版主说的用软件模拟UART的接收时序怎么弄可否具体说说。谢谢咯~
首先需要确定的是返回数据的格式,这个需要确定下,看是2个8bits还是,一个16bits,这个确定后才能确定接收的方案
点赞  2012-5-3 10:57
点赞  2012-5-3 11:01
还有一篇
https://bbs.eeworld.com.cn/thread-288421-1-5.html

[ 本帖最后由 wstt 于 2012-5-3 11:05 编辑 ]
点赞  2012-5-3 11:02
我其实一直想找这篇文章来着https://bbs.eeworld.com.cn/thread-309735-1-1.html
点赞  2012-5-3 11:07

回复 4楼 wstt 的帖子

返回数据的格式是16位的,结果接收缓存存放的从接收移位寄存器最后的字符即低8位,如果用软件模拟UART时序是指用timerA和B吗?那之前写的用UART实现接收功能的程序是不是无法实现16位的数据接收了?
点赞  2012-5-5 12:30
查看IC的uart说明,可能只有7~8bit的格式可选,如果是的话就用定时器模拟uart通讯,思路是

1、用一个普通IO口做输入,打开它的外部输入中断,当起始位来的时候在中断里面打开定时器并关掉外部中断,在定时器的延时中断程序里读取IO口的电平并移位存储,这样你数据是几位就在判断几次,最终得到的就是你收到的数据。
2、更换普通IO口为时钟输入捕获复用口,用定时器的捕获功能触发起始位。
具体参考官方例程,或自己baidu
点赞  2012-5-5 13:31

回复 9楼 shower.xu 的帖子

现在我的问题解决啦,连续发5次55就能中断接收两个字节的值。这是我修改后的程序
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx(void)
{
  //while(!(IFG1&UTXIFG0));                              //TX or RX?

  while((IFG1 & UTXIFG0)==0);                     //USART0接收缓存有数据吗,UTXIFG0发送中断标志,TX缓存空闲否?
  //TXBUF0=RXBUF0;                                 //读出接收到的数据
  //IFG1|=~URXIFG0;

  LastRcvData=RXBUF0;                           //输入缓存器转换成字符
  TXBUF0=LastRcvData;
  
if(RcvIndex==0)
{
  GLengthHigh=LastRcvData;
  
      RcvIndex++;
}
else if(RcvIndex==1)
        {
           GLengthLow=LastRcvData;
           PreLength=GLengthHigh;
           PreLength<<=8;
           PreLength+=GLengthLow;
           RcvIndex=0;
              }
}
不过还是要感谢你的回复哟,你说的方法我会尝试一下的~
点赞  2012-5-6 23:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复