本文隶属于AVR单片机教程系列。

 

上一讲中,我们实现了单片机开发板向电脑传输数据。在这一讲中,我们将通过电脑向单片机发送指令,让单片机根据指令控制LED。这一次,两端的TX与RX需要交叉连接,单片机TX连接串口工具RX也是需要的,因为程序会根据指令反馈信息。

为了简单起见,我们的程序只需要控制4个板载LED。指令包含两个字节:第一个字节为rygb中的一个,分别表示红、黄、绿、蓝灯;第二个字节为01,表示灯不亮或亮。

然而,a2这样的指令是没有意义的,却是可能出现的。即使用户已经熟悉了这8条指令,也可能会不小心打错。我们应当记住,用户是世界上最愚蠢的人,我们要把他们可能犯的错误都想到,然后在程序中合理地处理。比如,对于不合法的指令,程序忽略指令,并返回What?给电脑;对于合法的,则执行并返回Done!

#include <ee1/led.h>
#include <ee1/uart.h> int main(void)
{
led_init();
uart_init(UART_DUPLEX);
char temp[3];
while (1)
{
uart_scan_string_n(temp, 2);
bool good = true;
led_t led;
switch (temp[0])
{
case 'r': led = LED_RED ; break;
case 'y': led = LED_YELLOW; break;
case 'g': led = LED_GREEN ; break;
case 'b': led = LED_BLUE ; break;
default: good = false; break;
}
bool on;
switch (temp[1])
{
case '0': on = false; break;
case '1': on = true ; break;
default: good = false; break;
}
if (good)
{
led_set(led, on);
uart_print_string("Done!\n");
}
else
uart_print_string("What?\n");
}
}

while循环的周期是多少呢?没有delay语句,是不是循环在很快地扫描呢?不是,uart_scan_string_n函数一直等待直到串口接收到了规定量的数据。

实际上,这一系列串口接收的函数的功能非常受限——程序必须等待数据到来,不能错过它,这与scanf等函数从缓冲区读取数据不同。当然,单片机系统中的串口输入(以及输出)也可以实现缓冲区,并且是一种实用并常用的做法,但这要涉及到中断,是以后的内容。你可以试着利用数据手册以及其他资源实现一个带缓冲的串口输入输出。在avr-gcc中,使用中断要先#include <avr/interrupt.h>,串口接收中断写为ISR(USART0_RX_vect) { }

 

作业:

  1. 如果通过串口发送指令r11g1,只有红色LED会亮,因为程序对指令的解读是r11g1,而我只是不小心(故意)多打了一个1,本意是想让红色和绿色LED都亮。改进程序解决这个问题。

  2. 基于uart_scan_char,实现my_scan_int函数,从串口上读取十进制整数(注意正负号与溢出等;你可以了解一下atoi)。

AVR单片机教程——串口接收的更多相关文章

  1. AVR单片机教程——串口发送

    本文隶属于AVR单片机教程系列.   到目前为止,我们的开发板只能处理很小量的数据:读取几个引脚电平,输出几个LED,顶多用数码管显示一个两位数字.至于输入一个指令.输出一条调试信息,甚至用scanf ...

  2. AVR单片机教程——UART进阶

    本文隶属于AVR单片机教程系列.   在第一期中,我们已经开始使用UART来实现单片机开发板与计算机之间的通信,但只是简单地讲了讲一些概念和库函数的使用.在这一篇教程中,我们将从硬件与软件等各方面更深 ...

  3. AVR单片机教程——点亮第一个LED

    做了这么多准备,我们终于可以开始用开发板做点事了. 单片机编程与计算机编程有一些不同点.程序都要有零个或多个输入.一个或多个输出,这是两者都有的,但是计算机编程的输入输出主要靠控制台,而单片机没有. ...

  4. AVR单片机教程——ADC

    ADC 计算机的世界是0和1的.单片机可以通过读取0和1来确定按键状态,也可以输出0和1来控制LED.即使是看起来不太0和1的PWM,好像可以输出0到5V之间的电压一样,达到0和1之间的效果,但本质上 ...

  5. AVR单片机教程——定时器中断

    本文隶属于AVR单片机教程系列.   中断,是单片机的精华. 中断基础 当一个事件发生时,CPU会停止当前执行的代码,转而处理这个事件,这就是一个中断.触发中断的事件成为中断源,处理事件的函数称为中断 ...

  6. AVR单片机教程——矩阵键盘

    本文隶属于AVR单片机教程系列.   开发板上有4个按键,我们可以把每一个按键连接到一个单片机引脚上,来实现按键状态的检测.但是常见的键盘有104键,是每一个键分别连接到一个引脚上的吗?我没有考证过, ...

  7. AVR单片机教程——示波器

    本文隶属于AVR单片机教程系列.   在用DAC做了一个稍大的项目之后,我们来拿ADC开开刀.在本讲中,我们将了解0.96寸OLED屏,移植著名的U8g2库到我们的开发板上,学习在屏幕上画直线的算法, ...

  8. AVR单片机教程——DAC

    本文隶属于AVR单片机教程系列.   单片机的应用场景时常涉及到模拟信号.我们已经会使用ADC把模拟信号转换成数字信号,本讲中我们要学习使用DAC把数字信号转换成模拟信号.我们还将搭建一个简单的功率放 ...

  9. AVR单片机教程——走向高层

    本文隶属于AVR单片机教程系列.   在系列教程的最后一篇中,我将向你推荐3个可以深造的方向:RTOS.C++.事件驱动.掌握这些技术可以帮助你更快.更好地开发更大的项目. 本文涉及到许多概念性的内容 ...

随机推荐

  1. H3C配置路由器作为TFTP客户端

  2. jquery ajax请求步骤

    $.ajax({ type: "GET", url: "/alink-hq/checkCode", data: { "mobile": ph ...

  3. C# 大端小端转换

    关于大端和小端,是一个有趣的问题.本文告诉大家如何在C#转换大端和小端. 这里有一个有趣的故事,请看详解大端模式和小端模式 - CSDN博客 默认的 C# 使用的是小端,如果收到的消息是大端,那么就会 ...

  4. 数据库java包

    package com.hgkj.model.dao.impl; import java.sql.*; public class DBManager { private static final St ...

  5. Python2_实现文件中特定内容的获取

    ===================================================== 参考链接 Python 文本文件内容批量抽取:https://blog.csdn.net/q ...

  6. slim中返回结果加密的

    //返回结果不加密 $this->get("/open]",function (Request $request, Response $response, $args) {  ...

  7. python OrderedDict

    15年16年接触python时候,还不知道这个函数,只知道dict的无序,造成了一些麻烦 今天view 代码,发现了 OrderedDict() 在python2.7中比较吃内存 pop(获取指定ke ...

  8. 牛客国庆days赛 地铁

    传送门:https://ac.nowcoder.com/acm/problem/52805 我佛了,还能跑边图啊!!! 跑边图不能用vector啦啦啦啦啦 具体也不难,就直接上代码了 #include ...

  9. 大数据(5)---分布式任务资源调度Yarn

    前面也说到过的Yarn是hadoop体系中的资源调度平台.所以在整个hadoop的包里面自然也是有它的.这里我们就简单介绍下,并配置搭建yarn集群. 首先来说Yarn中有两大核心角色Resource ...

  10. fiddler 手机 https 抓包

    fiddler手机抓包原理fiddler手机抓包的原理与抓pc上的web数据一样,都是把fiddler当作代理,网络请求走fiddler,fiddler从中拦截数据,由于fiddler充当中间人的角色 ...