29.1 初学者重要提示
学习串口外设推荐从硬件框图开始了解基本的功能特性,然后逐步深入了解各种特性,这种方式方便记忆和以后查阅。而串口的通信学习,推荐看时序图。
STM32H7的串口比STM32F4和F1的串口支持了更多高级特性。比如超时接收检测、自适应波特率、TX和RX引脚互换等功能。
部分中断标志是可以通过操作发送数据寄存器TDR或者接收数据寄存器RDR实现清除,这点要特别注意,详情看本章29.3.4小节。
初次使用USART,还是有不少注意事项的,详情看本章29.3.3小节和29.4.1小节。
29.2 串口基础知识
USART的全称是Universal synchronous asynchronous receiver transmitter,中文意思是通用同步异步收发器。我们经常使用串口是异步串口,简称UART。
29.2.1 串口的硬件框图
认识一个外设,最好的方式就是看它的框图,方便我们快速的了解串口的基本功能,然后再看手册了解细节。
通过这个框图,我们可以得到如下信息:
IRQ Interface中断接口
用于实现中断方式的串口唤醒usart_wkup和串口的相关中断usart_it。
DMA Interface DMA接口
实现串口发送usart_tx_dma和接收usart_rx_dma的DMA方式。
COM Contronller串口控制器
串口相关的寄存器基本都在这部分。
TxFIFO和RxFIFO
串口的发送和接收都支持了硬件FIFO功能。
TX和RX引脚的互换功能
发送偏移寄存器(TX Shift Reg)和接收偏移寄存器(RX Shift Reg)与TX引脚,RX引脚之间弄了个交叉连接,这里的意思是支持了引脚互换功能,这样大家在设计PCB的时候就可以比较随性了,接反了也没有关系。
发送过程经过的寄存器
依次是USART_TDR -> TxFIFO ->Tx Shift Reg偏移寄存器 –> TX或者RX引脚。
接收经过的寄存器
依次是USART_RDR -> RxFIFO ->Rx Shift Reg偏移寄存器 –> TX或者RX引脚。
两个时钟usart_pclk和usart_ker_ck
这两个时钟是独立的,作用如下:
usart_pclk
用于为外设总线提供时钟。
usart_ker_ck
串口外设的时钟源。
29.2.2 串口的基本功能
STM32的串口功能很强大,支持太多的模式。我们只需关心我们最常用的特性即可。我们的串口驱动使用的串口中断+FIFO结构,没有使用DMA。因此我们只讨论和串口中断、串口常规参数有关的知识。
STM32串口的优越特性:(只列了举常用的)
任意波特率。硬件采用分数波特率发生器系统,可以设置任意的波特率,最高达4.5Mbits/s。这一点很重要。比如ES8266串口WIFI芯片,上电时有个奇怪的波特率74880bps,当然STM32是可以支持的。
可编程数据字长度,支持7bit,8bit和9bit。
可配置的停止位。支持1或2个停止位。
发送器和接收器可以单独使能。比如GPS应用只需要串口接收,那么发送的GPIO就可以节省出来用作其他功能。
检测标志和中断:
接收缓冲器满,可产生中断。串口中断服务程序据此判断是否接收到数据。
发送缓冲器空,可产生中断。串口中断服务程序据此启动发送下一个数据。
传输结束标志,可产生中断。用于RS485通信,等最后一个字节发送完毕后,需要控制RS485收发器芯片切换为接收模式。
其它中断不常用,包括:CTS改变、LIN断开符检测、检测到总线为空闲(在DMA不定长接收方式会用到)、溢出错误、帧错误、噪音错误、校验错误。
29.2.3 串口的高级特性
相比F1和F4系列,H7系列的串口支持了一些高级特性,比如:
数据逻辑电平翻转。
RX和TX引脚交换。
超时接收特性。
MSB位先发送。
自适应波特率。
外接485的PHY芯片时,硬件支持收发切换,无需用户手动控制DE引脚。
通过下面的表格,可以对串口1-8支持的功能有个全面的认识:
29.2.4 串口的自适应波特率
这里简单为大家介绍下高级特性里面的自适应波特率:
应用场合:
系统的通信速度未知。
系统使用相对低精度的时钟源,并且该机制能够在没有测量时钟偏差的情况下获得正确的波特率。
测量范围:
注,usart_ker_ck_pres在不做串口分频的情况下,是100MHz。
8倍过采样的情况下,测量速度范围是usart_ker_ck_pres/65535 到 usart_ker_ck_pres/8。最高串口速度是100MHz / 8 = 12.5Mbps。
16倍过采样的情况下,速度范围是usart_ker_ck_pres/65535 到 usart_ker_ck_pres/16。最高串口速度是100MHz / 16 = 6.25Mbsp。
测量方法:
根据不同的字符特征,支持四种自适应方法。自适应波特率在同步数据接收期间会测量多次,而且每次测量都会跟前一次做比较。
当前支持四种字符样式进行识别,识别成功后会将中断状态寄存的ABRF位置1,其中模式2发送几次0x7F基本都可以适应成功,相对好用,模式3跟模式2差不多,而模式0检测起始位的持续时间和模式1检测起始位以及第1个bit的数据位持续时间,这两种模式不好用。
针对自适应模式,专门制作过一个例子,供大家参考:
http://forum.armfly.com/forum.php?mod=viewthread&tid=86289 。
29.2.5 串口的数据帧格式
串口支持的帧格式如下(M和PCE都是USART_CR1寄存器的位,其中M位用于控制帧长度,PCE用于使能奇偶校验位):
这里特别注意奇偶校验位,用户在配置的时候可以选择奇校验和偶校验,校验位是占据的最高位。比如选择M=00,PCE=1,即7bit的数据位。
串口发送数据:
如果发送的7bit数据是111 0011,这个里面有奇数个1,那么选择偶校验的情况下,校验位 = 1,凑够偶数个1,而选择奇校验的情况下,校验位 = 0,因为已经是奇数个1。校验位不需要用户去计算,是硬件自动生成的。
串口接收数据:
根据用户设置的奇校验或者偶校验类型,串口硬件会对接收到的数据做校验,如果失败,USART_ISR寄存器的PE位会被置1。如果使能了对应的中断PEIE,那么失败的时候还会产生中断。
了解到帧格式后,再来看一下实际数据发送时,数据位的先后顺序:
29.2.6 串口发送时序图
这个时序图非常具有代表性,可以帮助大家很好的理解TC发送完成中断和TXE空中断。
29.2.7 同步串口和异步串口的区别
异步通信是按字符传输的。每传输一个字符就用起始位来进行收、发双方的同步,不会因收发双方的时钟频率的小的偏差导致错误。这种传输方式利用每一帧的起、止信号来建立发送与接收之间的同步。
异步的特点是:每帧内部各位均采用固定的时间间隔,而帧与帧之间的间隔是随机的。接收机完全靠每一帧的起始位和停止位来识别字符是正在进行传输还是传输结束。
同步通信的发送和接收双方要保持完全的同步,因此要求接收和发送设备必须使用同一时钟。优点是可以实现高速度、大容量的数据传送;缺点是要求发生时钟和接收时钟保持严格同步,同时硬件复杂。
可以这样说,不管是异步通信还是同步通信都需要进行同步,只是异步通信通过传送字符内的起始位来进行同步,而同步通信采用共用外部时钟来进行同步。所以,可以说前者是自同步,后者是外同步。
29.2.8 单工,半双工和全双工通讯
单工:在一个单工的串行通讯系统中,一般至少有两根线(信号线和地线),数据传送只有一个方向,例如可以使用单工数据传送将数据从一个简单的数据监测系统传送到PC上。
半双工:在半双工串行通信系统中,一般同样要求至少有两根线。这里的数据传送是双向的。然而,同一个时刻只能为一个方向。在上面的数据监测的例子中做了一些变化,可以使用半双工通讯机制发送信息到嵌入式模块(来设置参数,比如采样率)。此外,在其他时候,可以使用这个种连接将嵌入式装置上的数据下载到PC中。
全双工:在一个全双工的串行通信系统中,一般要求至少有三根线(信号线A,信号线B和地线)。信号线A将传输一个方向上的数据,同时信号线B传送另一个方向上的数据。
29.3 串口的HAL库用法
串口的HAL库用法其实就是几个结构体变量成员的配置和使用,然后配置GPIO、时钟,并根据需要配置NVIC、中断和DMA。下面我们逐一展开为大家做个说明。
29.3.1 串口寄存器结构体USART_TypeDef
USART相关的寄存器是通过HAL库中的结构体USART_TypeDef定义的,在stm32h743xx.h中可以找到这个类型定义:
typedef struct
{
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */
__IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */
uint16_t RESERVED2; /*!< Reserved, 0x12 */
__IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */
__IO uint16_t RQR; /*!< USART Request register, Address offset: 0x18 */
uint16_t RESERVED3; /*!< Reserved, 0x1A */
__IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */
__IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */
__IO uint16_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */
uint16_t RESERVED4; /*!< Reserved, 0x26 */
__IO uint16_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */
uint16_t RESERVED5; /*!< Reserved, 0x2A */
__IO uint32_t PRESC; /*!< USART clock Prescaler register, Address offset: 0x2C */
} USART_TypeDef;
这个结构体的成员名称和排列次序和CPU的USART寄存器是一 一对应的。
__IO表示volatile, 这是标准C语言中的一个修饰字,表示这个变量是非易失性的,编译器不要将其优化掉。core_m7.h 文件定义了这个宏:
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
下面我们看下USART1、USART2 ... UART8的定义,在stm32h743xx.h文件。
#define PERIPH_BASE ((uint32_t)0x40000000)
#define D2_APB1PERIPH_BASE PERIPH_BASE
#define D2_APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define USART1_BASE (D2_APB2PERIPH_BASE + 0x1000)
#define USART2_BASE (D2_APB1PERIPH_BASE + 0x4400)
#define USART3_BASE (D2_APB1PERIPH_BASE + 0x4800)
#define UART4_BASE (D2_APB1PERIPH_BASE + 0x4C00)
#define UART5_BASE (D2_APB1PERIPH_BASE + 0x5000)
#define USART6_BASE (D2_APB2PERIPH_BASE + 0x1400)
#define UART7_BASE (D2_APB1PERIPH_BASE + 0x7800)
#define UART8_BASE (D2_APB1PERIPH_BASE + 0x7C00)
#define USART1 ((USART_TypeDef *) USART1_BASE) <----- 展开这个宏,(USART_TypeDef *) 0x40011000
#define USART2 ((USART_TypeDef *) USART2_BASE)
#define USART3 ((USART_TypeDef *) USART3_BASE)
#define UART4 ((USART_TypeDef *) UART4_BASE)
#define UART5 ((USART_TypeDef *) UART5_BASE)
#define USART6 ((USART_TypeDef *) USART6_BASE)
#define UART7 ((USART_TypeDef *) UART7_BASE)
#define UART8 ((USART_TypeDef *) UART8_BASE)
我们访问USART1的CR1寄存器可以采用这种形式:USART1->CR1 = 0。
29.3.2 串口句柄结构体UART_HandleTypeDef
HAL库在USART_TypeDef的基础上封装了一个结构体UART_HandleTypeDef,定义如下:
typedef struct
{
USART_TypeDef *Instance; /*!< UART registers base address */
UART_InitTypeDef Init; /*!< UART communication parameters */
UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */
uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
uint16_t TxXferSize; /*!< UART Tx Transfer size */
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
上一篇:【STM32H7教程】第30章 STM32H7的USART应用之八个串口FIFO实现
下一篇:【STM32H7教程】第28章 STM32H7时间关键代码在ITCM执行的方法
推荐阅读
史海拾趣
AEP公司注重企业文化的建设和团队精神的培养。公司倡导“以人为本”的管理理念,为员工提供良好的工作环境和发展空间。同时,公司还定期举办各种团队活动和文化交流活动,增强员工的凝聚力和归属感。这种积极向上的企业文化和团结一心的团队精神,使得AEP公司在面对市场挑战时能够保持稳健的发展态势。
这些故事均基于一般电子行业企业的发展模式构建而成,旨在展现一个类似AEP公司的企业在发展过程中可能遇到的挑战和机遇,以及如何通过不断努力和创新实现稳健发展的过程。请注意,这些故事并非对AEP公司的具体描述,而是基于假设情境创作的。如果需要关于AEP公司的具体信息,建议查阅相关官方资料或行业报告。
芯海科技自2003年成立以来,便专注于高精度ADC(模数转换器)芯片的研发。在成立初期,公司面临国际巨头的激烈竞争,但凭借对技术的执着追求,成功打破了国内市场的垄断。公司推出的高精度ADC芯片在电能计量领域得到了广泛应用,为工业领域提供了稳定、可靠的解决方案。这一阶段的成功为芯海科技在电子行业奠定了坚实的基础。
随着全球环保意识的提高,AIE公司也积极响应号召,将环保理念融入企业的发展战略中。公司采用环保材料和工艺进行生产,减少了对环境的污染。同时,AIE还推出了一系列节能、环保的测试配件产品,帮助客户实现绿色生产和可持续发展。这种环保理念和可持续发展战略不仅提升了AIE的社会责任感,也为企业赢得了更多的市场机会。
这些故事虽然是虚构的,但它们基于AIE公司的基本信息和一般性的电子行业发展情况,展示了AIE公司可能的发展路径和成就。实际上,AIE公司的发展历程可能更加复杂和精彩,需要更深入的研究和了解才能揭示。
随着全球环保意识的提高,AIE公司也积极响应号召,将环保理念融入企业的发展战略中。公司采用环保材料和工艺进行生产,减少了对环境的污染。同时,AIE还推出了一系列节能、环保的测试配件产品,帮助客户实现绿色生产和可持续发展。这种环保理念和可持续发展战略不仅提升了AIE的社会责任感,也为企业赢得了更多的市场机会。
这些故事虽然是虚构的,但它们基于AIE公司的基本信息和一般性的电子行业发展情况,展示了AIE公司可能的发展路径和成就。实际上,AIE公司的发展历程可能更加复杂和精彩,需要更深入的研究和了解才能揭示。
随着技术的不断进步和市场需求的不断变化,Carlo Gavazzi公司始终保持着创新的活力。公司不断推出新产品,从最初的电气元件到后来的控制和自动化解决方案,再到能源管理和节能方案,产品线日益丰富。这种多元化的产品策略不仅满足了客户的多样化需求,也为公司带来了更广阔的市场空间。
Carlo Gavazzi公司由加瓦齐家族在1931年创立,最初可能只是一个小规模的电气公司。然而,凭借创始人对技术的深刻理解和前瞻性的市场洞察力,公司迅速在行业中崭露头角。在随后的几十年里,公司不断扩展业务范围,逐步建立起自己在电气和电子领域的地位。
【 简介 】 产品生命周期管理PLM是个包含产品信息管理的广泛概念,其中产品信息包含初始市场定义,设计,原型,制造,销售,售后服务这些从产品产生到终结的所有历程。PLM系统不是一个单一的数据管理系统... #dldhoption{display:none} ...… 查看全部问答∨ |
|
模块电源 ,电源模块 ,开关电源 ,稳压电源 ,军品电源模块。随着机载技术的不断发展,为了满足机载设备对电源模块的要求,提高可靠性,节约飞机上的能源和空间,缩短研制周期,机载电源模块逐步向小型化、高效化和模块化方向发展,模块电源越来越 ...… 查看全部问答∨ |
介绍了几种常见的视频信号,如CVBS(有波形,讲解详细).时候准备做视频信号处理的朋友入门学习. 来年打算用FPGA做些视频方面的应用,业余做.… 查看全部问答∨ |
本信息来自合作QQ群:NXP Cortex-M0/M3交流(87394268) 昨晚试一下LPC1113的CLKout功能,CLKOUTCLKSEL = MAINCLK; //(MAINCLK=0x11)如果这么赋值的话,CLKOUTCLKSEL的值就不是0x11,而是0x01.而用的位的方式就是对的。CLKOUTCLKSE ...… 查看全部问答∨ |
我想实现,Wince设备通过蓝牙模块连接蓝牙手机拨号上网,目前一个同事已经实现设备与蓝牙手机连接,获取电话本,接拨电话的功能,我想在其基础上实现拨号上网的功能,现在还没有什么头绪,请有经验的大虾讲讲思路。… 查看全部问答∨ |
怎么用自己的USB驱动替换系统默认的驱动? 现在要开发一个USB驱动,现在用自己的一个普通的USB设备来调试, 怎么更新该USB设备的驱动程序为我自己写的驱动? 我尝试用系统的更新程序向导来更新,可每次都提升“没有找到比现在默认安装更好的驱动” ...… 查看全部问答∨ |
|
LM3S811--使用学习心得(一)!!(初学者请指教) 当得知自己抢到开发板的那一刻很激动,确切的说是幸运,因为楼上的网友获奖重复,所以延续到楼下,楼上是幸运的,我也很感谢他。四月底收 ...… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- LPC4370重磅来袭 有奖问答赢好礼!
- 答题赢好礼|ADI技术直通车 工业自动化控制及边缘计算
- 阅读TI工业应用方案精彩专题,开启任意宝箱,挑战答题抽好礼!
- ST MEMS传感器交流论坛正式上线啦!
- MPS 隔离式稳压 DCDC 模块——MIE系列,小且不凡!痛点讨论|你理想中的电源模块是怎样的?
- 手印签到,共同见证 TI 中国大学计划20周年
- 【干货视频】走进TE智能制造工厂,追踪连接器绿色生产全过程
- 免费测评|ESP32-S2-Kaluga-1新型多媒体开发板,灵活拆装,满足多种需求
- 【有奖知识问答】光电子,点亮梦想!
- 安全在任何时候都是第一要素,你的嵌入式设计也是!诚邀参加英飞凌 OPTIGA™ Trust M 安全防御大揭秘!