一、接口简介
UART(Universal Asynchronous Receiver Transmitter)是用来和外围设备交互数据的通用接口,如GPS模块,LCD显示器,XBee收音机等复杂的外围设备,通常使用UART端口(通常简称为串行端口)来通信。
  它是通用的:因为数据传输速率和数据字节格式是可配置的。
  它是异步的:因为没有时钟信号来同步两个设备之间的数据传输,设备的硬件在一个先进先出的缓冲中收集所有的输入数据,直到你的app读取它。
  它是全双工:意味着可以同时发送和接口数据。
  它比I2C更快:但是缺少共享时钟,意味着所有的设备必须同意一个相同的数据传输速率,每个设备可以坚持独立最小定时误差。
  它仅支持点对点通信:不像API和I2C,它仅支持两个设备之间的点对点通信。

UART外围设备通常有两种类型:
  3线端口包含数据接收(RX),数据发送(TX),和接地引用(GUD)信号;
  5线端口添加了请求发送(RTS)和清除发送(CTS)信号,用于硬件流量控制。流量控制允许接收设备标识它的缓冲已满,发送设备应该在发送更多数据之前等待。
二、使用步骤
1.打开连接:创建PeripheralManagerService对象,使用你想打开端口的名称,调用open()方法打开连接。

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);try {PeripheralManagerService manager = new PeripheralManagerService();mDevice = manager.openUartDevice(UART_DEVICE_NAME);} catch (IOException e) {Log.w(TAG, "Unable to access UART device", e);}
}

2.配置参数:调用setBaudrate()、setDataSize、setParity()和setStopBits等方法设置波特率、数据大小、错误校验和结束位等。
每个通过UART发送的字符都被包装在数据帧中,它包含以下组件:

  起始位:在发送数据之前,这行保持固定1位持续时间间隔的时间,来指示新的字符的开始。
  数据位:标识数据字符的单个的位。UART可能配置发送5-9数据位来代表字符。更少的比特减少数据的范围,但是可以提高数据传输效率。
  校验位:可选的错误检查值。如果UART被配置为奇偶校验,一个额外的帧将会添加到这个位,预示着数据内容是否匹配奇偶校验。设置为none则从帧移除这位。
  结束位:在所有数据传输后,该行被重置为可配置的时间间隔,指示字符的结尾。它能配置为1或者2位闲置时间。
通过UART传输数据的速率被称为波特率,它代表了接受和发送的速度,比特每秒。
通过UART连接的连个设备没有共享时钟,都需要使用相同的波特率提前配置来保证数据的正确解码。

public void configureUartFrame(UartDevice uart) throws IOException {uart.setBaudrate(115200);uart.setDataSize(8);uart.setParity(UartDevice.PARITY_NONE);uart.setStopBits(1);
}

如果你的设备支持5线UART端口,启动硬件流控制可以提交数据传输的可靠性。通常这也意味着你可以安全地使用更快的波特率,而丢失传入数据的几率要低得多。
硬件流控制启动之后,当设备的接收缓冲区已满不能接受任何数据的时候,UART发出发送请求(RTS)信号。一旦缓冲区被耗尽这个信号将被清除。相似的,UART监视清除发送(CTS)信号,如果它发现外部设备这行生效,将会增加数据传输。

public void setFlowControlEnabled(UartDevice uart, boolean enable) throws IOException {if (enable) {// Enable hardware flow controluart.setHardwareFlowControl(UartDevice.HW_FLOW_CONTROL_AUTO_RTSCTS);} else {// Disable flow controluart.setHardwareFlowControl(UartDevice.HW_FLOW_CONTROL_NONE);}
}

3.发送数据:使用UART向外设发送缓冲数据,使用write()方法。

public void writeUartData(UartDevice uart) throws IOException {byte[] buffer = {...};int count = uart.write(buffer, buffer.length);Log.d(TAG, "Wrote " + count + " bytes to peripheral");
}

4.监听输入数据:使用read()方法从UART FIFO缓冲中向你的应用读取数据。这个方法接受一个空缓冲来填充输入数据,要读取的最大字节数。
UART读取是非阻塞的,如果在FIFO中没有有效数据它将会立即返回。UartDevice将会返回在读取时候FIFO有效字节的数目,达到要求的数量。为了确保所有的数据都被读取,UART循环读取直到它报告没有数据存在了。
当缓冲为空的时候,为了避免不必要的轮询,使用UartDevice注册一个UartDeviceCallback。当还有数据可读的时候,这个回调调用onUartDeviceDataAvailable()方法。当你的应用程序不再监听输入数据的时候,你应该注销这个回调。
onUartDeviceDataAvailable()回调返回一个布尔值,指示回调是否自动注销获取将来的中断事件。这里返回true在UART FIFO每次数据出现时继续获取事件。

@Override
protected void onStart() {super.onStart();// Begin listening for interrupt eventsmDevice.registerUartDeviceCallback(mUartCallback);
}
public void readUartBuffer(UartDevice uart) throws IOException {// Maximum amount of data to read at one timefinal int maxCount = ...;byte[] buffer = new byte[maxCount];int count;while ((count = uart.read(buffer, buffer.length)) > 0) {Log.d(TAG, "Read " + count + " bytes from peripheral");}
}
@Override
protected void onStop() {super.onStop();// Interrupt events no longer necessarymDevice.unregisterUartDeviceCallback(mUartCallback);
}
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {@Overridepublic boolean onUartDeviceDataAvailable(UartDevice uart) {// Read available data from the UART devicetry {readUartBuffer(uart);} catch (IOException e) {Log.w(TAG, "Unable to access UART device", e);}// Continue listening for more interruptsreturn true;}@Overridepublic void onUartDeviceError(UartDevice uart, int error) {Log.w(TAG, uart + ": Error event " + error);}
};

5.关闭连接:当你完成和外部设备的通信,调用close()方法关闭连接并释放资源。此外在现有端口关闭之前,你不能打开相同端口的新连接。

@Override
protected void onDestroy() {super.onDestroy();if (mDevice != null) {try {mDevice.close();mDevice = null;} catch (IOException e) {Log.w(TAG, "Unable to close UART device", e);}}
}

三、案例演示
这里我们和大家演示一下,电脑和树莓派如何通过FTDI TTL-232R连接线进行信息传递,该线使用的是UART接口。
1.硬件准备
     树莓派3开发板 1块
     FTDI芯片 TTL-232R-3V3 USB转TTL线 1根
广告时间咯:如果你还没有自己的开发板和元器件,到我们的“1024工场旗舰店”来逛逛一逛吧(文章底部二维码),这里能一次性有买到你想要的!
2.电路搭建


注意:在连接线的时候是连接线的TX连接线插入树莓派的RX引脚,同理RX插入TX。
2.代码编写
UARTDemo\app\src\main\java\com\chengxiang\uartdemo\MainActivity.java

public class MainActivity extends AppCompatActivity {private static final String TAG = "LoopbackActivity";private static final String UART_DEVICE_NAME = "UART0";private static final int BAUD_RATE = 115200;private static final int DATA_BITS = 8;private static final int STOP_BITS = 1;private static final int CHUNK_SIZE = 512;private UartDevice mUartDevice;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);PeripheralManagerService peripheralManagerService = new PeripheralManagerService();try {//通过UART接口名称UART0,打开接口mUartDevice = peripheralManagerService.openUartDevice(UART_DEVICE_NAME);//设置波特率、数据大小、校验等参数mUartDevice.setBaudrate(BAUD_RATE);mUartDevice.setDataSize(DATA_BITS);mUartDevice.setParity(UartDevice.PARITY_NONE);mUartDevice.setStopBits(STOP_BITS);//注册数据监听,在有数据可读的时候回调mUartDevice.registerUartDeviceCallback(mUartDeviceCallback);} catch (IOException e) {e.printStackTrace();}}private UartDeviceCallback mUartDeviceCallback = new UartDeviceCallback() {@Overridepublic boolean onUartDeviceDataAvailable(UartDevice uart) {try {//读取PC终端发来的数据 ,并原封返回给PCbyte[] buffer = new byte[CHUNK_SIZE];int read;while ((read = mUartDevice.read(buffer, buffer.length)) > 0) {Log.w(TAG, "read from PC:"+ new String(buffer));mUartDevice.write(buffer, read);}} catch (IOException e) {Log.w(TAG, "Unable to transfer data over UART", e);}return true;}@Overridepublic void onUartDeviceError(UartDevice uart, int error) {Log.w(TAG, uart + ": Error event " + error);}};@Overrideprotected void onDestroy() {super.onDestroy();//在不需要的时候,关闭连接if (mUartDevice != null) {try {mUartDevice.close();mUartDevice = null;} catch (IOException e) {Log.w(TAG, "Unable to close UART device", e);}}}
}

代码库:https://github.com/ThingsDeveloper/uartdemo

3.运行结果

我们是以windows系统演示,故使用了Termite终端,设置串口(相关驱动推荐使用驱动人生自动安装) 连接参数(与代码中一致,相关操作这里就不详细介绍)。

在终端输入hello uart(蓝色),就收到返回的hello uart(红色)

1.抛弃各种找元器件的烦恼,来“1024工场”旗舰店,一次性买到你所想要的:树莓派套装—专为Android Things打造。

电脑用户,点击如下链接进入淘宝宝贝页面:
https://item.taobao.com/item.htm?spm=686.1000925.0.0.3f11c9ed68fPu7&id=549263158263
手机用户,打开淘宝客户端扫描二维码:
2.完整和持续更新的《使用Android打开物联网开发大门——Andoid Thigns开发》文档,欢迎大家阅读! 
https://www.kancloud.cn/workshop1024/android_things_develop/360773 
 
3.新技术,新未来!欢迎大家关注“1024工场”微信服务号,时刻关注我们的最新的技术讯息。

4.加入“Android Things开发”QQ讨论群,一起学习一起Hi。(甭客气!尽情的扫描或者长按!)

Android Things:外设I/O接口-UART相关推荐

  1. 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)

    更多技术干货,欢迎扫码关注博主微信公众号:HowieXue,共同探讨软件知识经验,关注就有海量学习资料免费领哦: 目录 0背景 1.手机USB接口通信特点 1.1 使用方便 1.2 通用性强 1.3 ...

  2. 定制Android系统开发之一——提供接口的方式

    何为定制Android系统?就是在特定的硬件上,移植上Android操作系统,并修改原生Android系统以提供给定制的APP操作定制硬件的方法. 所以,定制Android的主要工作有以下三部分: 适 ...

  3. Android 9 的非 SDK 接口限制 | 中文教学视频

    我们一直致力于为 Android 用户和开发者提供稳定的体验.秉持这种理念,我们逐步限制应用使用非公开接口,因为这种做法往往导致用户遭遇系统崩溃及开发者需要紧急发布修复的风险.在 Android 8. ...

  4. (92)低速接口UART、IIC、SPI介绍,面试必问(十六)(第19天)

    (92)低速接口UART.IIC.SPI介绍,面试必问(十六)(第19天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)低速接口UART.IIC.SPI介绍,面 ...

  5. Android P (4)一种绕过Android P上非SDK接口限制的简单方法

    一种绕过Android P上非SDK接口限制的简单方法 众所周知,Android P 引入了 针对非 SDK 接口(俗称为隐藏API)的使用限制.这是继 Android N上 针对 NDK 中私有库的 ...

  6. android 首页接口设计方案,Android开发最佳实践——1.接口设计

    Android开发最佳实践--1.接口设计 一个项目刚开始的时候,最需要确认的就是接口设计了:数据如何传递,使用什么格式什么协议乃至如何保证安全性.如果一个项目的接口设计不合理--比如没有考虑到安全性 ...

  7. Android 推送消息开放接口 OpenPush

    Android 推送消息开放接口 OpenPush 我们知道, 在中国不能使用 google 的服务. 在中国销售的手机甚至没有安装 google 的服务.所以, 原本由 google gcm 提供的 ...

  8. Android开发规范:API接口安全设计规范

    公众号[国民程序员]回馈粉丝福利: 现金红包和送书活动火热进行中,点击参与! 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买. 书籍详情请 ...

  9. Android 通过蒲公英pgyer的接口 Service 实现带进度下载App 通知栏显示 在线更新 自动更新Demo

    Android 通过蒲公英pgyer的接口 Service 实现带进度下载App 通知栏显示 在线更新 自动更新Demo 标签: app在线更新下载Update升级 2016-09-18 20:47  ...

最新文章

  1. 给网站管理员的建议:创建可利用的、可抓取的网站
  2. Java集合:Integer.parseInt() String.substring()
  3. DL之self-attention:self-attention自注意力机制的简介、应用之详细攻略
  4. 全志代码中的bug之2
  5. python自动化测试视频教程_精品系列-悠悠Python自动化测试学习视频,资源教程下载...
  6. 统计、可视化两不误,多达19种可视化技能你一定要掌握~~
  7. 2015年第六届蓝桥杯C/C++ B组国赛 —— 第一题:积分之迷
  8. 【机器学习】主题模型
  9. RabbitMQ指南之四:路由(Routing)和直连交换机(Direct Exchange)
  10. MetaTransformer:简单到尴尬的视觉模型
  11. 华为云·云享专家公开课:45分钟掌握Python项目部署与调度核心逻辑直播
  12. neo4j查询节点的出度与入度的数量
  13. C++循环语句的效率
  14. 网络编程+并发编程总结
  15. 推荐!12个经典开源人脸识别数据库
  16. 三维空间点到线段的距离
  17. 明日方舟公式计算机,【科普向】明日方舟里的伤害计算公式
  18. 人脸识别技术及实现思路
  19. 2021年安全生产模拟考试(全国特种作业操作证电工作业-高压电工模拟考试题库二)
  20. 嵌入式工程师月薪最高排行榜

热门文章

  1. AI智能车牌识别技术如何提升出行体验?
  2. linux mysql dengl_linux环境搭建(四)--MYSQL
  3. SpringBoot22-spingboot数据访问-Spring Data JPA
  4. 电脑配置jdk环境变量_苹果电脑配置环境变量
  5. mysql 8.0 新特性 统计直方图 优化执行计划SQL查询
  6. 使用OpenOffice插件实现RTF/WORD转PDF转多张图片或者一张图片
  7. Python 读取文件夹下的Excel文件导入到数据库
  8. 一款产品经理很好用的产品原型Axure配合软件--墨刀,将产品原型Axure,添加到墨刀,可以/预览/设计/编辑/共享/协同设计
  9. Github-Client(ANDROID)开源之旅(四) ------ 简介Roboguice
  10. Ruoyi 解释(一)