打印

数字传感器测温

[复制链接]
1136|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yuluabc|  楼主 | 2015-9-9 10:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 yuluabc 于 2015-9-9 14:43 编辑

各位大神帮忙分析下程序,为什么读出来的温度值总是一个,而且是个负值,百思不得解,谢谢了!

//*****************************************************************************
//   MSP430x42x0 Demo - SD16_A, LCD
//*****************************************************************************

//MLX90614 Pin Config

//GND-----6.0.....I/O supply the MLX90614
//SDA-----6.1
//SCL-----6.2
//POW-----6.3.....I/O supply the MLX90614

#include  <msp430x54x.h>
#include <string.h>
#include "lcdoperate.h"
#include <math.h>

unsigned int A1,A2,A3,A4,A5;


//*************************************************************
//*************************************************************
#define uchar unsigned char
#define uint  unsigned int
void Delay(unsigned int n);
void start_bit();
void stop_bit();
void send_bit(unsigned char bit_out);
unsigned char receive_bit();
unsigned char slave_ack();
void TX_byte(unsigned char TX_buffer);
unsigned char RX_byte(unsigned char ack_nack);
unsigned char PEC_cal(unsigned char pec[],int n);
unsigned long int MEM_READ( unsigned char slave_addR, unsigned char cmdR );                                                
void  Init_LCD();
void mlx90614_POW_0() { P1OUT &= ~0x08;}  // define P6.3 ---> POW
void mlx90614_POW_1() { P1OUT |= 0x08;}

void mlx90614_GND_0() { P1OUT &= ~0x01;}  // define P6.0 ---> GND
void mlx90614_GND_1() { P1OUT |= 0x01;}

void mlx90614_SCL_0() { P1OUT &= ~0x04;}  // define P6.2 ---> SCL
void mlx90614_SCL_1() { P1OUT |= 0x04;}

void mlx90614_SDA_0() { P1OUT &= ~0x02;}  // define P6.1 ---> SDA
void mlx90614_SDA_1() { P1OUT |= 0x02;}


#define _SDA_OUTPUT P1DIR |=0x02; //Set SDA as Output
#define _SDA_INPUT P1DIR &=~0x02; //Set SDA as Input

#define SDA ((P1IN & BIT1)>>1) //define input pin

//*************************************************************
//*************************************************************

void Delay(unsigned int n)
{
  unsigned int i;
  for(i=0;i<n;i++)
  _NOP();
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: start_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
void start_bit()
{
  _SDA_OUTPUT; //Set SDA as output
  mlx90614_SDA_1();
  Delay(3);
  mlx90614_SCL_1();
  
  Delay(40);
  mlx90614_SDA_0();
  Delay(40);
  mlx90614_SCL_0();
  Delay(3);
  
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: stop_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
void stop_bit()
{
  _SDA_OUTPUT; //Set SDA as output

  mlx90614_SCL_0();
    Delay(40);
  mlx90614_SDA_0();
  Delay(40);
  mlx90614_SCL_1();
  Delay(40);
  mlx90614_SDA_1();
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: send_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
void send_bit(unsigned char bit_out)
{
  _SDA_OUTPUT; //Set SDA as output
  Delay(5);
  if(bit_out==0) {mlx90614_SDA_0();}else{mlx90614_SDA_1();}
  Delay(3);
  mlx90614_SCL_1();
  Delay(32);
  mlx90614_SCL_0();
  Delay(32);
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: receive_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned char receive_bit()
{
  unsigned char bit_in;
  _SDA_INPUT; //Set SDA as input
  mlx90614_SCL_1();
  Delay(16);
  if(SDA==1){bit_in=1;}else{bit_in=0;}
  Delay(16);
  mlx90614_SCL_0();
  Delay(32);
  return bit_in;
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: slave_ack
//1 - ACK
//0 -NACK
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned char slave_ack()
{
  unsigned char ack;
  ack=0;
  _SDA_INPUT; //Set SDA as input
  mlx90614_SCL_1();
  Delay(16);
  if(SDA==1){ack=0;}else{ack=1;}
  Delay(16);
  mlx90614_SCL_0();
  Delay(32);
  return ack;
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: TX_byte
//----------------------------------------------------------------------------------------------------------------------------------------//
void TX_byte(unsigned char TX_buffer)
{
  unsigned char Bit_counter;
  unsigned char bit_out;
  for(Bit_counter=8;Bit_counter;Bit_counter--)
  {
    if(TX_buffer&0x80){bit_out=1;}else{bit_out=0;}
    send_bit(bit_out); //Send the current bit on SMBus
    TX_buffer<<=1; //Get next bit to check
  }
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: RX_byte
//Parameters: unsigned char ack_nack (acknowledgment bit)
//0 - Master device sends ACK
//1 - Master device sends NACK
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned char RX_byte(unsigned char ack_nack)
{
        unsigned char RX_buffer;
        unsigned char Bit_counter;
        for(Bit_counter=8;Bit_counter;Bit_counter--)
        {
         if(receive_bit()==1) //Read a bit from the SDA line
          {
           RX_buffer<<=1; //If the bit is HIGH save 1 in RX_buffer
           RX_buffer|=0x01;
          }
         else //If the bit is LOW save 0 in RX_buffer
          {
           RX_buffer<<=1;
           RX_buffer&=0xfe;
          }
        }
        send_bit(ack_nack); //Sends acknowledgment bit
        return RX_buffer;
}


//----------------------------------------------------------------------------------------------------------------------------------------//
//CALCULATE THE PEC PACKET
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned char PEC_cal(unsigned char pec[],int n)
{
    unsigned char crc[6];
    unsigned char Bitposition=47;
    unsigned char shift;
    unsigned char i;
    unsigned char j;
    unsigned char temp;
  do{
    crc[5]=0; //Load CRC value 0x000000000107
    crc[4]=0;
    crc[3]=0;
    crc[2]=0;
    crc[1]=0x01;
    crc[0]=0x07;
    Bitposition=47; //Set maximum bit position at 47
    shift=0;        //Find first 1 in the transmitted bytes
    i=5; //Set highest index (package byte index)
    j=0; //Byte bit index, from lowest
    while((pec[i]&(0x80>>j))==0 && (i>0))
    {
     Bitposition--;
     if(j<7){ j++;}
     else {j=0x00;i--;}
    }//the position of highest "1" bit in Bitposition is calculated
    shift=Bitposition-8; //Get shift value for CRC value
        
    while(shift)
    {
      for(i=5;i<0xFF;i--)
      {
       if((crc[i-1]&0x80) && (i>0)) //Check if the MSB of the byte lower is "1"
        { //Yes - current byte + 1
         temp=1; //No - current byte + 0
        } //So that "1" can shift between bytes
       else { temp=0;}
      crc[i]<<=1;
      crc[i]+=temp;
      }
    shift--;
    }
    //Exclusive OR between pec and crc
    for(i=0;i<=5;i++) { pec[i]^=crc[i]; }
    }
    while(Bitposition>8);
    return pec[0];
    }
        
//----------------------------------------------------------------------------------------------------------------------------------------//
//READ DATA FROM RAM/EEPROM
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned long int MEM_READ(unsigned char slave_addR, unsigned char cmdR)
{
  unsigned char DataL; //
  unsigned char DataH; //Data packets from MLX90614
  unsigned char PEC; //
  unsigned long int Data; //Register value returned from MLX90614
  unsigned char Pecreg; //Calculated PEC byte storage
  unsigned char arr[6]; //Buffer for the sent bytes
  unsigned char ack_nack;
  unsigned char SLA;
  SLA=(slave_addR<<1);
begin:
  start_bit(); //Send start bit
  TX_byte(SLA); //Send slave address, write
  if(slave_ack()==0){stop_bit();goto begin;} //Send command
  TX_byte(cmdR);
  if(slave_ack()==0){stop_bit();goto begin;}//Send Repeated start bit
  start_bit(); //Send slave address, read
  TX_byte(SLA+1);
  if(slave_ack()==0){stop_bit();goto begin;}
  DataL=RX_byte(0); //
  //Read two bytes data
  DataH=RX_byte(0); //
  PEC=RX_byte(ack_nack); //Read PEC from MLX90614
  if(ack_nack==1) //Master sends ack or nack
  //This depends on the pec calculation,
  //if the PEC is not correct, send nack and goto begin
  {stop_bit();goto begin;} //Send stop bit
  stop_bit();
  arr[5]=(SLA);
  arr[4]=cmdR;
  arr[3]=(SLA+1);
  arr[2]=DataL;
  arr[1]=DataH;
  arr[0]=0;
  Pecreg=PEC_cal(arr,6); //Calculate CRC
  if(PEC==Pecreg){ ack_nack=0;}
  else{ ack_nack=1;}
  Data=(DataH*256)+DataL;
  return Data;
}

//---------------------------------------
//Name: CALTEMP           
//Temperature data is T=(Data)*0.02-273.15
//---------------------------------------
float CalcTemp(unsigned int value )
{
        float temp;
        
        temp=(value*0.02)-273.15;
        _NOP();
        
        return temp;
}
//------------------------------------------------------------------------------
// LCD Test Code
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Init_LCD.
//------------------------------------------------------------------------------

//*************************************************************
//*************************************************************
/*LCD初始化:把控制引脚LCD_CS,LCD_SCL,LCD_SI,LCD_A0,LCD_RES,LCD_BLAEN等配置为输出*/
void  Init_LCD()
{
  P6DIR|=BIT7;          //背光引脚设置为输出,打开背光灯
  P8DIR|=(BIT5+BIT6+BIT7);  //复位引脚LCD_RES设置为输出
  P9DIR|=(BIT0+BIT1+BIT2+BIT3);//LCD控制引脚CS,SCL,SI,A0设置为输出
  initLCDM();                  //初始化LCDM
  ClearRAM(0,0,128,8);         //清屏
}
void main(void)
{
  volatile unsigned int i;   
  char temp[16];
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  
  P11DIR = BIT0 + BIT1 + BIT2;                    // ACLK ,MCLK ,MCLK  输出方向
      P11SEL = BIT0 + BIT1 + BIT2;
       P7SEL |= 0x03;                                   // 设置DCO范围  
     UCSCTL1 = DCORSEL_4;                             // 选择FLL参考源自REFO  
     UCSCTL2 |= 0x79;                                 // Set DCO Multiplier for 8MHz
     UCSCTL4 = SELM_3 + SELA_0 + SELS_3;              // 配置 MCLK = DCOC,SMCLK =DCOC,ACLK=XT1
     UCSCTL6 |= SMCLKOFF;
     while (SFRIFG1 & OFIFG)                          //清除OFIFG,and  XT1OFFG ,DCOFFG
     {
          UCSCTL7 &= ~(  XT1LFOFFG + DCOFFG);
          SFRIFG1 &= ~OFIFG;
     }        
  Init_LCD();

    unsigned long int DATA;
         
    _SDA_OUTPUT;
     P1SEL |= BIT2;
     
      mlx90614_SCL_0();                                //
       Delay(12000);                                //SMBus request,Switch PWM mode to SMBus mode(at least 2ms)
      mlx90614_SCL_1();                //
  while(1)
       {
      DATA=MEM_READ(0x5a,0x07);
   
        temp[16]=CalcTemp(DATA);
   sprintf(temp,"温度:%.2f度");
    Display_String_Unregular(0,6,temp);
   
       }
}



相关帖子

沙发
dirtwillfly| | 2015-9-9 11:03 | 只看该作者
你用的哪一个msp430?
MSP430x42x0还是msp430x54x?
用的什么传感器?

使用特权

评论回复
板凳
yuluabc|  楼主 | 2015-9-9 11:11 | 只看该作者
dirtwillfly 发表于 2015-9-9 11:03
你用的哪一个msp430?
MSP430x42x0还是msp430x54x?
用的什么传感器?

msp430x54x,传感器是mlx90614,温度一直显示负的100多度

使用特权

评论回复
地板
dirtwillfly| | 2015-9-9 11:52 | 只看该作者
yuluabc 发表于 2015-9-9 11:11
msp430x54x,传感器是mlx90614,温度一直显示负的100多度

你用的SMBus方式读取?

使用特权

评论回复
5
yuluabc|  楼主 | 2015-9-9 14:03 | 只看该作者
dirtwillfly 发表于 2015-9-9 11:52
你用的SMBus方式读取?

对,SMBus方式,您看是哪里的问题呢

使用特权

评论回复
6
lianer2002| | 2015-9-9 14:43 | 只看该作者
没用过你这个传感器,不过我建议Lz用示波器看下波形,你要是总是一个值的话,估计时序错误的可能性比较大

使用特权

评论回复
7
dirtwillfly| | 2015-9-9 15:06 | 只看该作者
lianer2002 发表于 2015-9-9 14:43
没用过你这个传感器,不过我建议Lz用示波器看下波形,你要是总是一个值的话,估计时序错误的可能性比较大 ...

嗯,或者用逻辑分析仪也可以,没有太好的办法。
或者读写其他寄存器试试,看能不能正确通讯

使用特权

评论回复
8
yuluabc|  楼主 | 2015-9-9 15:29 | 只看该作者
lianer2002 发表于 2015-9-9 14:43
没用过你这个传感器,不过我建议Lz用示波器看下波形,你要是总是一个值的话,估计时序错误的可能性比较大 ...

那这个时序错误是由什么造成的呢,和时钟频率和延时有关系吗

使用特权

评论回复
9
lefeng| | 2015-9-9 21:15 | 只看该作者
看看时序图怎么说的,其实就是先打开谁,然后谁才能工作等等

使用特权

评论回复
10
android2| | 2015-9-9 21:22 | 只看该作者
楼主的程序也不注释一下:L

使用特权

评论回复
11
Snow7| | 2015-9-10 21:35 | 只看该作者
建议先用示波器看下波形,估计是时序错误问题

使用特权

评论回复
12
309030| | 2015-9-14 22:38 | 只看该作者
读写其他寄存器试试,看能不能正确通讯

使用特权

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

本版积分规则

17

主题

49

帖子

0

粉丝