交互还是很有必要的,而且使用键盘和显示器的交互效率还是很高的。当然,可以直接使用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 <unistd.h>
#include <errno.h>
  • _write:

    int _write(int file,const char *ptr,int len)
    {
    // 只处理标准输出
    if (file == STDOUT_FILENO){
    for (int i = 0; i<len ; ++i){
    // 通过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 <stdio.h>
    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示例中的代码。

  1. 添加模块Standard serial I/O

  2. conf_board.h里面已经默认声明了相应的宏了:

    /* Configure UART pins */
    #define CONF_BOARD_UART_CONSOLE
  3. 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
  4. 调用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);

SAM4E单片机之旅——17、通过UART进行标准IO的更多相关文章

  1. SAM4E单片机之旅——11、UART之PDC收发

    使用PDC进行数据的收发能减少CPU的开销.这次就使用PDC进行UART数据的接收与发送,同时,也利用TC也实现了PDC的接收超时. PDC是针对外设的DMA控制器.对比DMA控制器,它更为简便,与相 ...

  2. SAM4E单片机之旅——10、UART与MCK之PLL

    为使用更更高的波特率,则需要更更高的外设时钟的频率.这个时候就需要用到锁相环(PLL)了.锁相环可以对输入的时钟进行分频.升频后进行输出.MCK可以使用的锁相环为PLLA,而PLLA的输入时钟为MAI ...

  3. SAM4E单片机之旅——9、UART与MCK之MAINCK

    为得到更高的带宽,需要使用更高的波特率.UART波特率的计算已经介绍过了,现在就尝试下调整外设的时钟频率.可以有多种方法调整外设时钟(MCK)的频率,这里先介绍先主要时钟(MAINCK)的设置,其中包 ...

  4. SAM4E单片机之旅——8、UART初步

    通信还是比让LED灯闪烁实用得多的. 这次试试使用UART,实现开发版和PC间的通信.功能比较简单,就是把PC发向开发版的内容发送回去.这次主要介绍一下UART的配置,至于通信,则使用较为简单的不断查 ...

  5. SAM4E单片机之旅——18、通过AFEC(ADC)获取输入的电压

    很多时候,一个电压不仅仅需要定性(高电平或者低电平),而且要定量(了解具体电压的数值).这个时候就可以用到模数转换器(ADC)了.这次的内容是测量开发板搭载的滑动变阻器(VR1)的电压,然后把ADC转 ...

  6. SAM4E单片机之旅——24、使用DSP库求向量数量积

    DSP(Digital Signal Processing,数字信号处理)中会使用大量的数学运算.Cortex-M4中,配置了一些强大的部件,以提高DSP能力.同时CMSIS提供了一个DSP库,提供了 ...

  7. SAM4E单片机之旅——23、在AS6(GCC)中使用FPU

    浮点单元(Floating Point Unit,FPU),是用于处理浮点数运算的单元. 为使用FPU,除了需要启用FPU外,还需要对编译器进行设置,以使其针对浮点运算生成特殊的指令.虽然在Atmel ...

  8. SAM4E单片机之旅——19、CAN间通信

    CAN协议具有良好的可靠性,在工业中应用广泛.这次就先熟悉CAN的基本功能. 开发板有两个CAN,每个CAN有8个信箱.这次内容是从CAN0的信箱0发送数据到CAN1的信箱0. 除本次使用的功能外,C ...

  9. SAM4E单片机之旅——13、LCD之ASF初步

    在Atmel Studio 6中,集成了Atmel Software Framework(ASF框架).通过它提供的库,可以很快速地完成新的项目. 这次的最终目标使用ASF在LCD上显示出文字“Hel ...

随机推荐

  1. 使用 Responsive Elements 快速构建响应式网站

    Responsive Elements 可以使任何元素来适应和应对他们所占据的区域.这是一个轻量的 JavaScript 库,你可以轻松嵌入到你的项目.元素会更具自己的宽度,自动响应和适应空间的增加或 ...

  2. P6 EPPM R16.1安装与配置指南(一)

    标题 http://www.cnblogs.com/endv/p/5634620.html 安装与配置指南安装与配置指南(数据库)说明哪些How to set up the P6专业数据库和服务器.a ...

  3. oracle 查询 当前最大时间的value的值

    数据列表: table : text id  datetime        name    value 1   2015-03-1     张三       3400 2   2015-03-1   ...

  4. 取值:webconfig中的key

    String rootUrl = System.Configuration.ConfigurationManager.AppSettings["SiteDomain"].ToStr ...

  5. [moka收藏]php正则表达式验证

    手机号验证规则[['mobile'], 'match','pattern' =>"/^1[34578]\\d{9}$/"], [['sendmail_limit'],'mat ...

  6. python函数和常用模块(二),Day4

    内置函数2 装饰器 字符串格式化 生成器 迭代器 递归 模块 序列化相关 time模块 datetime模块 内置函数2 callable() # 是否可以被执行,是否可以被调用 chr() # as ...

  7. [翻译]:SQL死锁-锁的类型

    很久没有写博客了,这里面的原因有很多.最近的一个项目由于客户明确提出要做下性能压力测试,使用的工具就是VS自带的压力测试工具.以前其它项目做压力测试后反馈的其中一个重要问题就是数据库的死锁.没想到我们 ...

  8. python3.5.2爬虫

    话不多说,都在代码里 #下载斗鱼颜值栏目主播照片 #author:ives #date:2016-8-28 21:58 #e-mail:renhanlinbsl@163.com import urll ...

  9. Android图像处理之Bitmap类

      Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图像剪切.旋转.缩放等操作,并可以指定格式保存图像文件.本文从应用的角度,着重介绍怎么用Bitmap来实现 ...

  10. Gulp-前端进阶A-3---如何不刷新监控文件变化?

    npm install --save-dev gulp-connect npm install --save-dev gulp-livereload npm其他,前面已有 var gulp = req ...