找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 327|回复: 13
打印 上一主题 下一主题
收起左侧

求助:LCD12864显示不了中文 “三”

  [复制链接]
跳转到指定楼层
楼主
   我在编写时钟时遇到显示中文“三”时LCD12864直接不显示,有碰到过的朋友吗
#include "config.h"
#include "AI8051U_Delay.h"
#include "AI8051U_RTC.h"
#include "AI8051U_GPIO.h"
#include "AI8051U_UART.h"
#include "AI8051U_NVIC.h"
#include "AI8051U_Timer.h"
#include "key_drv.h"
#include "lcd12864.h"
#include "display_time.h"
#include "set_time.h"
#include "stdio.h"

// 1. 枚举必须是合法的标识符常量
typedef enum
{
    TASK1_DISPLAY = 1, // 任务1:显示时间
    TASK2_SETTING,     // 任务2:设置时间
    TASK3_RESERVED     // 任务3:预留
} Task_State;

// 2. 默认任务用枚举常量名
Task_State current_task = TASK1_DISPLAY;     
bit task_init_flag = 0;

u8 key_val;  // 全局按键变量,主循环和 set_time.c 都会用到

// 直接声明你现成的函数
extern void Dis_Time_Init(void);
extern void Dis_Time_Update(void);
extern void Set_Time_Init(void);
extern void Set_Time_Update(void);
extern void task3_Init(void);
extern void task3_Run(void);


void task3_Init(void)
{
    // 预留
}

void task3_Run(void)
{
    // 预留
}

void main(void)
{
    // 3. 函数指针数组照常填函数名
    void (*task_run[])(void)  = {0, Dis_Time_Update, Set_Time_Update, task3_Run};      
    void (*task_init[])(void) = {0, Dis_Time_Init, Set_Time_Init, task3_Init};  

    WTST = 0;        
    EAXSFR();        
    CKCON = 0;      

    GPIO_config();
    Timer_config();
    UART_config();
    RTC_config();
    KeyDrvInit();
   
    Lcd12864_Init();
    delay_ms(500);   
    EA = 1;
        
         Lcd12864_SetPos(3, 1);
         Lcd12864_WriteCN("星");
         Lcd12864_WriteCN("期");
        Lcd12864_SetPos(3, 3);
         Lcd12864_WriteCN("三");
        Lcd12864_SetPos(3, 4);
         Lcd12864_WriteCN("星");
        Lcd12864_WriteCN("期");
        Lcd12864_WriteCN("四");
        
        delay_ms(500);
        delay_ms(500);
        delay_ms(500);
   
    printf("System Init OK!\r\n");

    while (1)
    {
        static unsigned char task_switch_flag = 0;
        
        key_val = GetKeyVal();  
        
        // Key1 任务切换:1(显示) -> 2(设置) -> 3(预留) -> 1(显示)
        if(key_val == 1 && !task_switch_flag)  
        {
            task_switch_flag = 1;
            task_init_flag = 0;
            current_task = (current_task % 3) + 1;
        }
        else if(key_val == 0 && task_switch_flag)
        {
            task_switch_flag = 0;
        }
        
        if(!task_init_flag)  
        {
            task_init[current_task]();
            task_init_flag = 1;
        }
        
        task_run[current_task]();
    }
}


[img]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶顶 踩踩
回复

使用道具 举报

沙发
ID:1069233 发表于 2026-11-5 08:17 | 只看该作者
可能是12864屏自带字库少了三,用CGRAM自定义一个三的16×16 字模,直接调用自定义的三就可以
回复

使用道具 举报

板凳
ID:584814 发表于 2026-11-5 09:20 | 只看该作者
正常。遇到过类似的问题。可绕过去或直接自定义字库
回复

使用道具 举报

地板
ID:1064915 发表于 2026-11-5 09:21 | 只看该作者
换成简单程序试
回复

使用道具 举报

5#
ID:996773 发表于 2026-11-5 09:31 | 只看该作者
直接用自定义字符就行
回复

使用道具 举报

6#
ID:45879 发表于 2026-11-5 09:40 | 只看该作者
检查你的字库生成的是否OK
回复

使用道具 举报

7#
ID:155507 发表于 2026-11-5 09:44 | 只看该作者

要看手册


2.14 Keil 软件中因含 0xFD 编码的汉字而出现乱码的问题
众所周知, Keil 软件的 8051 和 80251 编译器的所有版本都有一个叫做 0xFD 的问题,主要表现在字符串中不能含有带 0xFD 编码的汉字,否则 Keil 软件在编译时会跳过 0xFD 而出现乱码。
关于这个问题, Keil 官方的回应是: 0xfd、 0xfe、 0xff 这 3 个字符编码被 Keil 编译器内部使用,所以代码中若包含有 0xfd 的字符串时, 0xfd 会被编译器自动跳过。
Keil 官方提供的解决方法:在带有 0xfd 编码的汉字后增加一个 0xfd 即可。例如:
printf("数学"); //Keil 编译后打印会显示乱码
printf("数
\xfd 学"); //显示正常
这里的“\xfd”是标准 C 代码中的转义字符,“\x”表示其后的 1~2 个字符为 16 进制数。“\xfd”表示将 16 进制数 0xfd 插入到字符串中。
由于“数”的汉字编码是
0xCAFD, Keil 在编译时会将 FD 跳过,而只将 CA 编译到目标文件中,后面通过转义字符手动再补一个 0xfd 到目标文件中,就形成完整的 0xCAFD,从而可正常显示。
关于
0xFD 的补丁网上有很多,基本只对旧版本的 Keil 软件有效。打补丁的方法均是在可执行文件中查找关键代码[80 FB FD],并修改为[80 FB FF],这种修改方法查找的关键代码过于简单,很容易修改到其它无关的地方,导致编译出来的目标文件运行时出现莫名其妙的问题。所以,代码中的字符串有包含如下的汉字时,建议使用 Keil 官方提供的解决方法进行解决
GB2312 中,包含 0xfd 编码的汉字如下:
褒饼昌除待谍洱俘庚过糊积箭烬君魁
例笼慢谬凝琵讫驱三升数她听妄锡淆
旋妖引育札正铸 佚冽邶埤荦蔟摭啐
帻猃恺泯潺妪纨琮椠辇挲臊忑睚铨稞
瘕颀螨簖酏觚鳊鼾
另外, Keil 项目路径名的字符中也不能含有带 0xFD 编码的汉字,否则 Keil 软件会无法正确编译此项目。




回复

使用道具 举报

8#
ID:1073939 发表于 2026-11-5 09:51 | 只看该作者
汉字“三”的GB2312编码为十六进制 0xC8FD,keil有0xFD编译错误问题。“褒饼昌除待谍洱俘庚过糊积箭烬君魁例笼慢谬凝琵讫驱三升数她听妄锡淆旋妖引育札正铸佚冽邶埤荦蔟摭啐帻猃恺泯潺妪纨琮椠辇挲臊忑睚铨稞瘕颀螨簖酏觚鳊鼾”,这些汉字都不能正常显示。
回复

使用道具 举报

9#
ID:1073939 发表于 2026-11-5 09:59 | 只看该作者
Lcd12864_WriteCN("三");改成Lcd12864_WriteCN("\xC8\xFD");即可
回复

使用道具 举报

10#
ID:1175769 发表于 2026-11-5 10:54 | 只看该作者
1. Keil 编译器的 0xFD 字符 Bug(最常见原因)
Keil 编译器在处理中文字符串时存在一个已知的缺陷:它会忽略内码以 0xFD 结尾的字符。汉字“三”的 GB2312 内码恰好以 0xFD 结尾。当编译器遇到这个字符时,会将其丢弃,导致该汉字以及紧随其后的字符串全部显示为乱码或不显示。
解决方法:在代码中包含“三”字的字符串后面,手动添加一个转义字符 \xfd。例如,将 "三" 修改为 "三"\xfd,这样就能强制编译器保留该字符,使其正常显示。
2. 源文件编码格式不匹配
LCD12864 液晶模块内置的字库通常基于 GB2312 或 GBK 编码标准。如果您当前使用的代码编辑器(如 VS Code 等)默认将源文件保存为了 UTF-8 编码,编译器生成的机器码就会与字库不匹配,导致中文不能正确解析和显示。
解决方法:使用记事本或专业的代码编辑器,将您的 C 语言源文件“另存为”或转换编码为 ANSI(在中文 Windows 系统下即为 GB2312/GBK 编码),然后重新编译整个工程。
回复

使用道具 举报

11#
ID:1034262 发表于 2026-11-5 11:10 | 只看该作者
三、数、正,你试下,可能都显示不了,这就是KEIL最著名的0xfd问题,你打0xfd补丁即可。
回复

使用道具 举报

12#
ID:1151496 发表于 2026-11-5 16:03 | 只看该作者
感谢各位,现在在汉字后面加/xfd就能显示了
u8 code week_str[7][7] = {"星期日","星期一","星期二","星期三\xfd","星期四","星期五","星期六"};
回复

使用道具 举报

13#
ID:1110477 发表于 2026-11-8 10:57 | 只看该作者
Keil的老毛病,有一些汉字的内码是0xFDXX,比如:“三”、“数”,应该是一个区共94个字,Keil都编译不了,解决办法应该是使用转义字符,加“/三”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表