交互仍是很有必要的,并且运用键盘和显示器的交互功率仍是很高的。当然,能够直接运用UART进行字符的输入和输出。可是又何须浪费了C的规范输入输出的格局操控之类的功用呢?
这次内容便是运用scanf() 和printf() 函数进行PC和开发板的交互。
一、 C规范函数库
与硬件相关的功用,终究都需求直接拜访硬件。这一点,C的规范函数库的完结面临很多的硬件设备,现已力不从心了。
Atmel Studio运用的C规范库的完结疑似为Newlib。
在工程的 ASF\sam\utils\syscalls\gcc\syscalls.c 文件中,ASF现已完结了若干需求自己完结的函数了(这个文件尽管叫syscall,可是或许仅仅因恪守unix的习气起的。由于这儿没有操作体系,也就没有“体系调用”一说了)。可是相似输入输出这些定制性较高的完结就没有默许的完结。
Newlib的大部分文件读写功用是经过_read() 和_write() 函数完结了。所以完结了这两个函数就能够完结规范输入输出了。函数的签名及参数意义能够google。
二、 完结
留意需求先完结UART的装备作业。
在详细的完结就很简略了。在完结时,能够不对方针文件进行判别,而对一切的输入输出均经过UART完结。若需求判别方针文件是否为规范输入输出,以及在检测到过错时对这个过错进行陈述,就需求包括以下头文件:
#include
#include
_write:
int _write(int file,const char *ptr,int len)
{
// 只处理规范输出
if (file == STDOUT_FILENO){
for (int i = 0; i<LEN ; ++i){< p>
// 经过UART写出数据
while (!(UART0->UART_SR & UART_SR_TXRDY));
UART0->UART_THR = ptr[i];
}
return len;
}else {
errno = EBADF;
return -1;
}
}
_read:
int _read (int file, char *ptr, int len)
{
// 只处理规范输入
if (file == STDIN_FILENO){
int i;
for (i = 0; i < len; i++){
// 经过UART读入数据
while(!(UART0->UART_SR & UART_SR_RXRDY));
ptr[i] = UART0->UART_RHR;
/* 当读到换行符时回来
if ('\n' == ptr[i])
return i;
}
return i; /* 缓o冲?区?已°?慢y */
}else{
errno = EBADF;
return -1;
}
}
测验,以下代码获取UART的输入,并经过UART从头输出:
#include
printf("-I- Test for stdio through UART0\r\n");
char readbuf[64];
while (1)
{
printf("-I- Input something…\r\n");
scanf("%s", readbuf);
printf("Output: %s\r\n",readbuf);
}
留意,PC端在发送数据时需求加上换行符。
三、 在ASF中运用
由于这是一个很常用的功用,所以在ASF中也有完结。在ASF中不光能够进行一些装备,并且在运用的时分真实需求编写的代码只要几行,乃至这几行代码也能够彻底参阅(抄)ASF示例中的代码。
增加模块Standard serial I/O。
在conf_board.h里边现已默许声明晰相应的宏了:
1
2/* Configure UART pins */
#define CONF_BOARD_UART_CONSOLE
在conf_uart_serial.h 里,现已有了运用UART相关的参阅设置代码了。删去参阅代码前面的注释符号即可:
/* 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
调用stdio_serial_init初始化串行规范I/O:
const usart_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);