kuoo 发表于 2015-4-15 09:13:19

【求助】路虎LPC1768-IIC模块LM75如何工作?程序无法实现?..

【求助】路虎LPC1768-IIC模块LM75如何工作?程序无法实现?
IC用的是LM75B ,测试温度发送到串口0上··
以下是程序代码:


/****************************************Copyright (c)****************************************************
**                                 http://www.PowerAVR.com
**                                                                   http://www.PowerMCU.com
**--------------File Info---------------------------------------------------------------------------------
** File name:         uart.c
** Last modified Date:2010-05-12
** Last Version:      V1.00
** Descriptions:      
**
**--------------------------------------------------------------------------------------------------------
** Created by:          PowerAVR
** Created date:      2010-05-10
** Version:             V1.00
** Descriptions:      编写示例代码
**
**--------------------------------------------------------------------------------------------------------      
*********************************************************************************************************/
#include "lpc17xx.h"                              /* LPC17xx definitions    */
#include "uart.h"
#include "stdarg.h"
#include "stdio.h"
#define FOSC                        12000000                            /*振荡器频率                  */

#define FCCLK                      (FOSC* 8)                        /*主时钟频率<=100Mhz          */
                                                                        /*FOSC的整数倍                */
#define FCCO                     (FCCLK * 3)                        /*PLL频率(275Mhz~550Mhz)      */
                                                                        /*与FCCLK相同,或是其的偶数倍 */
#define FPCLK                      (FCCLK / 4)                        /*外设时钟频率,FCCLK的1/2、1/4*/
                                                                        /*或与FCCLK相同               */

#define UART0_BPS   115200                                             /* 串口0通信波特率             */
#define UART2_BPS   115200                                             /* 串口2通信波特率             */
/*********************************************************************************************************
** Function name:       UART0_Init
** Descriptions:      按默认值初始化串口0的引脚和通讯参数。设置为8位数据位,1位停止位,无奇偶校验
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void UART0_Init (void)
{
        uint16_t usFdiv;
    /* UART0 */
    LPC_PINCON->PINSEL0 |= (1 << 4);             /* Pin P0.2 used as TXD0 (Com0) */
    LPC_PINCON->PINSEL0 |= (1 << 6);             /* Pin P0.3 used as RXD0 (Com0) */

        LPC_UART0->LCR= 0x83;                      /* 允许设置波特率               */
    usFdiv = (FPCLK / 16) / UART0_BPS;         /* 设置波特率                   */
    LPC_UART0->DLM= usFdiv / 256;
    LPC_UART0->DLL= usFdiv % 256;
    LPC_UART0->LCR= 0x03;                      /* 锁定波特率                   */
    LPC_UART0->FCR= 0x06;                                   
}


void Print_String(char *prt)
{
        while(*prt != '\0')
        putch(*prt++);
}


void putch(uint8_t k)         //发送
{
        if(k == '\n')
        {
                LPC_UART0->THR = k;
                while((LPC_UART0->LSR & LSR_THRE) == 0);
        }
        else
        {
                LPC_UART0->THR = k;
                while((LPC_UART0->LSR & LSR_THRE) == 0);
        }       
}
/*********************************************************************************************************
** Function name:       UART0_SendByte
** Descriptions:      从串口0发送数据
** input parameters:    data: 发送的数据
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
int UART0_SendByte (int ucData)
{
        while (!(LPC_UART0->LSR & 0x20));
    return (LPC_UART0->THR = ucData);
}

/*----------------------------------------------------------------------------
Read character from Serial Port   (blocking read)
*----------------------------------------------------------------------------*/
int UART0_GetChar (void)
{
        while (!(LPC_UART0->LSR & 0x01));
        return (LPC_UART0->RBR);
}

/*********************************************************************************************************
Write character to Serial Port
** Function name:       UART0_SendString
** Descriptions:          向串口发送字符串
** input parameters:    s:   要发送的字符串指针
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void UART0_SendString (unsigned char *s)
{
        while (*s != 0)
        {
                   UART0_SendByte(*s++);
        }
}


void Uart0_Printf(const char *fmt,...)//
{
        va_list ap;           //This is support the format output
    char string;
    va_start(ap,fmt);
    vsprintf(string,fmt,ap); // Store the string in the String buffer
    Print_String(string);
    va_end(ap);       
}


/*********************************************************************************************************
** Function name:       UART2_Init
** Descriptions:      按默认值初始化串口2的引脚和通讯参数。设置为8位数据位,1位停止位,无奇偶校验
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void UART2_Init (void)
{
        uint16_t usFdiv;
    /* UART2 */
    LPC_PINCON->PINSEL0 |= (1 << 20);             /* Pin P0.10 used as TXD2 (Com2) */
    LPC_PINCON->PINSEL0 |= (1 << 22);             /* Pin P0.11 used as RXD2 (Com2) */

           LPC_SC->PCONP = LPC_SC->PCONP|(1<<24);              /*打开UART2电源控制位                   */

    LPC_UART2->LCR= 0x83;                     /* 允许设置波特率                */
    usFdiv = (FPCLK / 16) / UART2_BPS;            /* 设置波特率                  */
    LPC_UART2->DLM= usFdiv / 256;
    LPC_UART2->DLL= usFdiv % 256;
    LPC_UART2->LCR= 0x03;                     /* 锁定波特率                  */
    LPC_UART2->FCR= 0x06;
}

/*********************************************************************************************************
** Function name:       UART2_SendByte
** Descriptions:      从串口2发送数据
** input parameters:    data: 发送的数据
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
int UART2_SendByte (int ucData)
{
        while (!(LPC_UART2->LSR & 0x20));
    return (LPC_UART2->THR = ucData);
}

/*----------------------------------------------------------------------------
Read character from Serial Port   (blocking read)
*----------------------------------------------------------------------------*/
int UART2_GetChar (void)
{
        while (!(LPC_UART2->LSR & 0x01));
        return (LPC_UART2->RBR);
}

/*********************************************************************************************************
** Write character to Serial Port
** Function name:       UART2_SendString
** Descriptions:          向串口发送字符串
** input parameters:    s:   要发送的字符串指针
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void UART2_SendString (unsigned char *s)
{
        while (*s != 0)
        {
                   UART2_SendByte(*s++);
        }
}

void UART0_SendChar(uint16_t disp)
{
        uint16_t dispbuf;
        uint8_t i;

        dispbuf = disp%10 + '0';
        dispbuf = disp/10%10 + '0';
        dispbuf = disp/10/10%10 + '0';
        dispbuf = disp/10/10/10%10 + '0';
        for(i=0;i<4;i++)
                UART0_SendByte(dispbuf);       
}



/*****************************************************************************
*   i2c.c:I2C C file for NXP LPC17xx Family Microprocessors
*
*   Copyright(C) 2009, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2009.05.26ver 1.00    Prelimnary version, first Release
*
*****************************************************************************/
#include "lpc17xx.h"
#include "i2c.h"
#include "uart.h"
volatile uint32_t I2CMasterState = I2C_IDLE;
volatile uint32_t I2CSlaveState = I2C_IDLE;

volatile uint32_t I2CCmd;
volatile uint32_t I2CMode;

volatile uint8_t I2CMasterBuffer;
volatile uint8_t I2CSlaveBuffer;
volatile uint32_t I2CCount = 0;
volatile uint32_t I2CReadLength;
volatile uint32_t I2CWriteLength;

volatile uint32_t RdIndex = 0;
volatile uint32_t WrIndex = 0;

/*
From device to device, the I2C communication protocol may vary,
in the example below, the protocol uses repeated start to read data from or
write to the device:
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO
for master write: the sequence is: STA,Addr(W),length,RE-STA,Addr(w),data...STO
Thus, in state 8, the address is always WRITE. in state 10, the address could
be READ or WRITE depending on the I2CCmd.
*/   

/*****************************************************************************
** Function name:                I2C0_IRQHandler
**
** Descriptions:                I2C0 interrupt handler, deal with master mode
**                                                only.
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void I2C0_IRQHandler(void)//主发送和主接受模式
{


    uint8_t StatValue;          
   // Uart0_Printf("11111");

/* this handler deals with master read and master write only */
StatValue = LPC_I2C0->I2STAT;
       
switch ( StatValue )               //状态码详细对应
{
        case 0x08:                        /* A Start condition is issued. */

//        Uart0_Printf("2222");
        LPC_I2C0->I2DAT = I2CMasterBuffer;
        LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);//中断标志清零-启始标志清零
        I2CMasterState = I2C_STARTED;   //1
        break;
       
        case 0x10:                        /* A repeated started is issued */
        if ( I2CCmd == LM75_TEMP )
        {
          LPC_I2C0->I2DAT = I2CMasterBuffer;// 装入SLA+W,变为主接受模式
        }
        LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
        I2CMasterState = I2C_RESTARTED;//2
        break;
       
        case 0x18:                        /* Regardless, it's a ACK */
        if ( I2CMasterState == I2C_STARTED )
        {
          LPC_I2C0->I2DAT = I2CMasterBuffer;//1+0      ------------
          WrIndex++;
          I2CMasterState = DATA_ACK;   //4
        }
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x28:        /* Data byte has been transmitted, regardless ACK or NACK */
        case 0x30:
        if ( WrIndex != I2CWriteLength )
        {   
          LPC_I2C0->I2DAT = I2CMasterBuffer; /* this should be the last one */
          WrIndex++;
          if ( WrIndex != I2CWriteLength )
          {   
                I2CMasterState = DATA_ACK;
          }
          else
          {
                I2CMasterState = DATA_NACK;
                if ( I2CReadLength != 0 )
                {
                  LPC_I2C0->I2CONSET = I2CONSET_STA;        /* Set Repeated-start flag *///
                  I2CMasterState = I2C_REPEATED_START;
                }
          }
        }
        else
        {
          if ( I2CReadLength != 0 )
          {
                LPC_I2C0->I2CONSET = I2CONSET_STA;        /* Set Repeated-start flag */
                I2CMasterState = I2C_REPEATED_START;
          }
          else
          {
                I2CMasterState = DATA_NACK;
                LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
          }
        }
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
        break;
       
        case 0x40:        /* Master Receive, SLA_R has been sent */
        LPC_I2C0->I2CONSET = I2CONSET_AA;        /* assert ACK after data is received */
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
        break;
       
        case 0x50:        /* Data byte has been received, regardless following ACK or NACK */
        case 0x58:
        I2CMasterBuffer = LPC_I2C0->I2DAT;//---------------------------------------
        RdIndex++;
        if ( RdIndex != I2CReadLength )
        {   
          I2CMasterState = DATA_ACK;
        }
        else
        {
          RdIndex = 0;
          I2CMasterState = DATA_NACK;
        }
        LPC_I2C0->I2CONSET = I2CONSET_AA;        /* assert ACK after data is received */
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
        break;
       
        case 0x20:                /* regardless, it's a NACK */

        case 0x48:
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
        I2CMasterState = DATA_NACK;
        break;
       
        case 0x38:                /* Arbitration lost, in this example, we don't
                                        deal with multiple master situation */
        default:
        LPC_I2C0->I2CONCLR = I2CONCLR_SIC;       
        break;
}
}

/*****************************************************************************
** Function name:                I2CStart
**
** Descriptions:                Create I2C start condition, a timeout
**                                value is set if the I2C never gets started,
**                                and timed out. It's a fatal error.
**
** parameters:                        None
** Returned value:                true or false, return false if timed out
**
*****************************************************************************/
uint32_t I2CStart( void )
{
uint32_t timeout = 0;
uint32_t retVal = 0;

/*--- Issue a start condition ---*/
LPC_I2C0->I2CONSET = I2CONSET_STA;        /* Set Start flag */
   
/*--- Wait until START transmitted ---*/
while( 1 )
{
        if ( I2CMasterState == I2C_STARTED )
        {
          retVal = 1;
          break;       
        }
        if ( timeout >= MAX_TIMEOUT )
        {
          retVal = 0;
          break;
        }
        timeout++;
}
return( retVal );
}

/*****************************************************************************
** Function name:                I2CStop
**
** Descriptions:                Set the I2C stop condition, if the routine
**                                never exit, it's a fatal bus error.
**
** parameters:                        None
** Returned value:                true or never return
**
*****************************************************************************/
uint32_t I2CStop( void )
{
LPC_I2C0->I2CONSET = I2CONSET_STO;/* Set Stop flag */
LPC_I2C0->I2CONCLR = I2CONCLR_SIC;/* Clear SI flag */
            
/*--- Wait for STOP detected ---*/
while( LPC_I2C0->I2CONSET & I2CONSET_STO );
return 1;
}

/*****************************************************************************
** Function name:                I2CInit
**
** Descriptions:                Initialize I2C controller
**
** parameters:                        I2c mode is either MASTER or SLAVE
** Returned value:                true or false, return false if the I2C
**                                interrupt handler was not installed correctly        //哪里返回0????
**
*****************************************************************************/
uint32_t I2CInit( uint32_t I2cMode )
{
// LPC_SC->PCONP |= (1 << 7);

/* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */
/* function to 01 on both SDA and SCK. */
LPC_PINCON->PINSEL1 &= ~0x03C00000;
//LPC_PINCON->PINSEL1=0x01400000;
LPC_PINCON->PINSEL1 |= 0x01400000;       

/*--- Clear flags ---*/
LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;   //写1清零相应的位

/*--- Reset registers ---*/
LPC_I2C0->I2SCLL   = I2SCLL_SCLL;          //PCLK_I2C多少???
LPC_I2C0->I2SCLH   = I2SCLH_SCLH;
if ( I2cMode == I2CSLAVE )
{
        LPC_I2C0->I2ADR0 = LM75_ADDR;                //此寄存器只有在从模式下才有用·          如何表示地址?????
}   

/* Install interrupt handler */
NVIC_EnableIRQ(I2C0_IRQn);

LPC_I2C0->I2CONSET = I2CONSET_I2EN;       //IIC接口使能
return( 1 );
}

/*****************************************************************************
** Function name:                I2CEngine
**
** Descriptions:                The routine to complete a I2C transaction
**                                from start to stop. All the intermitten
**                                steps are handled in the interrupt handler.
**                                Before this routine is called, the read
**                                length, write length, I2C master buffer,
**                                and I2C command fields need to be filled.
**                                see i2cmst.c for more details.
**
** parameters:                        None
** Returned value:                true or false, return false only if the
**                                start condition can never be generated and
**                                timed out.
**
*****************************************************************************/
uint32_t I2CEngine( void )
{
I2CMasterState = I2C_IDLE;
RdIndex = 0;
WrIndex = 0;
if ( I2CStart() != 1 )
{
        I2CStop();
        return ( 0 );
}

while ( 1 )
{
        if ( I2CMasterState == DATA_NACK )
        {
          I2CStop();
          break;
        }
}
   
return ( 1 );      
}

/******************************************************************************
**                            End Of File
******************************************************************************/

/*****************************************************************************
*   i2c.h:Header file for NXP LPC17xx Family Microprocessors
*
*   Copyright(C) 2009, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2009.05.26ver 1.00    Prelimnary version, first Release
*
******************************************************************************/
#ifndef __I2C_H
#define __I2C_H

#define BUFSIZE                        0x20
#define MAX_TIMEOUT                0x00FFFFFF

#define I2CMASTER                0x01
#define I2CSLAVE                0x02

/* For more info, read Philips's LM75 datasheet */
#define LM75_ADDR                0x90   //?????
#define LM75_TEMP                0x00
#define LM75_CONFIG                0x01
#define LM75_THYST                0x02
#define LM75_TOS                0x03

#define RD_BIT                        0x01

#define I2C_IDLE                        0
#define I2C_STARTED                        1
#define I2C_RESTARTED                2
#define I2C_REPEATED_START        3
#define DATA_ACK                        4
#define DATA_NACK                        5

#define I2CONSET_I2EN                0x00000040/* I2C Control Set Register */
#define I2CONSET_AA                        0x00000004
#define I2CONSET_SI                        0x00000008
#define I2CONSET_STO                0x00000010
#define I2CONSET_STA                0x00000020

#define I2CONCLR_AAC                0x00000004/* I2C Control clear Register */
#define I2CONCLR_SIC                0x00000008
#define I2CONCLR_STAC                0x00000020
#define I2CONCLR_I2ENC                0x00000040

#define I2DAT_I2C                        0x00000000/* I2C Data Reg */
#define I2ADR_I2C                        0x00000000/* I2C Slave Address Reg */
#define I2SCLH_SCLH                        0x00000080/* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL                        0x00000080/* I2C SCL Duty Cycle Low Reg */

extern void I2C0_IRQHandler( void );
extern uint32_t I2CInit( uint32_t I2cMode );
extern uint32_t I2CStart( void );
extern uint32_t I2CStop( void );
extern uint32_t I2CEngine( void );

#endif /* end __I2C_H */
/****************************************************************************
**                            End Of File
*****************************************************************************/


主函数:
/*****************************************************************************
*   i2cmst.c:main C entry file for NXP LPC17xx Family Microprocessors
*
*   Copyright(C) 2009, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2009.05.26ver 1.00    Prelimnary version, first Release
*
******************************************************************************/
#include "lpc17xx.h"
#include "i2c.h"
#include "uart.h"
#include "stdarg.h"
#include "stdio.h"

extern volatile uint32_t I2CCount;
extern volatile uint8_t I2CMasterBuffer;
extern volatile uint32_t I2CCmd, I2CMasterState;
extern volatile uint32_t I2CReadLength, I2CWriteLength;
extern void delay_ms(int z);
/*******************************************************************************
**   Main Functionmain()
*******************************************************************************/
int main (void)
{
uint32_t i;
//uint32_t qq=0x00000064;
uint8_t ww=0xff;
//int CompValue=123;
SystemInit();
UART0_Init();

if ( I2CInit( (uint32_t)I2CMASTER ) == 0 )        /// initialize I2c// -哪里返回0????
{
        while ( 1 );                                /* Fatal error */
}
//UART0_SendString("123\r\n");
// Uart0_Printf("%d\r\n",qq);

//Uart_Printf("Config %d\r\n",FConfig);
//UART0_SendByte(qq);
//UART0_SendChar(qq);
/* the example used to test the I2C interface is
a Philips's LM75 temp sensor, as an I2C slave.
   
the sequence to get the temp reading is:
get device ID register,
set configuration register,
get temp reading
*/

/* In order to start the I2CEngine, the all the parameters
must be set in advance, including I2CWriteLength, I2CReadLength,
I2CCmd, and the I2cMasterBuffer which contains the stream
command/data to the I2c slave device.

(1) If it's a I2C write only, the number of bytes to be written is
I2CWriteLength, I2CReadLength is zero, the content will be filled       // fill?
in the I2CMasterBuffer.

(2) If it's a I2C read only, the number of bytes to be read is
I2CReadLength, I2CWriteLength is zero, the read value will be filled
in the I2CMasterBuffer.

(3) If it's a I2C Write/Read with repeated start, specify the
I2CWriteLength, fill the content of bytes to be written in
I2CMasterBuffer, specify the I2CReadLength, after the repeated
start and the device address with RD bit set, the content of the
reading will be filled in I2CMasterBuffer index at
I2CMasterBuffer.

e.g. Start, DevAddr(W), WRByte1...WRByteN, Repeated-Start, DevAddr(R),
RDByte1...RDByteN Stop. The content of the reading will be filled
after (I2CWriteLength + two devaddr) bytes. */


/*
// Configure temp register before reading //
for ( i = 0; i < BUFSIZE; i++ )        // clear buffer //       //32
{
        I2CMasterBuffer = 0;
}

I2CWriteLength = 2;    //???????
I2CReadLength = 0;   //??????
I2CMasterBuffer = LM75_ADDR;   //????
I2CMasterBuffer = LM75_CONFIG;   
I2CMasterBuffer = 0x55;        // configuration value, no change from
                                                        ///        default //
I2CCmd = LM75_CONFIG;
I2CEngine();

*/

/* Get temp reading */
for ( i = 0; i < BUFSIZE; i++ )        /* clear buffer */
{
        I2CMasterBuffer = 0;
}

I2CWriteLength = 1;    //???????
I2CReadLength = 2;   //???????
I2CMasterBuffer = LM75_ADDR;
I2CMasterBuffer = LM75_TEMP;
I2CMasterBuffer = LM75_ADDR | RD_BIT;   //从机地址+R(1)
I2CCmd = LM75_TEMP;
I2CEngine();


/* The temp reading value should reside in I2CMasterBuffer byte 3, 4 */           //16BIT        I2CMasterBufferandI2CMasterBuffer
while(1){
          
          
delay_ms(2000);
Uart0_Printf("%d\r\n",I2CMasterBuffer);
Uart0_Printf("%d\r\n",I2CMasterBuffer);
   //UART0_SendByte(I2CMasterBuffer);
   //UART0_SendByte(I2CMasterBuffer);
   //UART0_SendByte(I2CMasterBuffer);
   //UART0_SendByte(I2CMasterBuffer);
   //UART0_SendByte(I2CMasterBuffer);
delay_ms(2000);

}

}



void delay_ms(int z)
{
        int x,y;
        for(x=z;x>0;x--)
        for(y=10000;y>0;y--);
}
/******************************************************************************
**                            End Of File
******************************************************************************/


最后的温度值应该是显示在:
Uart0_Printf("%d\r\n",I2CMasterBuffer);
Uart0_Printf("%d\r\n",I2CMasterBuffer);
调试的结果是0 0 。短接了SDA SCL数据没有变化:
求大神解救!!{:2_25:}

黑夜之狼 发表于 2015-4-15 09:25:22

LZ没看坛规,走好不送

hcambridge 发表于 2015-4-15 09:41:58

刷屏玩,是吧,byebye了你的!

lryxr2507 发表于 2015-4-15 09:49:43

看到满屏的求助估计就是新手,进来一看果然是.

kuoo 发表于 2015-4-15 09:49:56

是网络的原因啊,吗的狗屎公司网络

kuoo 发表于 2015-4-15 10:05:25

求阿莫不要封我ID啊 这个ID花钱买的 是网络的原因

steaven2000 发表于 2015-4-15 10:09:44

kuoo 发表于 2015-4-15 10:05
求阿莫不要封我ID啊 这个ID花钱买的 是网络的原因

跟网络有屁关系啊,一上来就大段大段的代码,谁有空来给你看啊。

你自己不做分析,不思考,先粗略定位一下问题点也好啊。

kuoo 发表于 2015-4-15 10:15:39

steaven2000 发表于 2015-4-15 10:09
跟网络有屁关系啊,一上来就大段大段的代码,谁有空来给你看啊。

你自己不做分析,不思考,先粗略定位一 ...

{:sweat:} {:sweat:} {:sweat:} 没有经过思考就不会发到上面了···搞了3天了

ersha4877 发表于 2015-4-15 10:23:59

kuoo 发表于 2015-4-15 10:15
没有经过思考就不会发到上面了···搞了3天了

还是先问问版主帮忙解决重贴问题,程序的话找找ZLG那里的例程,记得有个I2C的程序可以看看

jjj206 发表于 2015-4-15 17:45:13

楼主ID不保咯
页: [1]
查看完整版本: 【求助】路虎LPC1768-IIC模块LM75如何工作?程序无法实现?..