You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(&params);
    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, &params);
    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;
    }
}

修复说明

  1. 补全CONFIG_GPIO_BUTTON_0的引脚配置,确保按键中断正常触发。
  2. 修正任务列表初始化顺序,匹配结构体定义,设置正确的任务周期(200ms/500ms/1000ms)。
  3. 删除main循环中提前调用的任务函数,仅通过timerCallback触发的任务列表执行逻辑。
  4. 将global_period改为const常量,避免非法递增,保证定时器回调中每次累加固定的100ms。
  5. 修正DISPLAY宏,传递正确的output指针,并显式处理snprintf的返回值作为UART写入长度。
  6. 移除无效的buttonCheckTime等变量,任务逻辑直接执行对应功能(因为timerCallback已经保证了触发周期)。
  7. 将按键状态变量声明为volatile,避免编译器优化导致的变量值错误。
  8. 修正定时器周期参数,GLOBAL_PERIOD是100ms,对应100000微秒,确保定时器回调每100ms触发一次。

内容的提问来源于stack exchange,提问作者FireMonkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:30:51