函数的交替行为实现:如何识别函数调用者?
为每个独立调用场景实现独立的静态标志位
你的问题核心在于当前代码里的static bool flag是全局共享的——不管传入的col、line、text是什么,所有闪烁调用都会共用同一个标志位,导致不同位置/内容的闪烁文本互相干扰。要实现“每个调用场景(相同参数组合)独立切换标志位”,可以用以下两种方案:
方案一:用结构体数组管理每个闪烁场景的状态
适合需要区分同一位置不同文本的场景,比如同一个LCD位置可能交替显示不同闪烁文本。
实现代码
#include <string.h> // 定义存储闪烁状态的结构体 typedef struct { uint8_t col; uint8_t line; const char *text; bool flag; } BlinkState; // 根据实际需求调整最大支持的闪烁场景数量 #define MAX_BLINK_SCENES 8 static BlinkState blink_scenes[MAX_BLINK_SCENES] = {0}; void showText(uint8_t col, uint8_t line, const char *text, bool blinking) { if(blinking) { BlinkState *target = NULL; // 1. 查找当前参数对应的已存在状态 for(int i = 0; i < MAX_BLINK_SCENES; i++) { // 若text是动态分配的字符串,将指针比较换成strcmp(blink_scenes[i].text, text) == 0 if(blink_scenes[i].col == col && blink_scenes[i].line == line && blink_scenes[i].text == text) { target = &blink_scenes[i]; break; } } // 2. 没找到则初始化一个新的空状态 if(target == NULL) { for(int i = 0; i < MAX_BLINK_SCENES; i++) { if(blink_scenes[i].text == NULL) // 用text是否为空标记未使用状态 { target = &blink_scenes[i]; target->col = col; target->line = line; target->text = text; target->flag = false; break; } } } // 3. 执行闪烁逻辑 if(target != NULL) { lcd_setcursor(col, line); if(target->flag) { for(int i = 0; i < strlen(text); i++) { lcd_data(' '); } } else { lcd_string(text); } target->flag = !target->flag; } // 可选:处理状态池满的情况,比如覆盖最早创建的场景 } else { lcd_setcursor(col, line); lcd_string(text); // 可选:停止闪烁时清除对应场景的状态 for(int i = 0; i < MAX_BLINK_SCENES; i++) { if(blink_scenes[i].col == col && blink_scenes[i].line == line && blink_scenes[i].text == text) { blink_scenes[i].text = NULL; break; } } } }
关键说明
- 用结构体保存每个闪烁场景的参数和标志位,通过遍历数组匹配参数找到对应状态;
- 若使用动态字符串,需替换指针比较为
strcmp,同时注意动态内存的管理; MAX_BLINK_SCENES需根据硬件内存和实际需求调整。
方案二:用二维数组按LCD位置存储标志位
适合同一位置仅显示固定闪烁文本的场景,代码更简洁高效。
实现代码
#include <string.h> void showText(uint8_t col, uint8_t line, const char *text, bool blinking) { if(blinking) { // 根据你的LCD实际尺寸调整数组大小(示例为16列×2行) static bool blink_flags[16][2] = {false}; bool *current_flag = &blink_flags[col][line]; lcd_setcursor(col, line); if(*current_flag) { for(int i = 0; i < strlen(text); i++) { lcd_data(' '); } } else { lcd_string(text); } *current_flag = !*current_flag; } else { lcd_setcursor(col, line); lcd_string(text); // 可选:停止闪烁时重置该位置的标志位 static bool blink_flags[16][2] = {false}; blink_flags[col][line] = false; } }
关键说明
- 利用LCD的行列范围有限的特性,直接用
(col, line)作为二维数组的索引,每个位置对应独立的标志位; - 缺点是同一位置更换不同文本时,标志位会延续之前的状态,但大部分嵌入式LCD场景下不会出现这种情况。
内容的提问来源于stack exchange,提问作者Clem Housa
相关产品推荐
相关产品推荐

