基于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语句,同时采用第二种代码的段码数组方式实现。
实现方案
核心逻辑
- 放弃死循环阻塞架构,改用轮询按键+全局变量记录数值的方式,主循环同时处理按键响应与数码管刷新
- 用段码数组存储0-9的对应值,通过索引直接调用,替代switch硬编码段码;用switch处理按键触发的数值边界逻辑
- 加入按键消抖,避免机械抖动导致的单次触发多次增减
具体代码
// 全局变量:记录当前显示数值(范围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
相关产品推荐
相关产品推荐

