数字传感器测温

2019-07-25 15:41发布

本帖最后由 yuluabc 于 2015-9-9 14:43 编辑

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

  1. //*****************************************************************************
  2. //   MSP430x42x0 Demo - SD16_A, LCD
  3. //*****************************************************************************

  4. //MLX90614 Pin Config

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

  9. #include  <msp430x54x.h>
  10. #include <string.h>
  11. #include "lcdoperate.h"
  12. #include <math.h>

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


  14. //*************************************************************
  15. //*************************************************************
  16. #define uchar unsigned char
  17. #define uint  unsigned int
  18. void Delay(unsigned int n);
  19. void start_bit();
  20. void stop_bit();
  21. void send_bit(unsigned char bit_out);
  22. unsigned char receive_bit();
  23. unsigned char slave_ack();
  24. void TX_byte(unsigned char TX_buffer);
  25. unsigned char RX_byte(unsigned char ack_nack);
  26. unsigned char PEC_cal(unsigned char pec[],int n);
  27. unsigned long int MEM_READ( unsigned char slave_addR, unsigned char cmdR );                                                
  28. void  Init_LCD();
  29. void mlx90614_POW_0() { P1OUT &= ~0x08;}  // define P6.3 ---> POW
  30. void mlx90614_POW_1() { P1OUT |= 0x08;}

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

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

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


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

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

  40. //*************************************************************
  41. //*************************************************************

  42. void Delay(unsigned int n)
  43. {
  44.   unsigned int i;
  45.   for(i=0;i<n;i++)
  46.   _NOP();
  47. }

  48. //----------------------------------------------------------------------------------------------------------------------------------------//
  49. //Name: start_bit
  50. //----------------------------------------------------------------------------------------------------------------------------------------//
  51. void start_bit()
  52. {
  53.   _SDA_OUTPUT; //Set SDA as output
  54.   mlx90614_SDA_1();
  55.   Delay(3);
  56.   mlx90614_SCL_1();
  57.   
  58.   Delay(40);
  59.   mlx90614_SDA_0();
  60.   Delay(40);
  61.   mlx90614_SCL_0();
  62.   Delay(3);
  63.   
  64. }

  65. //----------------------------------------------------------------------------------------------------------------------------------------//
  66. //Name: stop_bit
  67. //----------------------------------------------------------------------------------------------------------------------------------------//
  68. void stop_bit()
  69. {
  70.   _SDA_OUTPUT; //Set SDA as output

  71.   mlx90614_SCL_0();
  72.     Delay(40);
  73.   mlx90614_SDA_0();
  74.   Delay(40);
  75.   mlx90614_SCL_1();
  76.   Delay(40);
  77.   mlx90614_SDA_1();
  78. }

  79. //----------------------------------------------------------------------------------------------------------------------------------------//
  80. //Name: send_bit
  81. //----------------------------------------------------------------------------------------------------------------------------------------//
  82. void send_bit(unsigned char bit_out)
  83. {
  84.   _SDA_OUTPUT; //Set SDA as output
  85.   Delay(5);
  86.   if(bit_out==0) {mlx90614_SDA_0();}else{mlx90614_SDA_1();}
  87.   Delay(3);
  88.   mlx90614_SCL_1();
  89.   Delay(32);
  90.   mlx90614_SCL_0();
  91.   Delay(32);
  92. }

  93. //----------------------------------------------------------------------------------------------------------------------------------------//
  94. //Name: receive_bit
  95. //----------------------------------------------------------------------------------------------------------------------------------------//
  96. unsigned char receive_bit()
  97. {
  98.   unsigned char bit_in;
  99.   _SDA_INPUT; //Set SDA as input
  100.   mlx90614_SCL_1();
  101.   Delay(16);
  102.   if(SDA==1){bit_in=1;}else{bit_in=0;}
  103.   Delay(16);
  104.   mlx90614_SCL_0();
  105.   Delay(32);
  106.   return bit_in;
  107. }

  108. //----------------------------------------------------------------------------------------------------------------------------------------//
  109. //Name: slave_ack
  110. //1 - ACK
  111. //0 -NACK
  112. //----------------------------------------------------------------------------------------------------------------------------------------//
  113. unsigned char slave_ack()
  114. {
  115.   unsigned char ack;
  116.   ack=0;
  117.   _SDA_INPUT; //Set SDA as input
  118.   mlx90614_SCL_1();
  119.   Delay(16);
  120.   if(SDA==1){ack=0;}else{ack=1;}
  121.   Delay(16);
  122.   mlx90614_SCL_0();
  123.   Delay(32);
  124.   return ack;
  125. }

  126. //----------------------------------------------------------------------------------------------------------------------------------------//
  127. //Name: TX_byte
  128. //----------------------------------------------------------------------------------------------------------------------------------------//
  129. void TX_byte(unsigned char TX_buffer)
  130. {
  131.   unsigned char Bit_counter;
  132.   unsigned char bit_out;
  133.   for(Bit_counter=8;Bit_counter;Bit_counter--)
  134.   {
  135.     if(TX_buffer&0x80){bit_out=1;}else{bit_out=0;}
  136.     send_bit(bit_out); //Send the current bit on SMBus
  137.     TX_buffer<<=1; //Get next bit to check
  138.   }
  139. }

  140. //----------------------------------------------------------------------------------------------------------------------------------------//
  141. //Name: RX_byte
  142. //Parameters: unsigned char ack_nack (acknowledgment bit)
  143. //0 - Master device sends ACK
  144. //1 - Master device sends NACK
  145. //----------------------------------------------------------------------------------------------------------------------------------------//
  146. unsigned char RX_byte(unsigned char ack_nack)
  147. {
  148.         unsigned char RX_buffer;
  149.         unsigned char Bit_counter;
  150.         for(Bit_counter=8;Bit_counter;Bit_counter--)
  151.         {
  152.          if(receive_bit()==1) //Read a bit from the SDA line
  153.           {
  154.            RX_buffer<<=1; //If the bit is HIGH save 1 in RX_buffer
  155.            RX_buffer|=0x01;
  156.           }
  157.          else //If the bit is LOW save 0 in RX_buffer
  158.           {
  159.            RX_buffer<<=1;
  160.            RX_buffer&=0xfe;
  161.           }
  162.         }
  163.         send_bit(ack_nack); //Sends acknowledgment bit
  164.         return RX_buffer;
  165. }


  166. //----------------------------------------------------------------------------------------------------------------------------------------//
  167. //CALCULATE THE PEC PACKET
  168. //----------------------------------------------------------------------------------------------------------------------------------------//
  169. unsigned char PEC_cal(unsigned char pec[],int n)
  170. {
  171.     unsigned char crc[6];
  172.     unsigned char Bitposition=47;
  173.     unsigned char shift;
  174.     unsigned char i;
  175.     unsigned char j;
  176.     unsigned char temp;
  177.   do{
  178.     crc[5]=0; //Load CRC value 0x000000000107
  179.     crc[4]=0;
  180.     crc[3]=0;
  181.     crc[2]=0;
  182.     crc[1]=0x01;
  183.     crc[0]=0x07;
  184.     Bitposition=47; //Set maximum bit position at 47
  185.     shift=0;        //Find first 1 in the transmitted bytes
  186.     i=5; //Set highest index (package byte index)
  187.     j=0; //Byte bit index, from lowest
  188.     while((pec[i]&(0x80>>j))==0 && (i>0))
  189.     {
  190.      Bitposition--;
  191.      if(j<7){ j++;}
  192.      else {j=0x00;i--;}
  193.     }//the position of highest "1" bit in Bitposition is calculated
  194.     shift=Bitposition-8; //Get shift value for CRC value
  195.         
  196.     while(shift)
  197.     {
  198.       for(i=5;i<0xFF;i--)
  199.       {
  200.        if((crc[i-1]&0x80) && (i>0)) //Check if the MSB of the byte lower is "1"
  201.         { //Yes - current byte + 1
  202.          temp=1; //No - current byte + 0
  203.         } //So that "1" can shift between bytes
  204.        else { temp=0;}
  205.       crc[i]<<=1;
  206.       crc[i]+=temp;
  207.       }
  208.     shift--;
  209.     }
  210.     //Exclusive OR between pec and crc
  211.     for(i=0;i<=5;i++) { pec[i]^=crc[i]; }
  212.     }
  213.     while(Bitposition>8);
  214.     return pec[0];
  215.     }
  216.         
  217. //----------------------------------------------------------------------------------------------------------------------------------------//
  218. //READ DATA FROM RAM/EEPROM
  219. //----------------------------------------------------------------------------------------------------------------------------------------//
  220. unsigned long int MEM_READ(unsigned char slave_addR, unsigned char cmdR)
  221. {
  222.   unsigned char DataL; //
  223.   unsigned char DataH; //Data packets from MLX90614
  224.   unsigned char PEC; //
  225.   unsigned long int Data; //Register value returned from MLX90614
  226.   unsigned char Pecreg; //Calculated PEC byte storage
  227.   unsigned char arr[6]; //Buffer for the sent bytes
  228.   unsigned char ack_nack;
  229.   unsigned char SLA;
  230.   SLA=(slave_addR<<1);
  231. begin:
  232.   start_bit(); //Send start bit
  233.   TX_byte(SLA); //Send slave address, write
  234.   if(slave_ack()==0){stop_bit();goto begin;} //Send command
  235.   TX_byte(cmdR);
  236.   if(slave_ack()==0){stop_bit();goto begin;}//Send Repeated start bit
  237.   start_bit(); //Send slave address, read
  238.   TX_byte(SLA+1);
  239.   if(slave_ack()==0){stop_bit();goto begin;}
  240.   DataL=RX_byte(0); //
  241.   //Read two bytes data
  242.   DataH=RX_byte(0); //
  243.   PEC=RX_byte(ack_nack); //Read PEC from MLX90614
  244.   if(ack_nack==1) //Master sends ack or nack
  245.   //This depends on the pec calculation,
  246.   //if the PEC is not correct, send nack and goto begin
  247.   {stop_bit();goto begin;} //Send stop bit
  248.   stop_bit();
  249.   arr[5]=(SLA);
  250.   arr[4]=cmdR;
  251.   arr[3]=(SLA+1);
  252.   arr[2]=DataL;
  253.   arr[1]=DataH;
  254.   arr[0]=0;
  255.   Pecreg=PEC_cal(arr,6); //Calculate CRC
  256.   if(PEC==Pecreg){ ack_nack=0;}
  257.   else{ ack_nack=1;}
  258.   Data=(DataH*256)+DataL;
  259.   return Data;
  260. }

  261. //---------------------------------------
  262. //Name: CALTEMP           
  263. //Temperature data is T=(Data)*0.02-273.15
  264. //---------------------------------------
  265. float CalcTemp(unsigned int value )
  266. {
  267.         float temp;
  268.         
  269.         temp=(value*0.02)-273.15;
  270.         _NOP();
  271.         
  272.         return temp;
  273. }
  274. //------------------------------------------------------------------------------
  275. // LCD Test Code
  276. //------------------------------------------------------------------------------

  277. //------------------------------------------------------------------------------
  278. // Init_LCD.
  279. //------------------------------------------------------------------------------

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

  310.     unsigned long int DATA;
  311.          
  312.     _SDA_OUTPUT;
  313.      P1SEL |= BIT2;
  314.      
  315.       mlx90614_SCL_0();                                //
  316.        Delay(12000);                                //SMBus request,Switch PWM mode to SMBus mode(at least 2ms)
  317.       mlx90614_SCL_1();                //
  318.   while(1)
  319.        {
  320.       DATA=MEM_READ(0x5a,0x07);
  321.    
  322.         temp[16]=CalcTemp(DATA);
  323.    sprintf(temp,"温度:%.2f度");
  324.     Display_String_Unregular(0,6,temp);
  325.    
  326.        }
  327. }



复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
dirtwillfly
1楼-- · 2019-07-25 17:28
你用的哪一个msp430?
MSP430x42x0还是msp430x54x?
用的什么传感器?
yuluabc
2楼-- · 2019-07-25 21:48
 精彩回答 2  元偷偷看……
dirtwillfly
3楼-- · 2019-07-25 22:59
yuluabc 发表于 2015-9-9 11:11
msp430x54x,传感器是mlx90614,温度一直显示负的100多度

你用的SMBus方式读取?
yuluabc
4楼-- · 2019-07-26 04:31
dirtwillfly 发表于 2015-9-9 11:52
你用的SMBus方式读取?

对,SMBus方式,您看是哪里的问题呢
lianer2002
5楼-- · 2019-07-26 05:34
没用过你这个传感器,不过我建议Lz用示波器看下波形,你要是总是一个值的话,估计时序错误的可能性比较大
dirtwillfly
6楼-- · 2019-07-26 09:10
lianer2002 发表于 2015-9-9 14:43
没用过你这个传感器,不过我建议Lz用示波器看下波形,你要是总是一个值的话,估计时序错误的可能性比较大 ...

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

一周热门 更多>