交互還是很有必要的,而且使用鍵盤和顯示器的交互效率還是很高的。當然,可以直接使用UART進行字符的輸入和輸出。但是又何必浪費了C的標準輸入輸出的格式控制之類的功能呢?
這次內(nèi)容就是使用scanf()和printf()函數(shù)進行PC和開發(fā)板的交互。
一、C標準函數(shù)庫
與硬件相關(guān)的功能,最終都需要直接訪問硬件。這一點,C的標準函數(shù)庫的實現(xiàn)面對眾多的硬件設(shè)備,已經(jīng)無能為力了。
Atmel Studio使用的C標準庫的實現(xiàn)疑似為Newlib。
在工程的ASF\sam\utils\syscalls\gcc\syscalls.c文件中,ASF已經(jīng)實現(xiàn)了若干需要自己實現(xiàn)的函數(shù)了(這個文件雖然叫syscall,但是可能只是因遵守unix的習(xí)慣起的。因為這里沒有操作系統(tǒng),也就沒有“系統(tǒng)調(diào)用”一說了)。但是類似輸入輸出這些定制性較高的實現(xiàn)就沒有默認的實現(xiàn)。
Newlib的大部分文件讀寫功能是通過_read()和_write()函數(shù)實現(xiàn)了。所以實現(xiàn)了這兩個函數(shù)就可以實現(xiàn)標準輸入輸出了。函數(shù)的簽名及參數(shù)含義可以google。
二、實現(xiàn)
注意需要先完成UART的配置工作。
在具體的實現(xiàn)就很簡單了。在實現(xiàn)時,可以不對目標文件進行判斷,而對所有的輸入輸出均通過UART完成。若需要判斷目標文件是否為標準輸入輸出,以及在檢測到錯誤時對這個錯誤進行報告,就需要包含以下頭文件:
12#include #include
_write:
123456789101112131415int_write(intfile,constchar*ptr,intlen){// 只處理標準輸出if(file == STDOUT_FILENO){for(inti = 0; iUART_SR & UART_SR_TXRDY));UART0->UART_THR = ptr[i];}returnlen;}else{errno= EBADF;return-1;}}
_read:
12345678910111213141516171819int_read (intfile, char*ptr, intlen){// 只處理標準輸入if(file == STDIN_FILENO){inti;for(i = 0; i < len; i++){// 通過UART讀入數(shù)據(jù)while(!(UART0->UART_SR & UART_SR_RXRDY));ptr[i] = UART0->UART_RHR;/* 當讀到換行符時返回if ('\n' == ptr[i])return i;}return i; /* 緩o沖?區(qū)?已°?慢y */}else{errno= EBADF;return-1;}}
測試,以下代碼獲取UART的輸入,并通過UART重新輸出:
123456789#include printf("-I- Test for stdio through UART0\r\n");charreadbuf[64];while(1){printf("-I- Input something...\r\n");scanf("%s", readbuf);printf("Output: %s\r\n",readbuf);}
注意,PC端在發(fā)送數(shù)據(jù)時需要加上換行符。
三、在ASF中使用
因為這是一個很常用的功能,所以在ASF中也有實現(xiàn)。在ASF中不但可以進行一些配置,而且在使用的時候真正需要編寫的代碼只有幾行,甚至這幾行代碼也可以完全參考(抄)ASF示例中的代碼。
添加模塊Standard serial I/O。
在conf_board.h里面已經(jīng)默認聲明了相應(yīng)的宏了:
12/* Configure UART pins */#define CONF_BOARD_UART_CONSOLE
在conf_uart_serial.h里,已經(jīng)有了使用UART相關(guān)的參考設(shè)置代碼了。刪去參考代碼前面的注釋符號即可:
1234567/* A reference setting for UART *//** UART Interface */#define CONF_UART CONSOLE_UART/** Baudrate setting */#define CONF_UART_BAUDRATE 115200/** Parity setting */#define CONF_UART_PARITY UART_MR_PAR_NO
調(diào)用stdio_serial_init初始化串行標準I/O:
1234567constusart_serial_options_t uart_serial_options = {.baudrate = CONF_UART_BAUDRATE,.paritytype = CONF_UART_PARITY};/* Configure console UART. */sysclk_enable_peripheral_clock(CONSOLE_UART_ID);stdio_serial_init(CONF_UART, &uart_serial_options);
評論
查看更多