YTM32的LINFlexD实现UART功能详解

文章目录

    • 引言
    • 简介
    • 原理与机制
      • 同UART模式相关的寄存器
      • 时钟与波特率
      • 数据缓冲区
      • 发送过程
      • 接收过程
    • 软件
    • 参考文献

引言

初看YTM32B1ME的手册时,一眼看上去,竟然没有找到UART模块的章节,心想这车规MCU的产品定义也太激进了,直接把工业和消费类微控制器中最常用的通信外设给整没了,但想想手头上的EVB-YTM32B1ME-Q144板子上,确实有通过CH340转接出来的串口接口。一顿上下求索之后,才发现,是用LINFlexD外设模块"兼容"了UART的功能。本文将从LINFlexD外设模块的介绍中,专门抽出同UART相关的内容,结合笔者调试过程中整理的知识点形成一份材料,对YTM32微控制器平台上基于LINFlexD实现UART外设功能的专题详解。

YTM32微控制器平台的LINFlexD外设,是专用于汽车电子系统中常用的LIN通信协议而设计的通信引擎,但因LIN通信协议中的“字节域”格式同UART相同,因此在硬件设计上,从而为LIN通信引擎兼容UART通信引擎提供了可能。实际上,在一些没有专门设计LIN通信引擎的微控制器平台上,大多是通过更常见的UART通信引擎配合软件来模拟LIN通信引擎实现LIN通信的。

简介

当配置LINFlexD的寄存器LINFlexD_UARTCR[UART]=1之后,LINFlexD变身为UART外设,可以支持常规的UART功能:

  • 全双工通信。
  • 除了最常用的 8-bit 数据帧,还支持 9-bit13-bit16-bit17-bit
  • 在校验位上支持偶校验、奇数校验、固定0电平、固定1电平。
  • 波特率可编程,支持过采样,实现高达4Mbps的通信。

原理与机制

同UART模式相关的寄存器

当配置LINFlexD的寄存器LINFlexD_UARTCR[UART]=1之后,LINFlexD变身为UART引擎,LINFlexD模块中,很多LIN引擎专属的寄存器,就不再起作用了,对应地,一些专属UART引擎的寄存器开始发挥作用。当然,还有一些寄存器,是LIN引擎和UART引擎共用的。实际上,当变身成UART引擎后,LINFlexD外设原本众多的寄存器,仅有少数会被用到,如图x所示。
在这里插入图片描述

图x LINFlexD的UART功能寄存器

其中,UART功能的配置寄存器LINFlexD_UARTCR中,设计了配置UART属性的绝大多数寄存器位,当不适用特殊功能(波特率的过采样、超时控制)的情况下,也仅需配置一小部分寄存器位,即可把UART功能用起来。如图x所示。
在这里插入图片描述

图x LINFlexD_UARTCR寄存器中的UART配置位

在寄存器LINFlexD_UARTSR中,能在UART模式下用到的状态标志位也比较简单,由于实际可用的缓冲区长度仅为1,所以实际能用的标志位也只有两个,分别对应发送缓冲区空和接收缓冲区满。如图x所示。

在这里插入图片描述

图x LINFlexD_UARTSR寄存器中状态标志位

另外,在寄存器LINFlexD_LINIER中,还可以通过寄存器位LINFlexD_LINIER[DTIE]LINFlexD_LINIER[DRIE]分别启用对应的中断触发开关。

计算UART波特率的方式同LIN引擎相同。LINFlexD虽然为UART引擎设计了数据缓冲区的FIFO模式,甚至DMA功能,如果用户对应用性能要求不高的情况下,稳妥起见,可使用数据缓冲区的Buffer模式,并配合中断或者轮询方式工作。详见下文有具体阐述。

还要特别注意的是,LINFlexD的“初始化模式”的安全机制仍在起作用,很多配置寄存器仍仅在初始化模式下才能配置,配置完毕后切回正常工作模式,之前的配置才正式生效。

时钟与波特率

在手册中IPC(IP Controller)章节里,表格Table 13.1: IP Clock Control Table 的备注中,有明确说明,LINFlexD的波特率时钟源来自于FAST_BUS_CLK。同LIN引擎计算波特率的方式相同,大体上是使用LINFlexD_LINIBRRLINFlexD_LINFBRR两个寄存器作为波特率时钟的分频器,最终算得UART通信过程中的波特率。

如果不使用可编程的过采样功能(即使用固定16位的过采样率),计算UART波特率的功能将非常简单。在绝大多数应用中,固定16位的过采样足够满足用户需求。此时为了获得波特率f_baudrate,可以配置:

  • LINFlexD_LINIBBR = (f_fast_bus_clk / f_baudrate ) / 16
  • LINFlexD_LINFBBR = (f_fast_bus_clk / f_baudrate) % 16

若要达到更高的波特率,或者在时钟源频率被降低后,仍要保持较高的波特率,就需要减少过采样点的数量,可以通过配置LINFlexD_UARTCR[ROSE]=1LINFlexD_UARTCR[OSR],来选择使用8次、6次、5次甚至4次过采样,并且可通过LINFlexD_UARTCR[CSP]指定采样点的位置。此时,计算波特率的公式就要引入过采样次数OSR,取代之前固定的16,另外,表示波特率分频因子分数部分的LINFlexD_LINFBBR寄存器也就不再生效了:

  • LINFlexD_LINIBBR = (f_fast_bus_clk / f_baudrate ) / OSR

还需要注意的是,在LIN模式下,可以基于LIN通信帧的同步段实现硬件自动同步波特率的功能,在UART模式下也是不生效的(硬件上没有测量的依据)。

数据缓冲区

LINFlexD为LIN通信设计了8个字节的数据帧缓冲区,刚好够LIN通信的应答数据包存放8字节的数据负载。在UART模式下,也复用了这8个字节的缓冲寄存器,作为UART通信的数据缓冲区。但是,在UART模式下使用这8个字节的数据缓冲区,有一些需要特别注意的地方。

阅读手册可知,使用LINFlexD_DATA[]缓冲区有两种模式,字面上称为FIFOBuffer模式,可通过寄存器LINFlexD_UARTCR[TDFL_TFC]配置。当LINFlexD变身为UART后,这个8字节缓冲区就变成了两个4字节的缓冲区,分别对应发送缓冲区和接收缓冲区。如图x所示。

在这里插入图片描述

图x UART模式下的LINFlexD_DATA

值得注意的是,这里4字节的缓冲区,其实就是1个常规的32位寄存器,这样看起来,就同一般普通的UART数据寄存器没差别了。但这里还额外设计了一个LINFlexD_UARTCR[TDLF_TFC]字段,配置其中有效的数据长度(8字节、16字节或是32字节),这相当于指定了将发送数据寄存器从低位开始串行送上总线的时钟脉冲数量,或者说设定了当使用32位数据寄存器时,有效的数据段长度。

当配置为FIFO模式时,锁死了可配置的数据长度为1字节,然后由硬件利用这块存储空间实现了一个先入先出的机制,可以从DATA0这个入口一直“压弹”。这种固定数据入口地址的机制比较适合同DMA搭配使用,但如果是多字节的FIFO,还需要设计可产生DMA触发的阈值。但实际上,此时可以利用的LINFlexD_UARTCR[TDLF_TFC]字段,竟然变成了只读属性,而并不是配置触发阈值。这样算下来,届时能触发DMA的,只有缓冲区空这个事件了,并可约定每次触发连续搬运4个字节(直接将缓冲区填满)并要小心处理最后小于4个字节的部分(需要人为计算最后实际要搬运的数据量),或者不厌其烦地让DMA每次仅搬运一个数,相对于有FIFO数量阈值提前触发的方式,这样都有“断线”的风险。但对于小传输负载的应用,目前实现的简单的FIFO(相当于还是Buffer)已经足够应对了。

发送过程

仅当LINFlexD_UARTCR[TxEN]=1时,UART引擎才能发送数据。然后,通过向寄存器BRD0(DATA0)写数,触发传输过程。如果一次要传输多个字节,则需要先写寄存器BRD1-BRD3(需要提前配置好LINFlexD_UARTCR[TDLF_TFC],激活可以发送更多的数据位),最后写寄存器BRD0以启动传输。

发送缓冲区中所有的数据发送完毕后,发送数据缓冲区被清空,LINFlexD_UARTSR[DTF]标志位由硬件自动置位。

但需要注意是,再次向发送数据缓冲区中写数,并不能自动清零LINFlexD_UARTSR[DTF]标志位。在写新数之前,需要人工清发送完成标志位。如此看来,这个标志位并不是缓冲区的状态标志位,而是事件的标志位(类似于LIN通信帧的管理机制)。

在手册中有限的描述中,也未细分数据从缓冲区送至发送数据的串行移位器之间的时序(通常人为发送缓冲区空的时候就可以向其中送入新数,而不必等移位器把数移到总线之后再启动新的写数过程),这可能会在实际传输过程中插入很多间隙,从而损失传输效率。

当发送缓冲区为FIFO模式时,写数入口固定为BRD0寄存器,并且固定写数的长度为1字节。根据手册描述,此时,当FIFO被数据填满后,LINFlexD_UARTSR[DTF]表示发送缓冲区满???这个功能仅作为调试功能使用。如果是这样,笔者心中不免冒出一个疑问,当发送FIFO中的数据即将清空之际,用什么信号触发DMA搬运新数补充FIFO呢?

The LINFlexD uses a single transmit DMA channel (0) to move data from RAM to the UART transmit buffer. To enable DMA for UART transmit mode, both DMATXE[0] and input signal dma_enb_req_tx[0] must be asserted.

In response to assertion of ipd_req_tx[0], the DMA controller transfers up to 4 bytes or 2 halfwords from RAM to the UART transmit FIFO through successive writes to the DATA0~DATA3 registers.

In the cycle after the data phase of the last write for the transfer, the DMA controller must assert both dma_done_lw_tx[n] and dma_ipd_complete_tx[n] to acknowledge the DMA request.

FIFO配合轮询和中断模式,可用的触发事件和标志位略显单薄,FIFO模式在设计之初似乎就是给DMA使用的。

接收过程

接收过程同发送过程类似。仅当LINFlexD_UARTCR[RxEN]=1时,UART引擎才能监控总线上的信号,一旦检测到START信号就开始启动接收过程,向接收缓冲区中送数。当接收缓冲区中有数后,标志位LINFlexD_UARTSR[DRF_RFE]起来,软件要么用中断,要么用轮询,赶紧把接收缓冲区中的数读走,否则新数来了之后会触发缓冲区溢出错误的同时会丢数(根据LINFlexD_LINCR1[RBLM]配置确定覆盖旧数还是抛弃新数)。

接收缓冲区寄存器是从LINFlexD_DATA[4]开始的。另外,接收缓冲区同发送缓冲区一样,也有数据缓冲区长度的说法。发送过程的节奏是由MCU自己控制的,所以设置多少,只要符合自己需要,就都可以。但接收缓冲区的长度是不好确定的,其接收过程是由外部的发送方决定的。因此,建议的做法是,在约定使用8位数据格式的情况下,始终将接收缓冲区的有效长度设置为1字节(如果约定基本的通信单元是16位,也可以设置数据长度为2字节),就是收到一个单元的数据就直接触发接收事件。

将接收缓冲区中的数读走之后,硬件也不会自动清零标志位LINFlexD_UARTSR[DRF_RFE],也需要软件清零,这个要注意一下。

另外,关于FIFO模式和DMA,与发送过程相似,尚待笔者亲自验证。

软件

YTMicro-SDK中设计了linflexd_uart驱动,但并未提供专门的uart应用样例(轮询收发、中断收发、DMA收发),可通过hello_world工程了解 linflexd_uart驱动的用法。

参考文献

  • YTM32B1ME0x_RM.pdf

  • YTM32B1Mx_SDK_RTM_1.0.4.zip

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue之vue-cli搭建SPA项目

目录 ​编辑 前言 一、vue-cli简介 1. 什么是vue-cli 2. vue-cli的重要性 3. vue-cli的应用场景 二、Vue-cli搭建SPA项目 1. 构建前提(node.js安装完成) 2. 安装vue-cli 3. 使用脚手架vue-cli(2.X版)来构建项目 4. 分析创建spa项目的八个问题 …

Rust 学习笔记

Rust 学习笔记 Hello world 代码一 fn main() { // 在这里编写你的 Rust 代码 println!("Hello world!"); } 什么是Rust 语言? Rust是一门系统编写语言 ,专注于安全 ,尤其是并发安全,支持函数式和命令式等编程…

基于规则架构-架构案例2019(三十九)

电子商务 某电子商务公司为了更好地管理用户,提升企业销售业绩,拟开发一套用户管理系统。该系统的基本功能是根据用户的消费级别、消费历史、信用情况等指标将用户划分为不同的等级,并针对不同等级的用户提供相应的折扣方案。在需求分析与架…

计算机网络相关知识点(二)

TCP如何保证传输过程的可靠性? 校验和:发送方在发送数据之前计算校验和,接收方收到数据之后同样需要计算,如果不一致,那么代表传输有问题。 确认应答序,序列号:TCP进行传输时数据都进行了编号…

Vue2+ElementUI 静态首页案例

源码 <template><div class"app-container home"><el-row type"flex" justify"space-around" class"row-bg"><el-card class"box-card cardDiv1"><el-col :span"5"><div clas…

【设计模式】四、工厂模式

文章目录 概述工厂模式简单工厂模式&#xff1a;工厂方法模式抽象工厂模式小结 概述工厂模式 传统方式&#xff1a; 简单工厂模式&#xff1a; 简单工厂模式的设计方案: 定义一个可以实例化 Pizaa 对象的类&#xff0c;封装创建对象的代码。 存在的问题&#xff1a; 简单工厂…

肠道微生物可改善围手术期和术后康复效果

谷禾健康 手术&#xff0c;俗称开刀&#xff0c;是医生通过医疗器械对病人身体局部进行去除病变组织、修复损伤等治疗&#xff0c;来维持患者的健康&#xff0c;在治愈疾病方面具有明确的作用。 围手术期是指从手术决策到手术结束及术后恢复期的整个时间段。围手术期管理的目标…

unable to access xxxx: Failed to connect to xxxx

问题&#xff1a; 1、GitLab仓库加上双重验证后&#xff0c;设置GIt得 Manage Remotes时报错 unable to access xxxx: Failed to connect to xxxx SSL certificate problem:self signed certificate 解决 1、返回前面得操作步骤检查了一遍 没有问题 2、最后尝试一些方法解…

Level FHE 的高效实现 兼容 Level FHE 的高级算法

参考文献&#xff1a; [CS05] Choi Y, Swartzlander E E. Parallel prefix adder design with matrix representation[C]//17th IEEE Symposium on Computer Arithmetic (ARITH’05). IEEE, 2005: 90-98.[SV11] Smart N P, Vercauteren F. Fully homomorphic SIMD operations[…

vue点击pdf文件直接在浏览器中预览文件

好久没有更新文章了&#xff0c;说说为什么会有这篇文章呢&#xff0c;其实是应某个热线评论的要求出的&#xff0c;不过由于最近很长一段时间没打开csdn现在才看到&#xff0c;所以才会导致到现在才出。 先来看看封装完这个预览方法的使用&#xff0c;主打一个方便使用&#x…

结合Mockjs与Bus事件总线搭建首页导航和左侧菜单

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

Python:pyts库中的GramianAngularField

您想要使用pyts库中的GramianAngularField类&#xff0c;这是一个用于时间序列数据图像转换的工具。要使用这个类&#xff0c;首先确保您已经安装了pyts库。如果尚未安装&#xff0c;您可以使用以下命令来安装它&#xff1a; pip install pyts一旦安装完成&#xff0c;您可以通…

如何使用ArcGIS Pro将等高线转DEM

通常情况下&#xff0c;我们拿到的等高线数据一般都是CAD格式&#xff0c;如果要制作三维地形模型&#xff0c;使用栅格格式的DEM数据是更好的选择&#xff0c;这里就为大家介绍一下如何使用ArcGIS Pro将等高线转DEM&#xff0c;希望能对你有所帮助。 创建TIN 在工具箱中选择“…

C/C++大写字母的判断 2023年5月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C大写字母的判断 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 C/C大写字母的判断 2023年5月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 输入一个字符&#xff0c;判…

数组01-二分查找算法

目录 数组如何实现随机访问 两个关键词 数组的特点 根据下标随机访问数组元素 为什么数组要从0开始编号&#xff0c;而不是从1开始 LeetCode之路——704. 二分查找 Code 二分查找算法 数组如何实现随机访问 数组&#xff08;Array&#xff09;是一种线性表数据结构。它…

【计算机网络】IP协议(上)

文章目录 TCP与 IP之间的关系IP地址的认识协议报头格式1. 报头和有效载荷如何分离&#xff1f;2. 8位协议3. 4位版本4. 8位服务类型5. 16位总长度6. 8位生存时间 TTL 网段划分IP地址的划分 子网划分CIDR的提出如何理解CIDR TCP与 IP之间的关系 如&#xff1a;假设 你上高中时&…

OpenCV项目开发实战--主成分分析(PCA)的特征脸应用(附C++/Python实现源码)

什么是主成分分析? 这是理解这篇文章的先决条件。 图 1:使用蓝线和绿线显示 2D 数据的主要组成部分(红点)。 快速回顾一下,我们了解到第一个主成分是数据中最大方差的方向。第二主成分是空间中与第一主成分垂直(正交)的最大方差方向,依此类推。第一和第二主成分红点(2…

Crypto:一眼就解密

题目 根据题目给出的信息可知&#xff0c;flag的为base64编码&#xff0c;数字后面的可以知道为base64编码&#xff0c;解码可得

数据结构上机1

1、题目&#xff1a; 将1~10存入数组a[10]&#xff0c;并将其逆序输出 #define _CRT_SECURE_NO_WARNINGS 1 //(1) 将1~10存入数组a[10]&#xff0c;并将其逆序输出#include <stdio.h>int main() {int a[10];// 将1到10存入数组a[10]for (int i 0; i < 10; i){a[i] i…

蓝桥杯打卡Day15天

文章目录 买不到的数目错误票据 一、买不到的数目OJ链接 本题思路:引理&#xff1a;给定a&#xff0c;b&#xff0c;若dgcd(a,b)>1 ,则一定不能凑出最大数。结论&#xff1a;如果 a,b均是正整数且互质&#xff0c;那么由 axby,x≥0,y≥0 不能凑出的最大数是 ab−a−b。 证…