CC430F5137和MLX非接触式测温,用的软件模拟IIc通讯,一直调试不通,没有ack,感觉...

2019-03-24 09:44发布

同学们好,最近做cc430f5137和mlx90614非接触式测温,软件模拟IIc和硬件IIc模块都尝试了,都收不到ack信号,做了近两个月了,附上模拟IIc的代码,跪求大神解答,希望可以有点实质性的建议,先谢谢了
#include "msp430_kyg.h"
void Init_CLK(unsigned char nDco)            //DCO_CLK 1,8,12,16MHZ------------------
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  switch(nDco)
  {
  case 1:
    UCSCTL3 |= SELREF_2+FLLREFDIV_4;          // Set DCO FLL reference = REFO,
    UCSCTL2 = FLLD_0 + 374;                   // Set DCO 1MHz
    break;
  case 8:
    UCSCTL3 |= SELREF_2+FLLREFDIV_4;          // Set DCO FLL reference = REFO,
    UCSCTL2 = FLLD_2 + 374;                   // Set DCO 8MHz
    break;
  case 12:
   UCSCTL3 |= SELREF_2+FLLREFDIV_0;                      // Set DCO FLL reference = REFO,
   UCSCTL2 = FLLD_0 + 374;                   // Set DCO Multiplier for 12MHz
  case 16:
   UCSCTL3 |= SELREF_2+FLLREFDIV_4;          // Set DCO FLL reference = REFO,
   UCSCTL2 = FLLD_3 + 374;                   // Set DCO 16MHz
    break;
  default:
    break;
  }
}

#include "mlx90615.h"
//--------------------------------------------------------------------------
//Description:  mlx90615操作函数
//write by Meredith
//2010.4.21
//email:cyberkyg@163.com
//此代码仅供学习交流使用,未经作者允许,不可用于其他用途!
//--------------------------------------------------------------------------
void MLX90615_init(void)
{
  mSDA_OUT;     // Set SDA as Output
  mSDA_LOW();
  mSCL_OUT;     // Set SCL as Output
  mSCL_HIGH();   
  mSDA_HIGH();
  SendRequest();
}

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>0; 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()

//---------------------------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------------------------

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(P1Input(BIT3))       
          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 char RX_byte(unsigned char ack_nack)
{
        unsigned char         RX_buffer;
        unsigned char        Bit_Counter;
       
        for(Bit_Counter=8; Bit_Counter>0; 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;
}
//----------------------------------------------------------------------------------------------

unsigned int MemRead(unsigned char SlaveAddress,unsigned char command)
{
        unsigned int  data;                        // 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 conditio
                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 *)(&data))=DataL;           //
        *((unsigned char *)(&data)+1)=DataH ;  //data=DataH:DataL
       
        return data;                                                       
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
void SendRequest(void)
{
        mSCL_LOW();                        //SCL 1 ____________|<-----80ms------->|______________
        _delay_ms(80);                //           0                    |__________________|
        mSCL_HIGH();
}
//---------------------------------------------------------------------------------------------
void DummyCommand(unsigned char byte)
{
        START_bit();                //Start condition
        TX_byte(byte);                //Send Slave Address or whatever,no need ACK checking
        STOP_bit();                        //Stop condition
}
//---------------------------------------------------------------------------------------------
float CalcTemp(unsigned int value)
{
        float temp;
       
        temp=(value*0.02)-273.15;
        _NOP();
       
        return temp;
}
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*/
void Init_IIC(void)
{
  P1DIR |= BIT6;
  P1OUT |= BIT6;
  /**** 输出9个时钟以恢复I2C总线状态 ****/
   for( uint i= 0; i <9 ; i++)  
  {  
    P1OUT |= BIT6;  
    __delay_cycles(8000);  
    P1OUT &= ~BIT6;  
    __delay_cycles(8000);  
  }
  mSCL_LOW();
  _delay_ms(2.5);
  mSCL_HIGH();
  mSDA_HIGH();  // bus free
}  

//----------------------------------------------------
//Description:  msp430f2274+mlx90615+ht1621
//write by Meredith
//2010.4.21
//email:cyberkyg@163.com
//
//此代码仅供学习交流使用,未经作者允许,不可用于其他用途!               
//
//其中ht1621.c是白沙兄的函数库,版权归白沙所有
//-----------------------------------------------------

//******************************************************************************
//
//
//                MSP430F2274
//             -----------------
//         /||              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |             P1.0|-->LED RED
//              |             P1.1|-->LED GREEEN
//            |             P1.2|-->key
//            |             P2.1|-->LCD DATA
//            |             P4.5|-->LCD /WR
//            |             P4.3|-->LCD /RD
//            |             P2.3|-->LCD /CS
//            |             P2.4|-->LCD /BL
//            |             P2.0|-->96015 SCL
//            |             P2.2|-->96015 SDA
//             -----------------
//
//  
//  
//  
//  Built with IAR Embedded Workbench Version: 4.21.2
//******************************************************************************
#include "cc430f5137.h"
#include "mlx90615.h"
//#include "ht1621.h"
//**********************************************************************************

//void displayTemp(unsigned int temp);


void main(void)
{       
  unsigned char SlaveAddress;                         //Contains device address
  unsigned char        command;                          //Contains the access command
  unsigned int         data;                  //Contains data value       
  float date;
  SlaveAddress=SA<<1;                                //Set device address
  command=RAM_Access|RAM_To;                 //Form RAM access command + RAM address                        
       
  Init_CLK(DCO_F);
  //lcd_init();
  //lcd_clr();
  //lcd_char(_lcd_DEGREE,1);            //显示℃标志
  //lcd_char(_lcd_DOT2,1);              //显示小数点
// Init_IIC();
  MLX90615_init();


  while(1)
  {
  //data=MemRead(SlaveAddress,command); //Read memory
  //MLX90615_init();
  data=MemRead(SlaveAddress,command);//Read memory
  date=CalcTemp(data);
  _delay_ms(10);                                               
  }
#include "cc430f5137.h"
//----------------------------------------------------
//Description:  msp430系列单片机常用端口位操作
//write by Meredith
//2007.5.1
//email:cyberkyg@163.com
//
//modify at 2010.4.21
//-----------------------------------------------------
#ifndef _MSP430_KYG_H_
#define _MSP430_KYG_H_

#define U8 unsigned char
#define U16 unsigned int
#define uint  unsigned int
#define uchar unsigned char

//----------------IO bits Set/Clr---------------------
#define ClrP1(n) P1OUT&=(~n)
#define SetP1(n) P1OUT|=n
/*#define ClrP2(n) P2OUT&=(~n)
#define SetP2(n) P2OUT|=n
#define ClrP3(n) P3OUT&=(~n)
#define SetP3(n) P3OUT|=n
#define ClrP4(n) P4OUT&=(~n)
#define SetP4(n) P4OUT|=n
#define ClrP5(n) P5OUT&=(~n)
#define SetP5(n) P5OUT|=n
#define ClrP6(n) P6OUT&=(~n)
#define SetP6(n) P6OUT|=n*/
//--------------------IO bits Input/Output--------------------------
#define SetInP1(n) P1DIR&=(~n)
#define SetOutP1(n) P1DIR|=n
/*#define SetInP2(n) P2DIR&=(~n)
#define SetOutP2(n) P2DIR|=n
#define SetInP3(n) P3DIR&=(~n)
#define SetOutP3(n) P3DIR|=n
#define SetInP4(n) P4DIR&=(~n)
#define SetOutP4(n) P4DIR|=n
#define SetInP5(n) P5DIR&=(~n)
#define SetOutP5(n) P5DIR|=n
#define SetInP6(n) P6DIR&=(~n)
#define SetOutP6(n) P6DIR|=n*/
//---------------------IO bits PULL Enabled/Disabled----------------
#define PullEnabledP1(n) P1REN|=n
#define PullDisabledP1(n) P1REN&=(~n)
#define PullEnabledP2(n) P2REN|=n
#define PullDisabledP2(n) P2REN&=(~n)
#define PullEnabledP3(n) P3REN|=n
#define PullDisabledP3(n) P3REN&=(~n)
#define PullEnabledP4(n) P4REN|=n
#define PullDisabledP4(n) P4REN&=(~n)
#define PullEnabledP5(n) P5REN|=n
#define PullDisabledP5(n) P5REN&=(~n)
#define PullEnabledP6(n) P6REN|=n
#define PullDisabledP6(n) P6REN&=(~n)
//---------------------IO bits PullUp/PullDown----------------------
#define PullDownP1(n) P1OUT&=(n)
#define PullUpP1(n) P1OUT|=n
#define PullDownP2(n) P2OUT&=(~n)
#define PullUpP2(n) P2OUT|=n
#define PullDownP3(n) P3OUT&=(~n)
#define PullUpP3(n) P3OUT|=n
#define PullDownP4(n) P4OUT&=(~n)
#define PullUpP4(n) P4OUT|=n
#define PullDownP5(n) P5OUT&=(~n)
#define PullUpP5(n) P5OUT|=n
#define PullDownP6(n) P6OUT&=(~n)
#define PullUpP6(n) P6OUT|=n
//------------------------IO bits Input-----------
#define P1Input(n) P1IN&n?1:0
#define P2Input(n) P2IN&n?1:0
#define P3Input(n) P3IN&n?1:0
#define P4Input(n) P4IN&n?1:0
#define P5Input(n) P5IN&n?1:0
#define P6Input(n) P6IN&n?1:0
//------------------------------------------------------------------------

#define DCO_F 12              //定义主时钟频率,1,8,12,16(MHZ)
#define _delay_us(n) __delay_cycles((float)(n)*DCO_F)   //20us以下误差较大
#define _delay_ms(n) __delay_cycles(n*(1000.0f)*DCO_F)
//------------------------------------------------------------------------
#define delay_Tbuf __delay_cycles(76)//16MHZ,62.5ns*76=4.75us
#define delay_Thd  __delay_cycles(5)//16MHZ,62.5ns*5=312.5ns
//----------------------------------------------------------------------------
void Init_CLK(unsigned char nDco);
#endif


#include "msp430_kyg.h"
#ifndef _MLX90615_H_
#define _MLX90615_H_
//-----------------------------------
#define mSDA_LOW()    ClrP1(BIT3)
#define mSDA_HIGH()   SetP1(BIT3)
#define mSCL_LOW()    ClrP1(BIT6)
#define mSCL_HIGH()   SetP1(BIT6)

#define mSDA_IN     SetInP1(BIT3)
#define mSDA_OUT    SetOutP1(BIT3)
#define mSCL_IN     SetInP1(BIT6)
#define mSCL_OUT    SetOutP1(BIT6)

#define ACK  0
#define        NACK 1

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

//*PROTOTYPES**********************************************************************************
void START_bit(void);
void STOP_bit(void);
unsigned char 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 MemRead(unsigned char SlaveAddress,unsigned char command);
void SendRequest(void);
void DummyCommand(unsigned char byte);
float CalcTemp(unsigned int value);
unsigned char PEC_calculation(unsigned char pec[]);
void Init_IIC(void);

#endif

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
liutingkd
1楼-- · 2019-03-24 19:48
邮箱是1257950730@qq.com,有消息麻烦联系我
exiao
2楼-- · 2019-03-24 21:53
 精彩回答 2  元偷偷看……

一周热门 更多>

相关问题

    相关文章