通信的基本概念

同步通信

一般情况下同步通信指的是通信双方根据同步信号进行通信的方式。比如通信双方有一个共同的时钟信号,大家根据时钟信号的变化进行通信,如SPI、I2C等。

     

异步通信

是指数据传输速度匹配依赖于通信双方有自己独立的系统时钟,大家约定好通信的速度。异步通信不需要同步信号,但是并不是说通信的过程不同步,例如UART。

串行通信

指的是同一时刻只能收或发一个bit位信息。因此只用1根信号线即可。优点:占用引脚资源少。缺点:传输速度相对较慢。

并行通信

指的是同一时刻可以收或发多个bit位的信息,因此需要多根信号线才行。优点:速度快。缺点:占用引脚资源多。

通信模式

单工:要么收,要么发,只能做接收设备或者发送设备。比如收音机
半双工:可以收,可以发,但是不能同时收发。比如对讲机
全双工:可以在同一时刻既接收,又发送。比如手机

常见通信方式总结如下表所示:

通信标准

引脚说明

通信方式

通信方向

UART

(通用异步收发器)

TXD:发送端

RXD:接收端

GND:公共地

异步通信

全双工

单总线

(1-wire)

DQ:发送/接收端

异步通信

半双工

SPI

SCK:同步时钟

MISO:主机输入,从机输出

MOSI:主机输出,从机输入

同步通信

全双工

I2C

SCL:同步时钟

SDA:数据输入/输出端

同步通信

半双工

USART基本概念

通用同步异步收发器(USART)灵活地与外部设备进行全双工数据通信,满足外部设备对工业标准NRZ异步串行数据格式的要求。USART通过小数波特率发生器提供了多种波特率。它支持同步单向通信和半双工单线通信;还支持LIN(局域互联网络),智能卡协议与IrDA(红外数据协会)SIR ENDEC规范,以及调制解调操作(CTS/RTS)。而且,它还支持多处理器通信。

USART持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此USART和一般单片机UART使用方式是一样的,都使用异步模式。

STM32F051串口

STM32F051芯片内置两个通用同步/异步收发器(USART1和USART2),通信速度可达6Mbit/s。其中USART1的发送和接收引脚分别为PA9、PA10,UART2的发送和接收引脚分别为PA14、PA15。

串口通信协议

UART串口通信协议有1个起始位、8-9位数据位、1位奇偶校验位(可选)及1-2位停止位。通信时低位先发送,一般情况下串口通信选择8N1,即8位数据位、无奇偶校验位、1位停止位。

波特率

在串行通信中,用“波特率”来描述数据的传输速率。所谓波特率,既每秒传送的二进制位数,其单位为bps(bits per second)。它是衡量串行数据速度快慢的重要指标。
国际上规定一个标准的波特率系列: 110、300、600、1200、1800、2400、4800、9600、115200、14.4Kbps、19.2Kbps、……
例如:115200bps、指每秒传送115200位。通信双方必须设置同样的同学速率才能正常通信。

USART寄存器及配置方法

控制寄存器(USART_CR1)

由于STM32F051的USART控制寄存器(USART_CR1)内容十分庞杂,所以这里仅介绍一些常用功能。

位12 M: 字长
        这个位决定串口字长。 由软件置1 和清零。
        0: 1 个起始位,8 位数据位
        1: 1 个起始位,9 个数据位
        这个位域只能在USART 未被使能的时候(UE=0)改写。

位 9 PS: 校验选择
        这个位选择在校验生成和检测功能被打开的时候(PCE=1)使用奇校验还是使用偶校验。 由软件置1 和清零。 校验方式会在当前字节结束后生效。
        0: 偶校验
        1: 奇校验
        这个位域只能在USART 未被使能的时候(UE=0)改写。

位 6 TCIE: 发送完毕中断使能
        由软件置1 和清零。
        0: 中断禁止
        1: 在USART_ISR 寄存器中的TC 位被置1 的时候会产生USART 中断

位 5 RXNEIE: 接收寄存器非空中断使能
        由软件置1 和清零。
        0: 中断禁止
        1: 在USART_ISR 寄存器中的ORE 或者RXNE 被置1 的时候会产生USART 中断。

位 0 UE: USART 使能
        当这个位被清零,USART 的预分频器和输出都立即停止,并且当前的操作也被取消。对USART 的设置都不会丢,但USART_ISR 中所有的状态标志都会被复位。由软件置1 和清零。
        0: USART 预分频器和输出关闭,低功耗模式
        1: USART 开启

控制寄存器(USART_CR2)

位 13:12 STOP[1:0]: 停止位
        这些位用来定制停止位的个数。
        00: 1 个停止位:
        01: 保留
        10: 2 个停止位:
        11: 1.5 个停止位
        这个位域只能在USART 未被使能的时候(UE=0)改写。

波特率寄存器(USART_BRR)

位31:16 保留,必须保持复位时的值。
位 15:4 DIV_Mantissa[11:0]: USARTDIV 的整数部分
        这12 位定义USART 分频器除法因子的整数部分
位 3:0 DIV_Fraction[3:0]: USARTDIV 的小数部分
        这4 位定义USART 分频器除法因子的小数部分,当OVER8=1时,DIV_Fraction3 位是没有用的,并且必须保持为0。

中断和状态寄存器(USART_ISR)

位 7 TXE: 发送数据寄存器空
        当USART_TDR 寄存器中的值被取到移位寄存器的同时,这个位被硬件置1。 再向USART_TDR 寄存器写数据就会同时清掉这个位。TXE 标志还可以用其它方式清除,例如向USART_RQR 寄存器的TXFRQ 位写1,为了丢弃数据(仅于智能卡模式T=0,传送失败的情形)。如果USART_CR1 寄存器中的TXEIE 位被置起时,则会产生中断。
        0: 没有数据被传到移位寄存器
        1: 有数据被传到移位寄存器,发送数据寄存器为空。

位 5 RXNE: 接收数据寄存器非空
        当接收移位寄存器的内容被传递到USART_RDR 寄存器中时,这个位被硬件置1。读取USART_TDR 寄存器的数据就会同时清掉这个位。 RXNE 标志也可以通过对USART_RQR 寄存器中的RXFRQ 位写1 来清除。如果USART_CR1 寄存器中的RXNEIE 位是1,就会产生中断请求。
        0: 没收到数据
        1: 收到的数据已经可读。

数据发送寄存器(USART_TDR)

位31:9 保留,必须保持复位时的值。
位 8:0 TDR[8:0]: 发送数据的值
        用于写入要发送的数据字节。TDR 寄存器提供发送移位寄存器和内部总线间的并行接口(见图226)。当发送的时候设置了校验功能(USART_CR1 中的PCE=1),向最高位(位7 还是
位8 取决于设置的字长)写入的信息是无效的,因为它总是要被校验位代替了之后再去发送的。
        注: 这个寄存器只能在TXE=1 的时候才能做写操作。

数据接收寄存器(USART_RDR)

位31:9 保留,必须保持复位时的值。
位 8:0 RDR[8:0]: 接收数据的值
        包含所收到的字节。
        RDR 寄存器提供输入移位寄存器和内部总线间的并行接口(见图226)。
        当接收数据时打开了校验位,读这个寄存器得到的最高位是校验位。

STM32实现串口数据的收发

直接操作寄存器进行数据收发

根据硬件原理图,在CubeMX上配置好串口UART1为异步模式,并将波特率设置为115200。

生成工程后,通过直接操作寄存器控制UART进行数据收发的代码如下:

void Uart_Putchar(uint8_t ch) // 接收1个字节的数据
{while(!(USART1->ISR&(1<<7))); // 等待TXE置位USART1->TDR = ch;
}
uint8_t Uart_Getchar(void) // 发送1个字节的数据
{while(!(USART1->ISR&(1<<5))); // 等待RXNE置位return USART1->RDR;
}

应用HAL库函数进行数据收发

在ST公司提供的HAL库代码中,已经集成了UART串口收发的库函数,我们可以直接调用相应的函数操作串口,代码如下:

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); // 串口发送数据
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); // 串口接收数据

其中huart是代表当前需要收发数据的串口的结构体指针,pData为即将接收/发送的数据首地址,Size为发送/接收的字节数,Timeout为最大阻塞时间(即阻塞Timeout毫秒后如果仍未响应则放弃本次操作,并继续执行后续代码)。代码示例如下:

uint8_t buf[32] = {0};
HAL_UART_Transmit(huart1, buf, sizeof(buf), 100); // 串口发送数据
HAL_UART_Receive(huart1, buf, sizeof(buf), 100); // 串口接收数据

应用C标准库的printf函数打印调试信息

printf函数调用的是c库中的fputc函数。因此我们如果重新写了fputc函数,就可以改变printf函数的功能,可以向串口打印输出。代码如下:

int fputc(int ch,FILE *f)
{while((USART1->ISR&(1<<7)) == 0);USART1->TDR=(uint8_t)ch;return ch;
} 

这样操作下来,就能通过printf函数向串口打印调试信息了。

注:本文仅由作者用于总结和记录学习ARM系列软件和Linux驱动开发的过程,未经允许请勿擅自转载,如有侵权请联系作者删除。

STM32-UART串口应用相关推荐

  1. STM32 UART串口驱动程序

    文章原始地址: http://feotech.com/?p=56 示例1.通过UART1进行数据发送 UART 1 的初始化 /** * @brief UART1 Initialise. * @par ...

  2. STM32 HAL库 UART 串口读写功能笔记

    https://www.cnblogs.com/Mysterious/p/4804188.html STM32L0 HAL库 UART 串口读写功能 串口发送功能: uint8_t TxData[10 ...

  3. stm32串口接收不定长数据_基于STM32之UART串口通信协议--接收

    一.前言 1.简介 回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作. 2.UART简介 嵌入式开发中,UART串口通信协议是我们 ...

  4. STM32从零到一,从标准库移植到HAL库,UART串口1以DMA模式收发不定长数据代码详解+常见问题 一文解析

    前言 本文的参考资料 感谢提供标准库版本的CSDN同学:这两篇文章至少是我看过的最详细的标准库配置DMA版本.而且代码实测稳定能用. STM32 | DMA配置和使用如此简单(超详细)_...| .. ...

  5. STM32的串口通信UART/TTL

    常用的串口pin STM32的串口是基础通信方式, 每个型号都带多组串口, 一般都使用默认的组, 可以参考芯片的datasheet, 去看pinout and pin definitions, stm ...

  6. STM32学习——UART串口通信学习

    1.UART简介 UART(Universal Asyvhronous Receiver Transmitter)统称为通用异步收发器,是一种通用的串行.异步通信总线,有两条数据线,可以实现全双工的发 ...

  7. javarxtx串口接收时数据会分成好几段_【STM32】串口通信基本原理(超基础、详细版)...

    STM32F1xx官方资料: <STM32中文参考手册V10>-第25章通用同步异步收发器(USART) 通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通 ...

  8. STM32cube HAL库 UART串口中断方式收发任意长度 调试笔记

    STM32Cube对于新项目的开发能节省不少时间,从繁琐芯片初始化中解脱出来 1.STM32 UART初始化部分,配置好工程,采用STM32cube生成代码,初始化即已经完成. 2.串口中断方式的发动 ...

  9. NXP(I.MX6uLL) UART串口通信原理————这个未复习

    参考:Linux NXP (I.MX6uLL) UART串口通信原理 作者:一只青木呀 发布时间: 2020-09-20 16:48:33 网址:https://blog.csdn.net/weixi ...

  10. STM32 —— STM32 的串口通信

    STM32 -- STM32 的串口通信 STM32的串口通信接口有两种,分别是:UART(通用异步收发器).USART(通用同步异步收发器).而对于大容量 STM32F10x 系列芯片,分别有 3 ...

最新文章

  1. java list_Java集合-List
  2. $(document).ready()和window.onload的区别
  3. Spring Cloud【Finchley】-05使用配置文件自定义Ribbon Client
  4. Linux usual cmd
  5. 【干货】Oracle数据库常用十一大操作指令
  6. Android 如何做一次内存泄漏大排查
  7. 【问题记录】RIDE-1.7.3.1控制台及日志中文乱码处理
  8. leetcode1576 (2022.1.5)
  9. VB讲课笔记01:VB6.0安装与启动
  10. 转:Java中子类是否可以继承父类的static变量和方法而呈现多态特性
  11. PHP 5.3.0以上推荐使用mysqlnd驱动
  12. Beyond Compare如何展开所有子文件夹
  13. Delphi中ListView和TreeView的Item中的内存泄露
  14. Web3.0中国峰会将于7月在成都召开
  15. ‍Mybatis源码我搞透了,面试来问吧!写了134个源码类,1.03万行代码!
  16. 各种计算机绘图的应用场合,cad制图员面试技巧
  17. 1235813找规律第100个数_中考数学专题 - -找规律总结题 -
  18. python 实现串口发送数据
  19. 什么是I3C总线?它和I2C和SMBus是什么关系?
  20. 公共场所提示语及常见英文名词

热门文章

  1. ERP服务器虚拟机,全球首发!Windows Server 2008虚拟机ERP压力测试
  2. 【安卓逆向】360加固-脱壳修复
  3. 云原生丨手把手教你使用zabbix监控postgresql数据库(超详细讲解)
  4. MySQL酒店管理系统课程设计_酒店管理系统的设计与实现(PHP,MySQL)(含录像)
  5. 我的idea偏好设置
  6. mysql内循环是什么人_mysql循环
  7. C语言程序设计——结构体 给定如下定义:struct date_rec { int day ; int month ; int year ; } ; struct date_rec current_
  8. Spring Boot 拦截器无效,不起作用
  9. C#调用matlab时的类型初始值设定项引发异常
  10. C语言高考试卷分析模板,试卷分析模板