目录
一、问题描述:
最近公司有个《很小很小很小的项目》让我尝试着去接手,该项目是用STC单片机开发一个无线采集终端。该项目有个重要的内容是“串口输出日志打印功能”,当然,这是个很不值得一提的功能开发,但是却不像传统STM32中 printf 函数的输出格式。
- 我在工程中定义了8位的变量使用%X格式打印出的值却变成了16位,且赋值为0后却打印出16位的“随机数值”;
- 然后定义了一个16位的变量,使用 %d 格式化打印,也不能正确打印变量的值。
- 打印其他异常的值,使用串口发送单字节的函数,分别发送高八位和低八位,又能正确将变量的值打印出来
二、现状分析:
小立确定 printf 已经正确重定向到指定的串口上
/********************* Printf 重定向函数 ************************/
#if(PRINTF_SEL == 1)
char putchar(char c)
{
TX1_write2buff(c);
return c;
}
#elif(PRINTF_SEL == 2)
char putchar(char c)
{
TX2_write2buff(c);
return c;
}
#elif(PRINTF_SEL == 3)
char putchar(char c)
{
TX3_write2buff(c);
return c;
}
#elif(PRINTF_SEL == 4)
char putchar(char c)
{
TX4_write2buff(c);
return c;
}
#endif
三、找出原因:
通过查阅资料,小立发现51单片机系列通过 printf()函数 打印格式化数据的时候,使用 %d 、%X之类的格式符是无效的,所以才会产生随机数的情况!在STC单片机中,变量类型输出格式含义如下二表:
表三-1 常用变量类型输出格式含义
格式 | 含义 | 类型 |
---|---|---|
%bd | 一个字节、有符号 | char |
%bu | 一个字节、无符号 | unsigned char |
%hd | 两个字节、有符号 | short |
%hu | 两个字节、无符号 | unsigned short |
%ld | 四个字节、有符号 | int |
%lu | 四个字节、无符号 | unsigned int |
表三-2 其他变量类型输出格式含义
Type Argument | Type Input | Format |
---|---|---|
d | int | Signed decimal number. |
u | unsigned int | Unsigned decimal number. |
o | unsigned int | Unsigned octal number. |
x | unsigned int | Unsigned hexadecimal number using “0123456789abcedf”. |
X | unsigned int | Unsigned hexadecimal number using “0123456789ABCDEF”. |
f | float | Floating-point number formatted as<[>-<]>dddd.dddd. %.1f(输出保留1位小数) |
e | float | Floating-point number formatted as<[>-<]>d.dddde<[>-<]>dd. |
E | float | Floating-point number formatted as<[>-<]>d.ddddE<[>-<]>dd. |
g | float | Floating-point number using either the e or f format, whichever is more compact for the specified value and precision. |
G | float | Floating-point number using either the E or f format, whichever is more compact for the specified value and precision. |
c | char | A single character. |
s | * | A string of characters terminated by a null character (‘\0’). |
p | * | A generic pointer formatted as t:aaaa where t is the memory type and aaaa is the hexadecimal address. |
!!!特别注意: 51单片机中 int 为2个字节
四、测试与解决问题:
通过上述资料,我尝试着输出六种常用的数据类型:
unsigned char q = 127;
char w = -66 ;
unsigned short e = 255;
short r = -222;
unsigned int t = 65534;
int y = -12345;
printf("q=%bu w=%bd e=%hu r=%hd t=%hu y=%hd \r\n",q,w,e,r,t,y);
调试助手正确输出打印结果:
q=128 w=-15 e=256 r=-25 t=65535 y=-32765