本帖最后由 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);
-
- }
- }
复制代码
MSP430x42x0还是msp430x54x?
用的什么传感器?
你用的SMBus方式读取?
对,SMBus方式,您看是哪里的问题呢
嗯,或者用逻辑分析仪也可以,没有太好的办法。
或者读写其他寄存器试试,看能不能正确通讯
一周热门 更多>