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

基于TMS320F28335的两位7段数码管按键增减控制方案问询

基于TMS320F28335的两位7段数码管按键单次增减实现方案

我正在用Code Composer Studio开发基于TMS320F28335的项目,通过D0-7信号驱动两位7段数码管。之前尝试过两种实现方式,但都存在问题:

第一种:switch手动预设段码实现增减

只能按固定顺序切换预设值,无法自由控制0-99的数值变化,代码如下:

void display(void)
{
    B1 +=1;
    if(B1 > B1_lim) { B1 = 0; }

    switch(B1)
    {
        case  0:  Display[0] = 0xf7; break;  //9
        case 1:  Display[0] = 0xfF; break;   //8
        case 2:  Display[0] = 0xf0; break;   //7
        case 3:  Display[0] = 0x9F; break;
    }
}

第二种:计数器循环显示

因while(1)死循环阻塞,无法响应按键;后续添加按键仅能控制启停,无法实现单次增减,代码如下:

void display(void)
{
    unsigned char a[]={0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7}; //[0,1,2,3,4,5,6,7,8,9]
    unsigned char b[]={0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7}; //[0,1,2,3,4,5,6,7,8,9]
    int k,j;
    while(1)
    {
        Display[0] = 0xfb;
        Display[1] = 0xfb;
        DELAY_US(200000L);
        for(j=0;j<=9;j++)
        {
            Display[1]=b[j];
            led_display(0x00);    DELAY_US(200000L);
            for(k=0;k<=9;k++)
            {
                Display[0] = a[k];
                led_display(0x00);    DELAY_US(200000L);
                DELAY_US(2L);
            }
        }
    }
}

当前驱动板有4个按键,需要用其中两个分别实现数码管数值的单次递增和单次递减,希望结合switch语句,同时采用第二种代码的段码数组方式实现。


实现方案

核心逻辑

  1. 放弃死循环阻塞架构,改用轮询按键+全局变量记录数值的方式,主循环同时处理按键响应与数码管刷新
  2. 用段码数组存储0-9的对应值,通过索引直接调用,替代switch硬编码段码;用switch处理按键触发的数值边界逻辑
  3. 加入按键消抖,避免机械抖动导致的单次触发多次增减

具体代码

// 全局变量:记录当前显示数值(范围0-99)
unsigned int current_num = 0;
// 段码数组:索引对应数字0-9,复用原有段码定义
unsigned char seg_code[] = {0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7};

// 按键读取函数(带消抖,需根据硬件GPIO引脚修改)
unsigned char read_keys(void)
{
    // 示例:KEY_UP为递增按键引脚,KEY_DOWN为递减按键引脚
    static unsigned char last_up = 1, last_down = 1;
    unsigned char current_up = GPIO_ReadPin(KEY_UP_PIN);
    unsigned char current_down = GPIO_ReadPin(KEY_DOWN_PIN);
    unsigned char key_state = 0;

    // 消抖:连续两次读取状态一致才判定有效
    if(current_up != last_up)
    {
        DELAY_US(10000L); // 10ms消抖延时
        current_up = GPIO_ReadPin(KEY_UP_PIN);
        if(current_up == 0 && last_up == 1)
        {
            key_state = 1; // 递增按键触发
        }
        last_up = current_up;
    }

    if(current_down != last_down)
    {
        DELAY_US(10000L);
        current_down = GPIO_ReadPin(KEY_DOWN_PIN);
        if(current_down == 0 && last_down == 1)
        {
            key_state = 2; // 递减按键触发
        }
        last_down = current_down;
    }

    return key_state;
}

// 数码管刷新函数
void update_display(void)
{
    // 拆分十位与个位
    unsigned char tens = current_num / 10;
    unsigned char units = current_num % 10;

    // 刷新两位数码管
    Display[1] = seg_code[tens]; // 十位
    Display[0] = seg_code[units]; // 个位
    led_display(0x00);
    DELAY_US(2000L); // 短延时保证显示稳定
}

// 主循环任务函数(放在主函数的while(1)中执行)
void main_loop_task(void)
{
    unsigned char key = read_keys();

    // 用switch处理按键对应的数值操作
    switch(key)
    {
        case 1: // 递增按键
            current_num = (current_num < 99) ? current_num + 1 : 0;
            break;
        case 2: // 递减按键
            current_num = (current_num > 0) ? current_num - 1 : 99;
            break;
        default:
            // 无按键操作,仅刷新显示
            break;
    }

    // 每次循环都刷新数码管
    update_display();
}

关键说明

  • 全局变量current_num:直接记录当前显示数值,按键操作仅修改该变量,数码管刷新时根据变量值拆分十位/个位
  • 段码数组seg_code:复用原有段码定义,通过索引直接获取对应数字的段码,比switch硬编码更灵活易维护
  • 按键消抖:必须加入,否则按键按下时会因机械抖动触发多次增减
  • 主循环架构:将main_loop_task()放在主函数的while(1)中执行,避免在display函数内写死循环,保证按键响应与数码管刷新的实时性
  • switch的作用:用于区分不同按键的操作逻辑,后续扩展其他按键功能时,直接新增case即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:01:00