[分享] MLX90614红外测温模块程序msp430源代码与资料分享

Aguilera   2020-6-1 21:20 楼主

MLX90614ESF+传感器+红外非接触温度测量传感器模块程序源代码,用msp430的单片机

电路原理图如下:

image.png image.png


单片机源程序如下:
//*****************************************************************************
//   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  <msp430x42x0.h>

void LCD_CHECK(void);
void Init_LCD(void);
unsigned int A1,A2,A3,A4,A5;

#define a 0x01
#define b 0x02
#define c 0x04
#define d 0x80
#define e 0x40
#define f 0x10
#define g 0x20
#define h 0x08

const char char_gen[] = {                   // definitions for digits
  a+b+c+d+e+f,                              // Displays "0"
  b+c,                                      // Displays "1"
  a+b+d+e+g,                                // Displays "2"
  a+b+c+d+g,                                // Displays "3"
  b+c+f+g,                                  // Displays "4"
  a+c+d+f+g,                                // Displays "5"
  a+c+d+e+f+g,                              // Displays "6"
  a+b+c,                                    // Displays "7"
  a+b+c+d+e+f+g,                            // Displays "8"
  a+b+c+d+f+g,                              // Displays "9"
};

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

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 CALTEMP(unsigned long int TEMP);

void mlx90614_POW_0() { P6OUT &= ~0x08;}  // define P6.3 ---> POW
void mlx90614_POW_1() { P6OUT |= 0x08;}

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

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

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


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

#define SDA ((P6IN & 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
  Delay(5);
  mlx90614_SDA_1();
  //Delay(30);
  mlx90614_SCL_1();
  
  Delay(30);
  mlx90614_SDA_0();
  Delay(30);
  mlx90614_SCL_0();
  Delay(30);
  
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: stop_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
void stop_bit()
{
  _SDA_OUTPUT; //Set SDA as output
  Delay(1);
  //mlx90614_SCL_0();
  mlx90614_SDA_0();
  Delay(2);
  mlx90614_SCL_1();
  Delay(2);
  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(5);
  mlx90614_SCL_1();
  Delay(30);
  mlx90614_SCL_0();
  Delay(30);
}

//----------------------------------------------------------------------------------------------------------------------------------------//
//Name: receive_bit
//----------------------------------------------------------------------------------------------------------------------------------------//
unsigned char receive_bit()
{
  unsigned char bit_in;
  _SDA_INPUT; //Set SDA as input
  Delay(5);
  mlx90614_SCL_1();
  Delay(5);
  if(SDA==1){bit_in=1;}else{bit_in=0;}
  Delay(10);
  mlx90614_SCL_0();
  Delay(30);
  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
  Delay(5);
  mlx90614_SCL_1();
  Delay(10);
  if(SDA==1){ack=0;}else{ack=1;}
  Delay(10);
  mlx90614_SCL_0();
  Delay(30);
  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&(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<<=1;
      crc+=temp;
      }
    shift--;
    }
    //Exclusive OR between pec and crc
    for(i=0;i<=5;i++) { pec^=crc; }
    }
    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
//---------------------------------------
void CALTEMP(unsigned long int TEMP)
{
   unsigned long int T;
   unsigned int A, B;
   //unsigned int tempb;
   
   T=TEMP*2;
   if(T>=27315)
   {
     T=T-27315;
     A=T/100;
     B=T-A*100;
     if(A>=100){A1=A/100;A=A%100;A2=A/10;A=A%10;A3=A;}
     else if(A>=10){A1=0;A2=A/10;A=A%10;A3=A;}
     else {A1=0;A2=0;A3=A;}
     if(B>=10){A4=B/10;B=B%10;A5=B;}
     else{A4=0;A5=B;}
    }
   else
    {
     T=27315-T;
     A=T/100;
     B=T-A*100;
     A1=9;
     if(A>=10){A2=A/10;A=A%10;A3=A;}
     else{A2=0;A3=A;}
     if(B>=10){ A4=A/10;B=B%10;A5=B;}
     else{A4=0;A5=B;}
    }
}

//------------------------------------------------------------------------------
// LCD Test Code
//------------------------------------------------------------------------------

void LCD_CHECK()  // Clear LCD
{
  int j;
  for( j = 0; j < 8; j ++) { LCDMEM[j] = 0; }
}

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

void Init_LCD()
{
  P5SEL  = 0x1C;                             // Set COM pins for LCD
  LCDACTL = LCDON + LCD4MUX + LCDFREQ_128;   // 4mux LCD, ACLK/128
  LCDAPCTL0 = 0x0F;                          // Segs S0-S15 = outputs
  LCDAVCTL0 = LCDCPEN;                       // Enable LCDA charge pump
  LCDAVCTL1 = VLCD_3_44;                     // to 3.26V
}


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

void main(void)
{
  volatile unsigned int i;                                                         
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  
  SCFI0 |= FN_3;                            // Set DCO operating range
  SCFQCTL = 121;                            // (121+1) x 32768 x 2 = 7.99 Mhz
  FLL_CTL0 = DCOPLUS + XCAP14PF;            // DCO+ set so freq = xtal x D x N+1
  for (i = 0; i < 10000; i++);              // Delay for 32 kHz crystal to
  

  P1OUT = 0;                            // All P1.x reset
  P1IES = 0xC0;                         // P1.0, P1.1 hi/low edge
  P1DIR = 0x3F;                         // P1.0/1 = input (switches)
  P6DIR = 0xFF;                         // All P6.x outputs
  P6OUT = 0;                            // All P6.x reset
  P5SEL  = 0x1C;                            // Set COM pins for LCD
  
  mlx90614_GND_0();    //powr supply
  mlx90614_POW_1();
  
  Init_LCD();
  LCD_CHECK();
  while (1)
  {
    unsigned long int i;
    unsigned long int DATA;
                              
    DATA=MEM_READ(0x5a,0x07);
    CALTEMP(DATA);
     
     //start_bit();
     //A4=1; A5=2; A6=3; A7=4; A8=5;
     
     LCDMEM[0] |= a + f + e +d + h;
     
     LCDMEM[1] = char_gen[A5 & 0x0f];
     LCDMEM[2] = char_gen[A4 & 0x0f];
     LCDMEM[3] = char_gen[A3 & 0x0f];
     LCDMEM[3] |= h;
     LCDMEM[4] = char_gen[A2 & 0x0f];
     LCDMEM[5] = char_gen[A1 & 0x0f];
  
     for (i = 0; i < 0x20000; i++);             // Delay  
     for (i = 0; i < 0x20000; i++);             // Delay
     
  }
}

回复评论 (1)

5c71b444a4732d732fbd0e12d067f1f.png  

点赞  2023-12-5 10:05
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复