TI Launchpad EK-TM4C1294XL开发板I2C功能无法正常工作的排查求助
我在TI Launchpad上没法让I2C正常工作,UART是好的,编译构建也没问题,但完全看不到I2C活动的迹象。我怀疑是不是漏了某个配置步骤?已经试了好几个网上的例子,最近用的代码(去掉了一些无关函数)如下:
#include <stdint.h> #include <stdbool.h> #include "inc/hw_gpio.h" #include <stdio.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "driverlib/i2c.h" #include "driverlib/pin_map.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" uint32_t g_sysclk; float MCP9808_ReadTempC(void) { uint8_t msb, lsb; float celsius; I2CMasterSlaveAddrSet(I2C0_BASE, 0x18, false); I2CMasterDataPut(I2C0_BASE, 0x05); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); while(I2CMasterBusy(I2C0_BASE)); SysCtlDelay((uint32_t)(.250*g_sysclk/3)); //250 ms delay I2CMasterSlaveAddrSet(I2C0_BASE, 0x18, true); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); while(I2CMasterBusy(I2C0_BASE)); msb = I2CMasterDataGet(I2C0_BASE); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); while(I2CMasterBusy(I2C0_BASE)); lsb = I2CMasterDataGet(I2C0_BASE); msb &= 0x0F; if (msb & 0x10) { celsius = 256 - (msb*16 + lsb/16.0); } else { celsius = msb*16 + lsb/16.0; } return celsius; } void I2C0_Init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)); SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0)); GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); I2CMasterInitExpClk(I2C0_BASE, g_sysclk, false); } int main(void) { float tC; char buf[] = {"Hello world\r\n"}; int i; SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ); g_sysclk = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); UART0_Init(); I2C0_Init(); for(i = 0; i < 13; i++) UARTCharPut(UART0_BASE, buf[i]); while(1) { tC = MCP9808_ReadTempC(); UART0_Print("Temp: "); UART0_PrintFloat(tC); UART0_Print(" C\r\n"); SysCtlDelay(g_sysclk / 2); } }
我还试过很多I2C0_Init()的小改动版本。
我已经排查好一阵子了,试过I2C0(PB2、PB3)和I2C7(PA4、PA5),示波器显示SCL上完全没有信号。我用的是最新版的Code Composer Studio,TI编译器版本和Tivaware里的闪烁灯示例匹配(我是导入这个示例开始做项目的),Tivaware也是最新的2.2.0.295版本。我在两块不同的Launchpad上试过同样的步骤,结果完全一样——都是Tiva™ C Series TM4C1294 Connected LaunchPad Evaluation Kit EK-TM4C1294XL。这两块开发板都在我办公室架子上放了5年多,同时买的但直到现在才拆封。
我确定是接在PB2和PB3上的,因为我之前可以把它们当成GPIO来切换电平。
我尝试和Adafruit的I2C板通信,一个是MCP4728(往DAC写值),另一个是MCP9808(读温度),但都没反应。读MCP9808要么返回0,要么启动时通常会返回重复的乱数据(比如-46.18摄氏度)。往DAC写值也从来不会改变输出电平。
我用的I2C扫描函数“扫到”每个地址(0到127)都有slave。两块Adafruit板都有上拉电阻,没有活动时SCL和SDA都能读到高电平。
DAC硬件是好的,我之前用另一个设备(Adafruit的USB转I2C转换器)用过它。MCP9808我也有理由相信是好的,大概一年前在树莓派上还能正常工作。
PCTL寄存器的值是0x00002200,Copilot建议我查这个,说这意味着MCU不接受寄存器写入,但Copilot已经猜错很多次了。按照Copilot的建议,我试过“解锁”引脚——不过根据文档,我觉得它们根本没锁。
我好像漏掉了某个基础的东西,真不敢相信I2C这么难搞。我不相信两块开发板会以同样的方式坏掉。
有没有什么下一步排查的建议?你们遇到过类似的问题吗?非常感谢任何帮助!
备注:内容来源于stack exchange,提问作者stilllearning

