前言
之前一直用hal库直接用的串口通信,所以以前也是学过的,但是当时才大一,看了原理也没有太理解,只是会用了,最近又重新复习了一遍,搞清楚原理,学习后,对学到的东西的一些总结。
USART介绍
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
主要特性
通信模式
任何USART通信,需要用到2个对外连接引脚,RxD(输入引脚,用于串行数据接收)、TxD(输出引脚,用于串行数据发送) SCLK:发送器时钟输出(同步时才用到) GND:共地
通信过程
通信协议
理解USART框图
框图是在参考手册里面的,需要的同学可以去看一下。
输入模式
输入模式的路线如上图所示 1:Rx接收到数据先进入码解码模块, 2:然后沿着线1,进入移位寄存器中,然后再发给接收数据寄存器(RDR),读操作就可以读RDR的值了, 3:目光回到接收移位寄存器,还有一条线连过去,就是4这条线,这条线连着 接收器控制 这个模块,这个模块就是控制这个接收移位寄存器的 4:再看5这条线,是接收器的时钟,连着时钟的发生器,我们要改变时钟的话,就是要改变这里 5:看回 接收器控制 模块,还有很多个寄存器箭头指向它,其实表示这些寄存器控制它,而我们到时要操作的也是这些寄存器,比如CR1 那些。 接收端就是这样了
输出模式
输出模式可以看到,与输入模式类似 到最后也是寄存器控制 发送器控制 模块,进行数据的输出。
寄存器
刚刚说了是寄存器控制 发送器/接收器控制模块 ,去控制输入输出,那要怎么控制的,这个我们要看参考手册了。 框图显示寄存器的控制 我们可以去参考手册看一下寄存器怎么用 以CR1为例 参考手册上已经把每一位讲的和清楚了,我就不过多阐述了。
有的同学会问,知道这些,还是一脸懵逼,不知道怎么设置啊?所以下一步我要告诉你们串口通信的步骤了。
串口通信步骤
发送过程
这个就是数据的发送过程,刚刚我们讲过通信协议的格式,我们这些步骤也是配置成协议的格式,如果不理解的话,大家只需要记住就行。按照这个步骤,我们就可以对寄存器进行操作了 比如 1:是在USART_CR1上置位UE激活USART 那我们就找到CR1控制寄存器,看到是第13位,我们就配置他的第13位 2:定义字长 我们同样找它,然后配置字长
3:设置停止位 找到CR2 ,看到这个停止位,我们就可以设置了。 这就是寄存器操作的过程
接收过程
接收过程也是类似发送过程,我们按照步骤,对相应的寄存器进行配置就行。
发送 寄存器版本代码
这样,我们就可以写出寄存器操作的代码了(上图的代码还没有配置波特率,是不能运行的,但是基础配置已经配置好了),我们对USART进行操作,安装步骤 1:先是找到CR1,激活UE, 可以看到UE是第13位,使能是置1,所以代码是 USART->CR1 | = (1<<13)就是,这个语句就可以把第13位置1,而不影响其他位。 2:定义位长 是第12位,我们设置位长是8,所以 USART->CR1 & =~ (1<<12) 第12位置0 3:编写停止位个数 改CR2 设成1.5位 所以是 代码里面是3<<12 4:DR寄存器同理,是我们要发的数据 上面是这个过程了,刚刚我们也讲到,波特率还没配置,所以我们要配置波特率。
波特率
这是波特率的计算,文档里面 也讲得很清楚了 比如我们要配置9600的波特率 我们可以这样计算 M=468(整数) F=0.75*16=12(如果不是整数,取最近的) 我们可以算出USART-BRR里面的值了
完整代码
因为涉及到时钟,所以必须有RCC_Configuration();因为涉及引脚的使用和复用,也要用到GPIO_Configuration();图中的BRR可以直接手算完直接等于,也可以按照图里一样,让程序来算。
注意RCC里面的AFIO时钟和USART1的时钟要打开 ok寄存器版本就完成了
库函数版本与HAL库
其实库函数版本同理,只是从对寄存器直接配置,多了一个库函数层 更加方便,HAL库也是同理,而且HAL只需在CUBEMX配置一下就行,很方便。
库函数 我们再固件库可以看到USART的函数有很多 可以自己去看 库函数配置USART1有一个这样的例子 直接复制到工程里面,按照需求修改,其实底层逻辑就是寄存器版本里面的逻辑,库函数的存在方便移植代码,使开发更高效了。 然后开启使能,就能用了。
一般正点原子,或者野火他们都会把这个封装起来。 直接使用这个USART_Configuration()函数就行, 你自己也可以改一下,比如这个多加了个波特率的形参,使用的时候可以自己设置波特率,更加灵活了
总结
好了,关于USART的学习总结就这么多了,我是怀着学习需要输入输出的心态来写这篇文章的,我输出这篇文章也是为了让我更好理解,希望对大家也有所帮助。
|