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

开发环境问题

CH340串口识别失败(22.12.17)

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

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内核设计。
  • 将两个版本都下载至同一个目录下即可同时使用。

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

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

如何修改字体大小(22.12.17)

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

Keil的 “0xFD” Bug(23.03.04)

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

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


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

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

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


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编码串口助手


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°旋转。


C51语法细节问题

将浮点数或整数转化为字符串方案(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个字节),会导致转换结果异常


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

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

事实上

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

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

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

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

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


Keil编译器中数据类型字节数问题(23.09.03)

keil中,int 2字节 65536
PC端 int 4字节

Unsigned char 1 char 1


bit数据类型问题(23.09.03)


常见警告信息

未调用函数警告(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

单片机编译时有三个参数
data 128字节
xdata 128字节
code 8KB


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

error C247: non-address/-constant initializer

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

猜你喜欢

转载自blog.csdn.net/m0_46500149/article/details/128350545