最近做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)強制轉換一下