【51单片机实验笔记】前篇(一)遇到的问题汇总(持续更新)

本文汇总了开发过程中的问题,如CH340串口识别、Keil跨平台兼容、工程模板创建、字体调整、编码Bug修复、乱码处理、C51语法技巧、数据类型理解、警告与错误排查。全面指导开发者解决Keil中遇到的各种技术难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


开发环境问题

1. CH340串口识别失败(22.12.17)

  1. 用数据线连接好,打开设备管理器,检查端口(COM),是否有CH340字样的串口。若无,则说明串口未正确识别。
  2. 检查CH340驱动是否安装或更新。
  3. 更换数据线再次尝试。有的数据线接口看似有5个pin(如Micro USB),但实际剪开只有两根充电线,没有数据传输功能,没有差分信号,自然无法识别串口。
  4. 换一个电脑的USB接口进行尝试,有可能是接口质量问题。
  5. 检查USB转TTL电路是否有虚焊,损坏。(一般不会)

2. Keil5 如何兼容C51和STM32(22.12.17)

  • 进入官网,对于51单片机和STM32单片机有两个版本。
    • Keil uvision5(MDK-ARM) : Development environment for Cortex and Arm devices. 为Cortex内核ARM内核设计。
    • Keil uvision5(C51) : Development tools for all 8051 devices. 为51内核设计。
  • 将两个版本都下载至同一个目录下即可同时使用。

3. 如何创建C51工程模板(22.12.17)

  • Keil4:找Atmel公司的AT89C52芯片即可。
  • Keil5:找Microchip中的AT89C51/AT89C52即可。

4. 如何修改字体大小(22.12.17)

  • 打开Keil,点击最右侧扳手图标,点击Font选项卡,选中C/C++,修改对应字号
  • 若出现"access to xxxx global.prop was denied"的字样,关闭Keil,以管理员身份运行Keil重复上述操作即可。

5. Keil的 “0xFD” Bug(23.03.04)

在一次偶然的串口通讯过程中,汉字"数" 始终无法正确显示,经验证是 Keil 的历史遗留 Bug

汉字机内码0xFD 结尾的部分汉字会被截尾(如等),甚至影响到后面汉字的正常显示。应尽量避免使用上述汉字。


6. Keil中文不显示或乱码或显示问号(23.08.23)

Edit 选项卡中,选择Configuration,设置 编码方式 EncodingUTF-8GB2312

实测KeilANSI编码与当前系统编码并不一致。实测环境Windows系统,在Keil编辑器中打开GBK编码可以正常显示,但输入汉字显示问号,实际只接收了单个字节。这应该是Keil的一个Bug


7. Keil串口传输中文乱码问题(23.09.02)

现象为单字节数据传输或英文字符传输正常,排除串口程序问题。问题定位至文本编码方式不一致问题。

发送汉字 “开”,通过查询,其GBK编码为0xBF 0xAAUnicode编码为0x5F 0x00UTF-8编码为0xE5 0xBC 0x80

串口助手HEX方式打印,结果为0xE5 0xBC 0x80,说明Keil 编码方式为UTF-8

常用的串口助手一般不支持UTF-8编码,而支持GBK编码。至此问题清晰了,发送端的编码方式和接收端的解码方式不一致,导致解析出来的中文乱码

解决方案:将Keil编码方式改成GB2312,并确认源文件编码方式ANSI(GBK),可打开为记事本另存为修改。或者找一款支持 UTF-8编码串口助手


8. Keil中文字体美化(23.09.02)

UTF-8编码格式,可以使用默认的Courier new等字体。但编码方式改成GB2312后,大部分字体修改失效

解决方案:

  1. 下载新字体文件YaHei-Consolas-Hybrid 。提供git命令。
    git clone https://gitee.com/a42/YaHei-Consolas-Hybrid-1.12.git && sh YaHei-Consolas-Hybrid-1.12/setup.sh && cd - && rm -rf YaHei-Consolas-Hybrid-1.12
    
  2. 双击字体库文件.ttf,点击下载字体会下载到系统字体库中。
  3. 重新打开Keil,设置Edit-Configuration-Color&Fonts-C/C++ Editor Files-Font-YaHei-Consolas-Hybrid

注意,前缀@的字体,会使汉字 90°旋转。


9. Keil导入STC选型文件和头文件(23.10.05)

下载并打开STC公司STC-ISP软件,选择Keil仿真设置选项卡,点击添加型号和头文件到Keil中字样的按钮,选择Keil安装根目录,即完成头文件的导入选型数据文件的导入

  • 新建工程时,我们可以直接选择对应STC型号芯片,当然也可以继续选择AT89C52
  • 包含头文件时,我们可以根据芯片选择包含STC提供头文件,当然也可以继续选择包含<REG51.H><REG52.H>

C51语法细节问题

C51使用C51优化C编译器C51 Optimizing C Compiler),基本完全兼容ANSIC语言标准,但对某些方面进行了更改增强,为8051微处理器生成极其快速紧凑的代码,具体可参考【51单片机实验笔记】前篇(三)C51语法新扩展总结


1. 将浮点数或整数转化为字符串方案(23.03.04)

使用 sprintf 字符串格式化函数,格式为

#include <stdio.h>  // 需包含头文件

char strA[10]; // 保证一定长度,用于保存字符串
char strB[10]; 
char strC[10]; 
sprintf(strA, "%d", 123);  // 整数转换字符串
sprintf(strA, "%u", 65530); // 整数转换字符串,指定按无符号解析
sprintf(strC, "%0.6f, 3.141593"); // 浮点数转换字符串

需要注意:在整数转换时,"%d"指 int 类型,占两字节(Keil编译器中),故传递整数时也应传递两字节整型。如果误输入常用的 unsigned char 类型(仅占1个字节),会导致转换结果异常


2. 位运算符优先级问题(23.08.08)

return tempH << 8 + tempL;    // 先执行加法,而非左移
return (tempH <<8 ) + tempL;  // 先执行左移

事实上

  • 左移<<、右移>>运算符优先级均低于+、减-,均高于大于>、小于<,列表达式时需要加括号
  • 按位与&、按位异或^、按位或|优先级逐次降低,均低于关系运算符。

3. 数码管不显示“0”的异常bug(23.08.09)

现象其他字符正常显示,但字符0始终不显示。

原因字符串结束符'\0'ASCII为恰好为0,因此在数码管显示函数中遇到0误作字符串结束标志,直接退出,导致字符0无法正常显示。

解决方案:输入字符0ASCII即可。


4. C51中数据类型字节数问题(23.09.03)

C语言中的数据类型所占字节数硬件平台决定。

C51规定int类型占2字节,而在PC端通常占4字节


bit数据类型问题(23.09.03)


大小端问题

union w{ 
  int a;
  char b;
}c;

c.a = 1;
if(c.b ==1){
	Uart_sendString("小端");
}else{
	Uart_sendString("大端");
}

常见警告信息

未调用函数警告(22.12.19)

*** WARNING Lxx(行号): UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS     SEGMENT: ?PR?xxxx(函数名)?MAIN

如果你定义了一个函数,但并没有调用它,就会产生这个警告。这在标准C编程中一般不会警告。我猜测是单片机RAM资源相对紧缺,通过该警告可以提示编码人员精简无用代码


永远无法执行代码警告(23.08.08)

warning C294: unreachable code

逻辑上永远无法被执行的代码理论上并不影响程序运行,但偶然发现该警告会导致串口通讯异常。以此记录。


重复定义警告(23.09.01)

xxx.c(4): warning C231: 'xxxx': redefinition

编译器发现重复定义同名变量时会发出此警告。一般由以下三种原因引起:

  • 函数声明未指定返回值类型。在C51类型缺省int,当函数实现的类型与之不符时,产生警告。例如func1(void);
  • 命名了与C文件中或头文件同名的变量,但数据类型不同,产生警告。检查自定义变量名是否有冲突
  • 外部声明时,缺省了数据类型,在C51中产生此警告。例如extern para1;

因此,先确认是否有变量名冲突,其次检查声明是否明确了数据类型,即可解决此类警告


常见报错信息

变量定义报错(22.12.19)

main.c(xx): error C141: syntax error near 'int', expected 'sizeof'
  • 首先检查有没有犯弱智错误:括号,分号是否漏打。

  • 如果语法没有问题,那么一般是编译器的差异导致的。Keil编译器遵循的是比较古老的C标准函数定义的内部,必须把所有的局部静态变量自动变量声明了之后,然后才能开始后续的代码书写,否则编译器会报错。

  • 举个栗子,在标准C中,我们可以变量定义写在for循环里。

    for(int i = 0; i < 10; i++){
    	// 正常运行
    }
    

    然而在Keil中,这么写就会报上述错误,导致变量未正确定义,后续只要使用到该变量就会报 undefined identifier 的错误(可能会产生一大堆)。

    所以应该更正为

    int i; //先定义变量
    for(i = 0; i < 10; i++){
    	//正常运行
    }
    

文件类型导入错误(23.3.13)

FCARM - Output Name not specified, please check ‘Options for Target - Utilities

用户的.c.h文件被导入 keil 时有可能会被识别成 image file 文件(图标与正常C文件不同)。选择对应文件右击选择Options for File,在File Type选择正确的文件类型。


地址溢出错误(23.09.03)

*** ERROR Lxxx: ADDRESS SPACE OVERFLOW

51单片机编译时有三个参数

  1. data:共128字节片内RAM区
  2. xdata:共128字节片外RAM区
  3. code:共8KBROM区

注意缩减无用代码,以节省内存空间


变量初始化不明确错误(23.09.03)

error C247: non-address/-constant initializer

定义的变量没有用明确的常量进行初始化。不要把需要计算宏定义等未决的常量赋值给新定义的变量,否则报错。


重复定义错误(24.02.13)

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS

此错误一般是在头文件定义变量造成的。在头文件中一般只做声明不定义变量。因为头文件可能会被多个源文件引用,从而产生重复定义的错误。

如需将该变量扩展其他文件,应在头文件中用extern关键词声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬铃木下的青春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值