最近做51小车,期间发现,sprintf在51单片机上发生了一点小意外。
出现意外的源程序如下:
#include <reg51.h>
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar n;
uint dat;
char buf[128];
void delay_ms(unsigned int nCount)
{
unsigned int j = 0,i=0;
for (j = nCount; j != 0; j--)
for(i = 7960; i != 0; i--);
}
#define UART
#define SENDSTR
#ifdef UART
//串口初始化 晶振为 11.0592M 方式 1 波特率 300-57600
void InitCom(unsigned char BaudRate)
{
unsigned char THTL;
switch (BaudRate)
{
case 1: THTL = 64; break; //波特率 300
case 2: THTL = 160; break; //600
case 3: THTL = 208; break; //1200
case 4: THTL = 232; break; //2400
case 5: THTL = 244; break; //4800
case 6: THTL = 250; break; //9600
case 7: THTL = 253; break; //19200
case 8: THTL = 255; break; //57600
default: THTL = 208;
}
SCON = 0x50; //串口方式 1,允许接收
TMOD = 0x20; //定时器1定时方式2
TCON = 0x40; //设定时器 1 开始计数
TH1 = THTL;
TL1 = THTL;
PCON = 0x80; //波特率加倍控制,SMOD 位
RI = 0; //清收发标志
TI = 0; // 发送
TR1 = 1; //启动定时器
}
//向串口输出一个字符(非中断方式)
void ComOutChar(char OutData)
{
SBUF = OutData; //输出字符
while(!TI); //空语句判断字符是否发完
TI = 0; //清 TI
}
void send_str(char *str)
{
while(*str) ComOutChar(*str++);
}
#define UARTOUT(inum) ComOutChar((uchar)inum);
// ComOutChar((uchar)inum>>8);ComOutChar((uchar)inum&0xff);
#endif // UART
void main()
{
InitCom(6);
for (n=0; n<8; ++n) {
P0 ^= 0x0f;
dat = 4*n + 1;
sprintf(buf,"n:%u dat:%u \n", n, dat);
send_str(buf);
delay_ms(100);
}
}
串口接收到的数据却不是预料的:
这里的 n, dat, 冒号,空格,换行都没有出错,只是两个整数在sprintf中出现了一些异常。
大家都来看看为什么啊?
后记:后来发现,原来是Keil实现的sprintf的问题——要求"%d"对应的参数必须以int型(2B)传入,sprintf在转义时不论如何都读取两个字节;
而这里用char(1B)传入所以导致出现了这样的情况,解决方法也比较简单——只需在传入的参数前面各自加上(int)强制转换一下