MSP430编译MLX90614失败

    科技2026-02-24  6

    在用MSP430G2553调试MLX90614红外测温传感器时,输出的值始终为-273.1,我认为应该是读取寄存器内容为0所致,我的程序使用STM32程序修改后进行调试的,原32程序输出正确,但误差较大。修改前后的程序时序相同,但就是无法使用MSP430进行调试,想请大神帮忙看看是哪里有问题。 原32程序详见:https://blog.csdn.net/qq_39400113/article/details/107099944?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.add_param_isCf

    以下为430程序,求指教: #define MCLK 8000000 #define CPU_F ((double)MCLK)

    #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) // MS级延时函数

    #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) // US级延时函数

    #define delay_s(x) __delay_cycles((long)(CPU_F*(double)x/1.0)) // S级延时函数

    #define ACK 0 #define NACK 1 //不应答或否定的应答 #define SA 0x5A //从机地址,单个MLX90614时地址为0x00,多个时地址默认为0x5a #define RAM_ACCESS 0x00 //RAM access command #define EEPROM_ACCESS 0x20 //EEPROM access command #define RAM_TOBJ1 0x07 //To1 address in the eeprom

    #define SDA_OUT P2DIR|=BIT3 #define SDA_H P2OUT|=BIT3 #define SDA_L P2OUT&=~BIT3 #define SDA_IN P2DIR&=~BIT3 #define SDA ((P2IN&BIT3)>>1)

    #define SCL_OUT P2DIR|=BIT4 //SCL低电平时,SDA管脚上数据发生改变;SCL上升沿,MD和SD读取数据 #define SCL_H P2OUT|=BIT4 #define SCL_L P2OUT&=~BIT4

    volatile unsigned int x=2; unsigned char PEC; //错误代码包 unsigned char TEMPL; unsigned char TEMPH;

    void SMBus_StartBit(void); void SMBus_StopBit(void); void SMBus_SendBit(unsigned char); unsigned char SMBus_SendByte(unsigned char); unsigned char SMBus_ReceiveBit(void); unsigned char SMBus_ReceiveByte(unsigned char); unsigned short SMBus_ReadMemory(unsigned char, unsigned char); unsigned char PEC_Calculation(unsigned char*); float SMBus_ReadTemp(void);

    void mlx09614_init() //传感器初始化 { SDA_OUT; SCL_OUT; P2REN|=BIT3+BIT4; P2OUT &= ~ BIT3 + BIT4;

    } /*******************************************************************************

    函数名: MLX90614MLX90614 发起始位 SMBus_StartBit功能 : MLX90614 发起始位 产生起始位Input : NoneOutput : NoneReturn : None

    *******************************************************************************/ void SMBus_StartBit(void) { SDA_H; // Set SDA line delay_us(20); // Wait a few microseconds SCL_H; // Set SCL line delay_us(20); // Generate bus free time between Stop SDA_L; // Clear SDA line delay_us(20); // Hold time after (Repeated) Start // Condition. After this period, the first clock is generated. //(Thd:sta=4.0us min)在SCK=1时,检测到SDA由1到0表示通信开始(下降沿) SCL_L; // Clear SCL line delay_us(20); // Wait a few microseconds }

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

    函数名: SMBus_StopBit功能: MLX90614 发停止位 STOP condition on SMBusInput : NoneOutput : NoneReturn : None *******************************************************************************/ void SMBus_StopBit(void) { SCL_L; // Clear SCL line delay_us(20); // Wait a few microseconds SDA_L; // Clear SDA line delay_us(20); // Wait a few microseconds SCL_H; // Set SCL line delay_us(20); // Stop condition setup time(Tsu:sto=4.0us min) SDA_H; // Set SDA line }

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

    函数名: SMBus_SendByte

    功能: MLX90614 发送一个字节 Send a byte on SMBus

    Input : Tx_buffer

    Output : None

    Return : None *******************************************************************************/ unsigned char SMBus_SendByte(unsigned char Tx_buffer) { unsigned char Bit_counter; unsigned char Ack_bit; volatile unsigned char bit_out;

    for(Bit_counter=8; Bit_counter; Bit_counter–) { if (Tx_buffer&0x80)//如果最高位为1 { bit_out=1; // 把最高位置1 } else //如果最高位为0 { bit_out=0; // 把最高位置0 } SMBus_SendBit(bit_out); // 把最高位发送出去 Tx_buffer<<=1;// 左移一位把最高位移出去等待下一个最高位,循环8次,每次都发最高位,就可把一个字节发出去了 } Ack_bit=SMBus_ReceiveBit(); return Ack_bit; }

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

    函数名: SMBus_SendBit功能: MLX90614 发送一个位 Send a bit on SMBus 82.5kHzInput : bit_outOutput : NoneReturn : None *******************************************************************************/ void SMBus_SendBit(unsigned char bit_out) { SDA_OUT; if(bit_out==0) { SDA_L; } else { SDA_H; } delay_us(8); // Tsu:dat = 250ns minimum SCL_H; // Set SCL line delay_us(24); // High Level of Clock Pulse SCL_L; // Clear SCL line delay_us(12); // Low Level of Clock Pulse // SMBUS_SDA_H(); // Master release SDA line , return; }

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

    Function Name : SMBus_ReceiveBit

    Description : Receive a bit on SMBus

    Input : None

    Output : None

    Return : Ack_bit *******************************************************************************/ unsigned char SMBus_ReceiveBit(void) { unsigned char Ack_bit;

    SDA_IN; //引脚输入 SDA_H; delay_us(8); // High Level of Clock Pulse SCL_H; // Set SCL line delay_us(20); // High Level of Clock Pulse if (SDA) { Ack_bit=1; } else { Ack_bit=0; } SCL_L; // Clear SCL line delay_us(12); // Low Level of Clock Pulse

    return Ack_bit; }

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

    函数名: SMBus_ReceiveByte

    功能: Receive a byte on SMBus 从SMBus中接受一个字节的数据

    Input : ack_nack

    Output : None

    Return : RX_buffer *******************************************************************************/ unsigned char SMBus_ReceiveByte(unsigned char ack_nack) { unsigned char RX_buffer; unsigned char Bit_Counter;

    for(Bit_Counter=8; Bit_Counter; Bit_Counter–) { if(SMBus_ReceiveBit())// Get a bit from the SDA line { RX_buffer <<= 1;// If the bit is HIGH save 1 in RX_buffer RX_buffer |=0x01;//如果Ack_bit=1,把收到应答信号1与0000 0001 进行或运算,确保为1 } else { RX_buffer <<= 1;// If the bit is LOW save 0 in RX_buffer RX_buffer &=0xfe;//如果Ack_bit=1,把收到应答信号0与1111 1110 进行与运算,确保为0 } } SMBus_SendBit(ack_nack);// Sends acknowledgment bit 把应答信号发出去,如果1,就进行下一次通信,如果为0、,就拜拜了 return RX_buffer; }

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

    函数名: SMBus_ReadMemory

    功能: READ DATA FROM RAM/EEPROM 从RAM和EEPROM中读取数据

    Input : slaveAddress, command

    Return : Data

    SMBus_ReadMemory(0x00, 0x07) 0x00 表示IIC设备的从地址 从0x07这个寄存器开始读取 *******************************************************************************/ unsigned short SMBus_ReadMemory(volatile unsigned char slaveAddress, unsigned char command) { unsigned short data; // Data storage (DataH:DataL) unsigned char Pec; // PEC byte storage unsigned char DataL=0; // Low data byte storage unsigned char DataH=0; // 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 slaveAddress <<= 1; //2-7位表示从机地址 从机地址左移一位,把读写位空出来

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

    SMBus_StartBit(); //Start condition if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令 { goto repeat; //Repeat comunication again } if(SMBus_SendByte(command)) //Send command { goto repeat; //Repeat comunication again } SMBus_StartBit(); //Repeated Start condition if(SMBus_SendByte(slaveAddress+1)) //Send SlaveAddress 最低位Rd=1表示接下来读数据 { goto repeat; //Repeat comunication again } DataL = SMBus_ReceiveByte(ACK); //Read low data,master must send ACK DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK Pec = SMBus_ReceiveByte(NACK); //Read PEC byte, master must send NACK SMBus_StopBit(); //Stop condition arr[5] = slaveAddress; // arr[4] = command; // arr[3] = slaveAddress+1; //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{}

    data = (DataH<<8) | DataL; //data=DataH:DataL return data; }

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

    函数名: PEC_calculation

    功能 : 数据校验

    Input : pec[]

    Output : None

    Return : pec[0]-this byte contains calculated crc value ******************************************************************************/ unsigned char PEC_Calculation(unsigned char pec[]) { unsigned char crc[6];//存放多项式 unsigned char BitPosition=47;//存放所有数据最高位,68=48 最高位就是47位 unsigned char shift; unsigned char i; unsigned char j; unsigned char temp;

    do { /Load pattern value 0x00 00 00 00 01 07/ crc[5]=0; crc[4]=0; crc[3]=0; crc[2]=0; crc[1]=0x01; crc[0]=0x07;

    /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/ BitPosition=47; /*Set shift position at 0*/ shift=0; /*Find first "1" in the transmited message beginning from the MSByte byte5*/ i=5; j=0; while((pec[i]&(0x80>>j))==0 && i>0) { BitPosition--; if(j<7) { j++; } else { j=0x00; i--; } }/*End of while */ /*Get shift value for pattern value*/ shift=BitPosition-8; /*Shift pattern 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]; }

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

    函数名: SMBus_ReadTemp功能: 计算并返回温度值Return : SMBus_ReadMemory(0x00, 0x07)*0.02-273.15 ******************************************************************************/ float SMBus_ReadTemp(void) { float temp; unsigned long i; i=SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1); temp = i0.02-273.15; return temp; }
    Processed: 0.011, SQL: 9