玩轉(zhuǎn)單片機(jī)之智能車小露——數(shù)字與字符串的轉(zhuǎn)換與打印
在 玩轉(zhuǎn)單片機(jī)之智能車小露——通過UART為單片機(jī)增加TTY終端 中我們?cè)?code>TTYEchoNumber中使用 printf 函數(shù)將數(shù)字輸出到串口。其實(shí)數(shù)字很多時(shí)候都不是以數(shù)的形式表示的,幾乎所有的輸入和顯示環(huán)節(jié)數(shù)字都是以字符串的形式來表示。
有沒有想過,為什么使用鍵盤輸入一串字符串,輸入到計(jì)算機(jī)就會(huì)自動(dòng)變成對(duì)應(yīng)的數(shù)字了?有沒有嘗試過把單片機(jī)程序中的數(shù)字輸出到串口、數(shù)碼管或都顯示屏上?
本文簡(jiǎn)單介紹單片機(jī)編程可能用到的數(shù)據(jù)與字符串的轉(zhuǎn)換,以及標(biāo)準(zhǔn)輸入輸出stdio相關(guān)的一些補(bǔ)充知識(shí)。
printf使用(重定向)
#include <stdio.h>
void main(){
printf("Hello,world!");
}
有多少人是從上面這個(gè)程序開始接觸編程的?又有多少人在接觸單片機(jī)后沒有再使用過這個(gè)函數(shù)?
Keil的stdio中包含 printf 函數(shù),但是使用時(shí)需要將 printf 的輸出重定向到特定設(shè)備(如串口或顯示屏),方法是重寫putchar函數(shù)。
STC 庫函數(shù)已默認(rèn)將 printf 重定向到 UART,修改宏PRINTF_SELECT的值可以定向到不同的串口。
#define PRINTF_SELECT UART1 //選擇 printf 函數(shù)所使用的串口,參數(shù) UART1~UART4
/********************* Printf 函數(shù) ************************/
#if(PRINTF_SELECT == UART1)
char putchar(char c){
TX1_write2buff(c);
return c;
}
#endif
printf 也可以定向到其它顯示設(shè)備,如重寫putchar函數(shù)將字符打印到 OLED 顯示屏上并移動(dòng)光標(biāo)到下一個(gè)位置,即可以將 printf 重定向到 OLED 顯示屏,在 玩轉(zhuǎn)單片機(jī)之智能車小露——OLED顯示屏控制 里我們將進(jìn)行實(shí)現(xiàn)(如果有鏈接代表已完成實(shí)現(xiàn))。
數(shù)字轉(zhuǎn)換為字符串
數(shù)字轉(zhuǎn)換為字符串一般都是用于輸出和顯示。轉(zhuǎn)換原理也很簡(jiǎn)單,按位將數(shù)字替換成可以顯示的數(shù)字代表的ASCII碼值:
char = num + '0';
如果想具體了解轉(zhuǎn)換過程可以搜索參考itoa函數(shù)的代碼(不是標(biāo)準(zhǔn)庫函數(shù),不一定在所有平臺(tái)中都可以直接使用)。實(shí)際上stdio提供了更加靈活的轉(zhuǎn)換形式:
extern int printf(const char *, ...);
extern int sprintf(char *, const char *, ...);
sprintf用于將格式化的數(shù)據(jù)寫入字符串中,而printf直接將格式化數(shù)據(jù)輸出。這兩個(gè)函數(shù)的功能在這里不再細(xì)述,需要注意的是,Keil Cx51是8位平臺(tái),printf 無法自動(dòng)識(shí)別變量的位寬,直接使用%d或%u打印數(shù)字時(shí),可能會(huì)遇到輸出異常的問題。(有沒有哪個(gè)冤大頭在ADC采樣調(diào)試時(shí)使用 printf 輸出采樣數(shù)據(jù)一直顯示錯(cuò)誤,還在不停懷疑單片機(jī)或者庫函數(shù)存在問題?)
要避免此類問題,必須顯式定義數(shù)據(jù)類型傳遞給 printf 函數(shù):
The optional characters b, h, and l may immediately precede the type character to respectively specify char, short, or long versions of the integer types d, i, u, o, and x.
(可選字母 b,h,l 可以用來指定 d,i,u,o,x 的整形是 char,short 還是 long)
char a = 1;
int b = 12365;
long c = 0x7FFFFFFF;
unsigned char x = 'A';
unsigned int y = 54321;
unsigned long z = 0x4A6F6E00;
printf ("char %bd int %d long %ld",a,b,c);
printf ("Uchar %bu Uint %u Ulong %lu",x,y,z);
printf ("xchar %bx xint %x xlong %lx",x,y,z);
字符串轉(zhuǎn)換為數(shù)字
標(biāo)準(zhǔn)庫stdlib提供了3個(gè)字符串轉(zhuǎn)換為數(shù)字的函數(shù),分別可以將字符串轉(zhuǎn)換為浮點(diǎn)數(shù)、長(zhǎng)整形和短整形。
extern float atof (char *s1);
extern long atol (char *s1);
extern int atoi (char *s1);

浙公網(wǎng)安備 33010602011771號(hào)