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

函数的交替行为实现:如何识别函数调用者?

为每个独立调用场景实现独立的静态标志位

你的问题核心在于当前代码里的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:18:18