This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123G 使用硬件IIC读取mlx90614 一直读取的是255

//包含一系列头文件
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
//要发送的I2C数据包的数量
#define SysCtlDelay_ms(ms) (SysCtlDelay(ms*(SysCtlClockGet()/3000)))
#define NUM_I2C_DATA  6
//地址
#define SLAVE_ADDRESS 0x5a
#define Register_ADDRESS 0x07
/*****************************************************************************
 *初始化配置使用 UART0 外设
 *-UART0RX - PA0
 *-UART0TX - PA1
*****************************************************************************/
void Init_Console_Uart0(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);     //内部16M时钟
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 115200, 16000000);
}
/*****************************************************************************
 *配置I2C0主机,并使用环回模式连接它们。
 *初始化I2C0外设
 *I2C0SCL - PB2
 *I2C0SDA - PB3
 *****************************************************************************/
int main(void)
{
    uint32_t pui32DataTx[NUM_I2C_DATA];   // 发送数据缓冲区
    uint32_t pui32DataRx[NUM_I2C_DATA];   //接受数据缓冲区
    uint32_t ui32Index;                   //要发送数据到缓冲区的位置
    //配置外部时钟为20M
    SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);   //使能I2C0外设
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);  //使能PB端口
    //配置引脚的复用功能 PB2 PB3
    GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD_WPU);
    GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_3,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_OD);
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    //配置I2C引脚
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    //I2CLoopbackEnable(I2C0_BASE);
    HWREG(I2C0_BASE + I2C_O_MCR) |= 0x01; //调用寄存器的环回模式 (改用寄存器实现)
    //初始化并使能主机模式,使用系统时钟为 I2C0 模块提供时钟频率,
    //主机模块传输速//率为 100Kbps
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    //设置主机放在总线上的地址,写入从机                                                                 write
    I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);
    //调用uart初始化函数串口显示
    Init_Console_Uart0();
    I2CMasterDataPut(I2C0_BASE, Register_ADDRESS);
    //从机回显发送数据到主机
    UARTprintf("\nSEND Register_ADDRESS %d\n", Register_ADDRESS);
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    while(I2CMasterBusy(I2C0_BASE));
    I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, true);
    // 初始化I2C主机模块状态为单端接收
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    // 初始化I2C主机模块状态为单端接收
    for (ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++){
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
        // 从主机数据寄存器读取数据
        SysCtlDelay_ms(20);
        pui32DataRx[ui32Index] = I2CMasterDataGet(I2C0_BASE);
        UARTprintf("\nmaster recv data %d is :%d\n",ui32Index , pui32DataRx[ui32Index]);
    }
    return 0;
}
  • 既然使用了硬件I2C,为什么使用回环模式呢?回环模式是CANnTX 和 CANnRX内部连接在一起,实现类似串口的自收自发功能。
  • 请确认SCL和SDA总线上是否有合适的上拉电阻。另请参阅 www.ti.com/.../spma073.pdf 的I2C应用笔记,其中包括一些I2C示例供您参考。

    一般来说255返回值是设备没有响应的情况下返回的结果
  • #include <stdbool.h>

    #include <stdint.h>

    #include "inc/hw_i2c.h"

    #include "inc/hw_memmap.h"

    #include "inc/hw_types.h"

    #include "driverlib/gpio.h"

    #include "driverlib/i2c.h"

    #include "driverlib/pin_map.h"

    #include "driverlib/sysctl.h"

    #include "driverlib/uart.h"

    #include "utils/uartstdio.h"



    //地址

    #define SLAVE_ADDRESS 0x3C
    #define MPU9250Addr 0xD2
    #define MPU9250_RA_WHO_AM_I 0x75



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

    *初始化配置使用 UART0 外设

    *-UART0RX - PA0

    *-UART0TX - PA1

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

    void Init_Console_Uart0(void)

    {



    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    GPIOPinConfigure(GPIO_PA0_U0RX);

    GPIOPinConfigure(GPIO_PA1_U0TX);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); //内部16M时钟

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTStdioConfig(0, 115200, 16000000);

    }



    //read specified register on slave device
    uint32_t I2CReceive(uint32_t slave_addr, uint8_t reg)
    {
    //specify that we are writing (a register address) to the
    //slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

    //specify register to be read
    I2CMasterDataPut(I2C0_BASE, reg);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //specify that we are going to read from slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);

    //send control byte and read from the register we
    //specified
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //return data pulled from the specified register
    return I2CMasterDataGet(I2C0_BASE);
    }

    //initialize I2C module 0
    //Slightly modified version of TI's example code
    void InitI2C0(void)
    {
    //enable I2C module 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //reset module
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);

    //enable GPIO peripheral that contains I2C 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    // Enable and initialize the I2C0 master module. Use the system clock for
    // the I2C0 module. The last parameter sets the I2C data transfer rate.
    // If false the data rate is set to 100kbps and if true the data rate will
    // be set to 400kbps.
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

    //clear I2C FIFOs
    HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
    }


    void main(void)
    {

    uint32_t data;
    // Set the clocking to run directly from the external crystal/oscillator.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ);
    InitI2C0();
    Init_Console_Uart0();
    //#define MPU9250Addr 0xD2
    // #define MPU9250_RA_WHO_AM_I 0x75

    data = I2CReceive(MPU9250Addr, MPU9250_RA_WHO_AM_I);
    UARTprintf("\nreturn status : 0x%x\n", I2CMasterErr(I2C0_BASE));
    UARTprintf("\nreturn data is : %d\n", data);
    }


    您好 这是新的程序 没有使用回环模式, 有上拉电阻 示波器也有波形显示, 可是 还是返回255, 别的功能都实现了就是这个硬件IIC卡很多天了
    求助!!!!
  • 请您参考下下面的代码并根据您的实际时钟情况修改时钟的相应配置

    unsigned long RD_Data[2];
    
    int main(void)
    {
    	//
    	// Setup clock
    	//
    	SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_12MHZ);
    
    
    	//
    	// Turn on I2S0 and reset to a known state
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); 
    	SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
    
    	//
    	// Configure the PortB pins for I2C0
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    	//
    	// Set GPIO Pins for Open-Drain operation
    	//
    	GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
    	GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
    
    	//
    	// Give control to the I2C Module
    	//
    	GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
    	GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_DIR_MODE_HW);
    
    	//
    	// Enable and Initalize Master module and Master Clk using 100kbps
    	//
    	I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), 0);
    
    	SysTickPeriodSet(SysCtlClockGet()/1000);
    	SysTickEnable();
      
    	display_init();
    	display_enable(1);
    
    	while(1)
    	{
    		//
    		// Set the slave address, and set the Master to Transmit mode
    		// Note* : Any MLX90614 will respond to address 0x00
    		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x00, false);
    
    		//
    		// Place the character to be sent in the data register
    		//
    		I2CMasterDataPut(I2C0_MASTER_BASE, 0x07);
    
    		//
    		// Initiate send of character from Master to Slave
    		//
    		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    
    		//
    		// Delay until transmission completes
    		//
    		while(I2CMasterBusy(I2C0_MASTER_BASE)){}
    
    		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x00, true);
    
    
    		// I2C Master module, initiate burst receive start
    		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    
    		// This function returns an indication of whether or not the I2C Master is busy
    		while(I2CMasterBusy(I2C0_MASTER_BASE)){}
    
    		// This function receives a byte that has been sent to the I2C Master.
    		RD_Data[0] = I2CMasterDataGet(I2C0_MASTER_BASE);
    
    		// I2C Master module, finish burst receive
    		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
    		// This function returns an indication of whether or not the I2C Master is busy
    		while(I2CMasterBusy(I2C0_MASTER_BASE)){}
    
    		display_string(0, 0, 0, "Data:          ");
    		display_double(35, 0, 0, 2, RD_Data[0]);
    		delay(500);
    		display_update();
    	}
    
    }