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.

TM4C129 I2C读取TMP100的温度问题

I2CMasterSlaveAddrSet( I2C6_BASE, 0x4A, true);										//控制传输方向为主机写
		I2CMasterDataPut( I2C6_BASE, 0x01 );												//写入主机数据(TMP100控制寄存器地址)
		I2CMasterControl( I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_START );						//start+从机地址+主机数据传输
		while( I2CMasterErr(I2C6_BASE) | I2CMasterBusy(I2C6_BASE) );
		I2CMasterDataPut( I2C6_BASE, 0xED  ); 												//写入主机数据(TMP100控制寄存器内容)
		I2CMasterControl( I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_CONT );					//主机数据传输
		while( I2CMasterErr(I2C6_BASE) | I2CMasterBusy(I2C6_BASE) );
		delay_ms(35);
		I2CMasterDataPut( I2C6_BASE, 0x00 ); 												//读取温度
		I2CMasterControl( I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH ); 							//start+从机地址+主机数据+stop传输
		while( I2CMasterErr(I2C6_BASE) | I2CMasterBusy(I2C6_BASE) );
		delay_ms(25);

		I2CMasterSlaveAddrSet( I2C6_BASE, 0x4A, true);										//控制传输方向为主机写
		I2CMasterControl( I2C6_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START );
		while( I2CMasterErr(I2C6_BASE) | I2CMasterBusy(I2C6_BASE) );		
		Result_H = I2CMasterDataGet( I2C6_BASE ); 													
		delay_ms(325);

		I2CMasterControl( I2C6_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH ); 							//start+从机地址+主机数据+stop传输
		while( I2CMasterErr(I2C6_BASE) | I2CMasterBusy(I2C6_BASE) );
		delay_ms(325);		
		Result_L = I2CMasterDataGet( I2C6_BASE ); 													//读出转换结果的低八位
		delay_ms(325);
为什么用100kHz的频率读不了数据?设置的精度是0.0625度,为什么每次温度变化是0.5度?

  • I2C初始化的部分有错误,TM4C 对初始化的时序很严格的,建议按照官方的来

      uint32_t ui32DataTx;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    
        //
        // The I2C0 peripheral must be enabled before use.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    
        //
        // For this example I2C0 is used with PortB[3:2].  The actual port and
        // pins used may be different on your part, consult the data sheet for
        // more information.  GPIO port B needs to be enabled so these pins can
        // be used.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        //
        // Configure the pin muxing for I2C0 functions on port B2 and B3.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
        //
        // Select the I2C function for these pins.  This function will also
        // configure the GPIO pins pins for I2C operation, setting them to
        // open-drain operation with weak pull-ups.  Consult the data sheet
        // to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
        //
        // Enable loopback mode.  Loopback mode is a built in feature that helps
        // for debug the I2Cx module.  It internally connects the I2C master and
        // slave terminals, which effectively lets you send data as a master and
        // receive data as a slave.  NOTE: For external I2C operation you will need
        // to use external pull-ups that are faster than the internal pull-ups.
        // Refer to the datasheet for more information.
        //
        HWREG(I2C0_BASE + I2C_O_MCR) |= 0x01;
    
        //
        // Enable the I2C0 interrupt on the processor (NVIC).
        //
        IntEnable(INT_I2C0);
    
        //
        // Configure and turn on the I2C0 slave interrupt.  The I2CSlaveIntEnableEx()
        // gives you the ability to only enable specific interrupts.  For this case
        // we are only interrupting when the slave device receives data.
        //
        I2CSlaveIntEnableEx(I2C0_BASE, I2C_SLAVE_INT_DATA);
    
        //
        // 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.  For this example we will use a data rate of 100kbps.
        //
        I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    
        //
        // Enable the I2C0 slave module.
        //
        I2CSlaveEnable(I2C0_BASE);
    
        //
        // Set the slave address to SLAVE_ADDRESS.  In loopback mode, it's an
        // arbitrary 7-bit number (set in a macro above) that is sent to the
        // I2CMasterSlaveAddrSet function.
        //
        I2CSlaveInit(I2C0_BASE, SLAVE_ADDRESS);
    
        //
        // Tell the master module what address it will place on the bus when
        // communicating with the slave.  Set the address to SLAVE_ADDRESS
        // (as set in the slave module).  The receive parameter is set to false
        // which indicates the I2C Master is initiating a writes to the slave.  If
        // true, that would indicate that the I2C Master is initiating reads from
        // the slave.
        //
        I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);
    
        //
        // Set up the serial console to use for displaying messages.  This is just
        // for this example program and is not needed for proper I2C operation.
        //
        InitConsole();
    
        //
        // Enable interrupts to the processor.
        //
        IntMasterEnable();
  • 这个官方的例程是TM4C129吗? 我记得129的时钟配置应该是

    ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |										
    										 SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |										
    										 SYSCTL_CFG_VCO_480), 120000000);
    还有 HWREG(I2C0_BASE + I2C_O_MCR) |= 0x01;  只在循环模式才配置的。
  • 这个应该是TM4123中的,我指的是这句

      SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
     
      //
      // For this example I2C0 is used with PortB[3:2].  The actual port and
      // pins used may be different on your part, consult the data sheet for
      // more information.  GPIO port B needs to be enabled so these pins can
      // be used.
      // TODO: change this to whichever GPIO port you are using.
      //
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    只能一步一步排除错误了。不知道你调试到哪一步了,如果有个逻辑分析仪就更好了
  • 100K是可以的,是参数没有正确写入。

  • 配置参数吗?