qq_41458013
qq_41458013
2019-05-13 19:27

基于STC89c52cpu,以MLX90615传感器测温,无法读出温度数据

80
  • c语言

我要做以STC89C52单片机为基础,MLX90615为测温传感器的一个测温仪,我下载了网上的程序,一开始连接硬件,拷入程序后可以直接测温,但是有一天程序突然测不了温了,做了很多尝试,找了其他人写的程序,但是接上温度传感器单片机还是没有反应,原来能测温的程序最后lcd分别显示-273.150,727.970,77.730,67.490数值,然后就不动了
做过改动有改变SDA,SCL的上拉电阻,修改延时程序,使用其他的STC89C52开发板,更换传感器,重新焊接面包板连电路。
图片说明
图片说明

只能求助大家了。以下是我找的程序,做了些修改,先只粘上有关MLX90615的程序:

#include "LCD1602.h" 
#include "reg52.h"
#include "MLX90615.h"
#include "delay.h"
#include "stdio.h"

sbit KEY=P3^2;        // 定义按键

unsigned char s[20];  // 待显示的字符串
float temp;           // 温度值

void main()
{
    unsigned char RunStatus=0;          // 是否测量标志
    unsigned char SlaveAddress;               // Contains device address
  unsigned char command;                    // Contains the access command
  unsigned int  tdata;                      // Contains data value  
  SlaveAddress=SA<<1;                             // Set device address
  command=RAM_Access|RAM_To;            // Form RAM access command + RAM address    
    MLX90615_init();
    LCD1602_init();
    write_string(0,0,"Press the KEY");
    write_string(1,0,"to start");

    while(1)
    {       
        if(RunStatus)
        {
            tdata=MemRead(SlaveAddress,command); //Read memory
            temp = (float)tdata*0.02-273.15;
            clean_screen();
            write_string(0,0,"Measuring");
            sprintf(s,"%.3f C");
            s[6]=0xDF;
            write_string(1,0,s);
            delay_ms(400);
        }

        if(!KEY)
        {
            delay_ms(20);
            if(!KEY)
            {
                if(RunStatus)
                {
                    RunStatus=0;
                    clean_screen();
                    write_string(0,0,"Press the KEY");
                    write_string(1,0,"to start");
                }
                else
                {
                    RunStatus=1;
                    clean_screen();
                    write_string(0,0,"Measuring");
                }
                while(!KEY);
            }
        }
    }
}


#include "MLX90615.h"
#include "intrins.h"
#include "delay.h"
#include "UART.h"

#define _NOP() _nop_()

// 5us
void delay_Tbuf()
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=1;a>0;a--);
}


void delay_Thd()
{
    _nop_(); 
}

void MLX90615_init(void) 
{ 
  mSDA_OUT;    // Set SDA as Output 
  mSCL_OUT;    // Set SCL as Output 
  mSDA_HIGH(); // bus free 
  mSCL_HIGH(); 
} 

void START_bit(void)
{       
    mSDA_OUT;
    mSDA_HIGH();            // Set SDA line
    delay_Tbuf();         // Wait a few microseconds
    mSCL_HIGH();            // Set SCL line
    delay_Tbuf();         // Generate bus free time between Stop
                                  // and Start condition (Tbuf=4.7us min)
    mSDA_LOW();             // Clear SDA line
    delay_Tbuf();         // Hold time after (Repeated) Start
                                  // Condition. After this period, the first clock is generated.
                                  //(Thd:sta=4.0us min)
    mSCL_LOW();             // Clear SCL line 
    delay_Tbuf();         // Wait a few microseconds        
}

void STOP_bit(void)
{       
    mSDA_OUT;
    mSCL_LOW();             // Clear SCL line
    delay_Tbuf();         // Wait a few microseconds
    mSDA_LOW();             // Clear SDA line
    delay_Tbuf();         // Wait a few microseconds
    mSCL_HIGH();            // Set SCL line
    delay_Tbuf();         // Stop condition setup time(Tsu:sto=4.0us min)
    mSDA_HIGH();            // Set SDA line
}

unsigned char TX_byte(unsigned char Tx_buffer)
{
    unsigned char   Bit_counter;
    unsigned char   Ack_bit;
    unsigned char   bit_out;

    for(Bit_counter=8; Bit_counter; Bit_counter--)
    {
        if(Tx_buffer&0x80) 
            bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out
        else               
            bit_out=0; // else clear bit_out

        send_bit(bit_out);            // Send the current bit on SDA
        Tx_buffer<<=1;                // Get next bit for checking
    }

    Ack_bit=Receive_bit();            // Get acknowledgment bit

    return  Ack_bit;
}// End of TX_bite()

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())                       // Get a bit from the SDA line
        {
            RX_buffer <<= 1;                    // If the bit is HIGH save 1  in RX_buffer
            RX_buffer |=0x01;
        }
        else
        {
            RX_buffer <<= 1;                    // If the bit is LOW save 0 in RX_buffer 
            RX_buffer &=0xfe;   
        }
    }

    send_bit(ack_nack);                         // Sends acknowledgment bit

    return RX_buffer;
}

//---------------------------------------------------------------------------------------------
void send_bit(unsigned char bit_out)
{       
    mSDA_OUT;
    if(bit_out) 
        mSDA_HIGH();      
    else           
        mSDA_LOW();

    delay_Thd();                            // Tsu:dat = 250ns minimum

    mSCL_HIGH();                    // Set SCL line
    delay_Tbuf();           // High Level of Clock Pulse------------------
    mSCL_LOW();                     // Clear SCL line
    delay_Tbuf();           // Low Level of Clock Pulse----------------------
//  mSDA_HIGH();                    // Master release SDA line ,

    return;
}//End of send_bit()
//---------------------------------------------------------------------------------------------

unsigned char Receive_bit(void)
{
    unsigned char Ack_bit;

    mSDA_IN;                          // SDA-input
    _NOP();_NOP();_NOP();
    mSCL_HIGH();                    // Set SCL line
    delay_Tbuf();                 // High Level of Clock Pulse
//  if(P2Input(BIT2))   
    SDA=1;
    if(SDA) 
        Ack_bit=1;              // \ Read acknowledgment bit, save it in Ack_bit
    else        
        Ack_bit=0;              // /
    mSCL_LOW();                     // Clear SCL line
    delay_Tbuf();                 // Low Level of Clock Pulse

    return  Ack_bit;
}//End of Receive_bit

unsigned int MemRead(unsigned char SlaveAddress,unsigned char command)
{
    unsigned int  tdata;                // Data storage (DataH:DataL)
    unsigned char Pec;                  // PEC byte storage
    unsigned char DataL;                // Low data byte storage
    unsigned char DataH;                // High data byte storage
    unsigned char arr[6];               // Buffer for the sent bytes
    unsigned char PecReg;               // Calculated PEC byte storage
    unsigned char ErrorCounter;     // Defines the number of the attempts for communication with MLX90614

    ErrorCounter=0x00;                  // Initialising of ErrorCounter

    do{
    repeat:
        STOP_bit();                         //If slave send NACK stop comunication  
        --ErrorCounter;                   //Pre-decrement ErrorCounter
        if(!ErrorCounter){              //ErrorCounter=0?
            break;                            //Yes,go out from do-while{}
        }
        START_bit();                        //Start condition

        if(TX_byte(SlaveAddress)){  //Send SlaveAddress
            goto    repeat;                 //Repeat comunication again
        }

        if(TX_byte(command)){           //Send command  
            goto    repeat;                 //Repeat comunication again
        }
        START_bit();                        //Repeated Start condition

        if(TX_byte(SlaveAddress)){  //Send SlaveAddress-------------------???
            goto    repeat;             //Repeat comunication again
        }

        DataL=RX_byte(ACK);             //Read low data,master must send ACK
        DataH=RX_byte(ACK);             //Read high data,master must send ACK
        Pec=RX_byte(NACK);              //Read PEC byte, master must send NACK
        STOP_bit();                         //Stop condition


        arr[5]=SlaveAddress;            //
        arr[4]=command;                   //
        arr[3]=SlaveAddress;            //Load array arr 
        arr[2]=DataL;                       //
        arr[1]=DataH;                       //
        arr[0]=0;                             //
        PecReg=PEC_calculation(arr);//Calculate CRC

    }while(PecReg != Pec);          //If received and calculated CRC are equal go out from do-while{}

    *((unsigned char *)(&tdata))=DataH;    // 
    *((unsigned char *)(&tdata)+1)=DataL;  //data=DataH:DataL

    return tdata;                           
}

unsigned char PEC_calculation(unsigned char pec[])
{
    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 transmited message
        i=5;                    /* Set highest index */
        j=0;
        while((pec[i]&(0x80>>j))==0 && i>0){
            BitPosition--;
            if(j<7){
                j++;
            }
            else{
                j=0x00;
                i--;
            }
        }/*End of while */

        shift=BitPosition-8;    /*Get shift value for crc value*/


        //Shift crc value 
        while(shift){
            for(i=5; i<0xFF; i--){
                if((crc[i-1]&0x80) && (i>0)){
                    temp=1;
                }
                else{
                    temp=0;
                }
                crc[i]<<=1;
                crc[i]+=temp;
            }/*End of for*/
            shift--;
        }/*End of while*/


        //Exclusive OR between pec and crc      
        for(i=0; i<=5; i++){
            pec[i] ^=crc[i];
        }/*End of for*/
    }while(BitPosition>8);/*End of do-while*/

    return pec[0];
}/*End of PEC_calculation*/


#ifndef __MLX90615_H
#define __MLX90615_H

#include "reg52.h"

sbit SDA = P2^0;                           
sbit SCL = P2^1;             

#define mSDA_IN       do{} while(0)
#define mSDA_OUT      do{} while(0)
#define mSCL_IN       do{} while(0)
#define mSCL_OUT      do{} while(0)

#define ACK       0
#define NACK      1

//MLX90614 constants
#define SA                0x00  // Slave address
#define DEFAULT_SA      0x5B    // Default Slave address
#define RAM_Access      0x20    // RAM access command
#define EEPROM_Access   0x10    // EEPROM access command
#define RAM_Ta          0x06    // Ta address in the ram
#define RAM_To          0x07    // To address in the ram

//*PROTOTYPES**********************************************************************************
void start_bit(void);
void STOP_bit(void);
void TX_byte(unsigned char Tx_buffer);
unsigned char RX_byte(unsigned char ack_nack);
void send_bit(unsigned char bit_out);
unsigned char Receive_bit(void);
void MLX90615_init(void); 
unsigned int MEM_READ(unsigned char slave_addR, unsigned char cmdR);
void SendRequest(void);
void DummyCommand(unsigned char byte);
unsigned int *CALTEMP(unsigned long int TEMP);
unsigned char PEC_cal(unsigned char pec[],int n);
void Delay(unsigned int N);

#endif
  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

1条回答

为你推荐