TI开发板嵌入式C代码故障排查:LED无响应及UART无输出
嵌入式C代码问题排查与修复
核心问题分析
- GPIO按钮配置未生效:CONFIG_GPIO_BUTTON_0的引脚配置代码被注释,导致按钮未设置为上拉输入+下降沿中断,按键触发时无法调用回调函数,按键状态永远不会被更新。
- 任务结构体初始化顺序错误:
struct task_entry的成员顺序为void (*f)(); int elapsed_time; int period; char triggered;,但初始化时将triggered放在首位,导致任务周期、触发逻辑完全错位。 - 任务调用逻辑重复且无效:main循环中提前调用
task_one()/task_two()/task_three(),且这些任务依赖的buttonCheckTime等变量从未被累加更新,条件永远不满足;同时timerCallback中已通过task_entry管理任务触发,无需单独维护时间变量。 - global_period非法递增:main循环中
++global_period导致timerCallback里的任务elapsed_time每次累加值持续增大,任务周期彻底混乱。 - DISPLAY宏参数错误:传递
&output给UART_write(output数组名本身就是指针),且未正确处理snprintf的返回值,导致UART输出异常。 - task_three触发条件无效:使用
displayCheckTime == displayCheckPeriod的严格相等判断,且displayCheckTime未被更新,永远无法触发UART上报。
修复后的代码
/* * ======== gpiointerrupt.c ======== */ #include <stdint.h> #include <stddef.h> /* Driver Header files */ #include <ti/drivers/GPIO.h> #include <ti/drivers/I2C.h> #include <ti/drivers/UART.h> /* Driver configuration */ #include "ti_drivers_config.h" /* Driver timer */ #include <ti/drivers/Timer.h> #define TRUE 1 #define FALSE 0 #define NUMBER_OF_TASKS 3 #define GLOBAL_PERIOD 100 // milliseconds #define DISPLAY(str_len) UART_write(uart, output, str_len); // UART Global Variables char output[64]; // Driver Handles - Global variables UART_Handle uart; // Global variables int setpoint = 25; int heat = 0; int seconds = 0; int16_t temperature = 0; volatile int firstButtonWasPressed = FALSE; volatile int secondButtonWasPressed = FALSE; const int global_period = GLOBAL_PERIOD; void initUART(void) { UART_Params uartParams; UART_init(); UART_Params_init(&uartParams); uartParams.writeDataMode = UART_DATA_BINARY; uartParams.readDataMode = UART_DATA_BINARY; uartParams.readReturnMode = UART_RETURN_FULL; uartParams.baudRate = 115200; uart = UART_open(CONFIG_UART_0, &uartParams); if (uart == NULL) { while (1); } } // I2C Global Variables static const struct { uint8_t address; uint8_t resultReg; char *id; } sensors[3] = { { 0x48, 0x00, "11X" }, { 0x49, 0x00, "116" }, { 0x41, 0x01, "006" } }; uint8_t txBuffer[1]; uint8_t rxBuffer[2]; I2C_Transaction i2cTransaction; I2C_Handle i2c; void initI2C(void) { int8_t i, found; I2C_Params i2cParams; int len = snprintf(output, 64, "Initializing I2C Driver - "); DISPLAY(len); I2C_init(); I2C_Params_init(&i2cParams); i2cParams.bitRate = I2C_400kHz; i2c = I2C_open(CONFIG_I2C_0, &i2cParams); if (i2c == NULL) { len = snprintf(output, 64, "Failed\n\r"); DISPLAY(len); while (1); } len = snprintf(output, 32, "Passed\n\r"); DISPLAY(len); i2cTransaction.writeBuf = txBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = rxBuffer; i2cTransaction.readCount = 0; found = false; for (i = 0; i < 3; ++i) { i2cTransaction.slaveAddress = sensors[i].address; txBuffer[0] = sensors[i].resultReg; len = snprintf(output, 64, "Is this %s? ", sensors[i].id); DISPLAY(len); if (I2C_transfer(i2c, &i2cTransaction)) { len = snprintf(output, 64, "Found\n\r"); DISPLAY(len); found = true; break; } len = snprintf(output, 64, "No\n\r"); DISPLAY(len); } if (found) { len = snprintf(output, 64, "Detected TMP%s I2C address: %x\n\r", sensors[i].id, i2cTransaction.slaveAddress); DISPLAY(len); } else { len = snprintf(output, 64, "Temperature sensor not found, contact professor\n\r"); DISPLAY(len); } } int16_t readTemp(void) { int16_t temp = 0; i2cTransaction.readCount = 2; if (I2C_transfer(i2c, &i2cTransaction)) { temp = (rxBuffer[0] << 8) | rxBuffer[1]; temp *= 0.0078125; if (rxBuffer[0] & 0x80) { temp |= 0xF000; } } else { int len = snprintf(output, 64, "Error reading temperature sensor (%d)\n\r", i2cTransaction.status); DISPLAY(len); len = snprintf(output,64, "Please power cycle your board by unplugging USB and plugging back in.\n\r"); DISPLAY(len); } return temp; } Timer_Handle timer0; volatile unsigned char TimerFlag = 0; struct task_entry { void (*f)(); int elapsed_time; int period; char triggered; }; void task_one(); void task_two(); void task_three(); void task_one() { if (firstButtonWasPressed == TRUE) { setpoint += 1; firstButtonWasPressed = FALSE; } if (secondButtonWasPressed == TRUE) { setpoint -= 1; secondButtonWasPressed = FALSE; } } void task_two() { temperature = readTemp(); if (temperature > setpoint) { GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF); heat = 0; } else { GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON); heat = 1; } } void task_three() { int len = snprintf(output, 64, "<%02d,%02d,%d,%04d>\n\r", (int)temperature, setpoint, heat, seconds); DISPLAY(len); ++seconds; } struct task_entry tasks[NUMBER_OF_TASKS] = { {&task_one, 0, 200, FALSE}, {&task_two, 0, 500, FALSE}, {&task_three, 0, 1000, FALSE} }; void timerCallback(Timer_Handle myHandle, int_fast16_t status) { for (int x = 0; x < NUMBER_OF_TASKS; x++) { tasks[x].elapsed_time += global_period; if (tasks[x].elapsed_time >= tasks[x].period) { tasks[x].triggered = TRUE; TimerFlag = TRUE; tasks[x].elapsed_time = 0; } } } void initTimer(void) { Timer_Params params; Timer_init(); Timer_Params_init(¶ms); params.period = GLOBAL_PERIOD * 1000; // 100ms = 100000us params.periodUnits = Timer_PERIOD_US; params.timerMode = Timer_CONTINUOUS_CALLBACK; params.timerCallback = timerCallback; timer0 = Timer_open(CONFIG_TIMER_0, ¶ms); if (timer0 == NULL) { while (1); } if (Timer_start(timer0) == Timer_STATUS_ERROR) { while (1); } } void gpioButtonFxn0(uint_least8_t index) { firstButtonWasPressed = TRUE; } void gpioButtonFxn1(uint_least8_t index) { secondButtonWasPressed = TRUE; } void* mainThread(void *arg0) { GPIO_init(); GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); GPIO_setConfig(CONFIG_GPIO_BUTTON_0, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING); GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON); GPIO_setCallback(CONFIG_GPIO_BUTTON_0, gpioButtonFxn0); GPIO_enableInt(CONFIG_GPIO_BUTTON_0); if (CONFIG_GPIO_BUTTON_0 != CONFIG_GPIO_BUTTON_1) { GPIO_setConfig(CONFIG_GPIO_BUTTON_1, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING); GPIO_setCallback(CONFIG_GPIO_BUTTON_1, gpioButtonFxn1); GPIO_enableInt(CONFIG_GPIO_BUTTON_1); } initUART(); initI2C(); initTimer(); while (TRUE) { while (!TimerFlag); for (int x = 0; x < NUMBER_OF_TASKS; x++) { if (tasks[x].triggered) { tasks[x].f(); tasks[x].triggered = FALSE; } } TimerFlag = FALSE; } }
修复说明
- 补全CONFIG_GPIO_BUTTON_0的引脚配置,确保按键中断正常触发。
- 修正任务列表初始化顺序,匹配结构体定义,设置正确的任务周期(200ms/500ms/1000ms)。
- 删除main循环中提前调用的任务函数,仅通过timerCallback触发的任务列表执行逻辑。
- 将global_period改为const常量,避免非法递增,保证定时器回调中每次累加固定的100ms。
- 修正DISPLAY宏,传递正确的output指针,并显式处理snprintf的返回值作为UART写入长度。
- 移除无效的buttonCheckTime等变量,任务逻辑直接执行对应功能(因为timerCallback已经保证了触发周期)。
- 将按键状态变量声明为volatile,避免编译器优化导致的变量值错误。
- 修正定时器周期参数,GLOBAL_PERIOD是100ms,对应100000微秒,确保定时器回调每100ms触发一次。
内容的提问来源于stack exchange,提问作者FireMonkey
相关产品推荐
相关产品推荐

