USART异步模式配置

特性:

(1)USART只能一位一位地发送和接受数据,在起始位期间,TX端处于低电平;当闲置时,TX端为高。

(2)发送和接受由一共用的波特率发生器驱动,当发送器和接收器的使能位分别置位时,分别为其产生时钟。

(3)发送器根据M位的状态发送8位或9位的数据字。当发送使能位TE被置位时,发送移位寄存器中的数据从TX上输出,如果需要用到时钟,相应的时钟脉冲将在SCLK脚上输出。

(4)一帧数据结构:

起始位

■8位或9位的数据字

■可选的奇偶校验位

■停止位

对于上面这张图,从下至上,我们看到串口外设主要由三个部分组成,分别是波特率控制、收发控制和数据存储转移。

波特率控制

和USART_BRR寄存器相关,上一篇文章《STM32下波特率计算详解》中已经详细地讲解过了,这里不再赘述。在实际的库函数操作,只需要将实际的波特率大小赋予一个结构体变量中的一个波特率成员即可。

收发控制

围绕着发送器和接收器控制部分,有好多个寄存器 : CR1 、 CR2、 CR3 和 SR,即USART 的三个控制寄存器( Control Register)及一个状态寄存器( Status Register)。通过向寄存器写入 各种控制参数来控制发送和接收,如奇偶校验位、停止位等,还包括对USART 中断的控制 ;串口的状态在任何时候都可以从状态寄存器中查询得到。

(1)数据发送过程

当使能了发送使能位TE后,数据要发送出去,首先要将数据写进USART_DR寄存器(和51单片机SBUF一样,USART_DR寄存器实际包含了两个寄存器,给发送用的TDR和给接收用的RDR,在USART_DR寄存器下还有一个发送/接收移位寄存器,数据的发送接收最后都要通过移位寄存器),如果此时USART正在发送数据,写入的数据先保存在TDR寄存器中,传输完成后再把该数据复制进移位寄存器。如果此时USART没有在发送数据,对USART_DR寄存器的写操作,数据直接存放进移位寄存器。无论哪种方式,数据存进移位寄存器后,便开始发送,TXE被置位,当一帧数据发送完(停止位发送后),TC位被置位,并且如果USART_CR1的TCIE位被置位,将产生中断。数据的发送是从低位发送起。

(2)数据的接收过程

当USART_CR1的RE位被使能后,且接收器的RX端由高电平被拉为低电平,那么接收开始。数据的最低有效位首先从RX脚移进移位寄存器。

■当RXNE(接收数据寄存器非空标志位)被置位,表明移位寄存器的内容被转移到RDR,此时数据已经被接收并且可以被读出,USART_DR和相关的错误标志位。

■如果RENEIE位被置位,将产生中断,如果在接收期间,检测到侦错误、噪音、溢出错误,错误标志位将被置位。

■在多缓冲器通信时, RXNE在每个字节接收后被置起,并由DMA对数据寄存器的读操作而清零。

■在单缓冲器模式里,由软件读USART_DR寄存器完成对RXNE位清除。 RXNE标志也可以通过对它写0来清除。 RXNE位必须在下一字符接收结束前被清零,以避免溢出错误。

注:

TEX和RXNE是针对USART_DR寄存器的,而USART_DR实质上由两个寄存器组成TDR和RDR,当发送时,数据从TDR传输到移位寄存器,TXE被置位,表示TDR已为空,当接收数据时,数据从移位寄存器转移到RDR时,RXNE被置位,表示RDR非空;E有Empty的意思。

(3)什么是溢出错误

我们知道。接收数据时,数据从移位寄存器转移到RDR,RXNE被置位,表示数据已被接收可以读出了。清除RXNE标志位的方法是读取USART_DR寄存器自动清零或对RXNE写0手动清零。当RXNE仍然置位,又接收到数据,新数据将暂存入移位寄存器,此时产生溢出错误,RXNE位仍为置位,数据只有在RXNE清零后,才能从移位寄存器转移到RDR。

● ORE位被置位。

● RDR内容将不会丢失。读USART_DR寄存器仍能得到先前的数据。

● 移位寄存器中以前的内容将被覆盖。随后接收到的数据都将丢失。

● 如果RXNEIE位被设置或EIE和DMAR位都被设置,中断产生。

● 顺序执行对USART_SR和USART_DR寄存器的读操作,可复位ORE位

注意: 当ORE位置位时,表明至少有1个数据已经丢失。有两种可能性:

● 如果RXNE=1 ,上一个有效数据还在接收寄存器RDR上,可以被读出。

● 如果RXNE=0,这意味着上一个有效数据已经被读走, RDR已经没有东西可读。当上一个效数据在RDR中被读取的同时又接收到新的(也就是丢失的)

数据时,此种情况可能发生。在读序列期间(在USART_SR寄存器读访问和USART_DR读访问之间)接收到新的数据,此种情况也可能发生。

(4)什么是侦错误

在预期的时间里,没有接收到停止位,可能的原因:

●大量噪音存在

●没有同步上

当帧错误被检测到时:

● FE位被硬件置起

● 无效数据从移位寄存器传送到USART_DR寄存器。

● 在单字节通信时,没有中断产生。然而,这个位和RXNE位同时置起,后者将产生中断。在多缓冲器通信情况下,如果USART_CR3寄存器中EIE位被置位的

话,将产生中断。顺序执行对USART_SR和USART_DR寄存器的读操作,可复位FE位。

(5)几个重要的中断标志(USART_SR)

●TXE:当TXE为1时,表示发送数据寄存器为空;当为0时,表示发送数据寄存器不为空。

●RXNE:当RXNE为1,表示接收数据寄存器为非空,可以读取接收到的数据了(存于USART_DR中);当为0时,表示接收寄存器为空,此时移位寄存器接收到新数据,会立即传输到数据寄存器中。

●TC:当发送完成,即数据已经从移位寄存器发送出去后,TC将置位。

●ORE:检测到数据溢出

●PE:检测到奇偶检验错误

○CTS:当nCTS输入变化状态时,该位被硬件置位,由软件清零

○LBD:LIN断开检测标志,当检测到LIN断开时,该位由硬件置位,由软件清0

○IDLE:当检测到空闲总线时,该位由硬件置位,清零时先读USART_SR,再读USART_DR

○NE:噪声错误标志,在接收到的帧检测到噪音时,由硬件对该位置位。由软件序列对其清玲(先读USART_SR,再读USART_DR)。

○FE:帧错误,当检测到同步错位,过多的噪声或者检测到break符,该位被硬件置位。由软件序列将其清零(先读USART_SR,再读USART_DR)。

0:没有检测到帧错误;

1 :检测到帧错误或者break符。

注意:该位不会产生中断,因为它和RXNE一起出现,后者自己会在RXNE标志置位时产生中断。如果当前传输的数据既产生了帧错误,又产生了过载错误,还是会继续该数据的传输,并且只有ORE位会被置位。如果EIE位被置位,在多缓冲区通信模式下,随着FE标志被置位,中断产生。

这些中断都被连接到同一个中断向量,在中断函数中,要用USART_SR中相应标志位是否置位,来区分中断来源。

数据存储转移    

收发控制器根据我们的寄存器配置,对数据存储转移部分的移位寄存器进行控制。当我们需要发送数据时,内核或 DMA 外设(一种数据传输方式,在后面介绍)把数据从内存(变量)写入到发送数据寄存器 TDR 后,发送控制器将适时地自动把数据从 TDR 加载到发送移位寄存器,然后通过串口线 Tx,把数据一位一位地发送出去,当数据从 TDR转移到移位寄存器时,会产生发送寄存器 TDR 已空事件 TXE,当数据从移位寄存器全部发送出去时,会产生数据发送完成事件 TC,这些事件以在状态寄存器中查询到。而接收数据则是一个逆过程,数据从串口线 Rx 一位一位地输入到接收移位寄存器,然后自动地转移到接收数据寄存器 RDR,最后用内核指令或 DMA 读取到内存(变量)中。

GPIO初始化

(1)USART引脚IO口位置及重映像问题

(2)USART引脚IO口的模式问题

所以如果使用的是USART 1,且没有重映射,那么GPIO口的配置是:

  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA,ENABLE);
  2. //初始化USART 1的TX和RX引脚
  3. GPIO_InitTypeDef GPIO_Struct;
  4. GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
  5. //USART TX引脚使用复用推挽输出
  6. GPIO_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
  7. GPIO_Struct.GPIO_Pin = GPIO_Pin_9;
  8. GPIO_Init(GPIOA,&GPIO_Struct);
  9. //USART RX引脚使用浮空输入
  10. GPIO_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  11. GPIO_Struct.GPIO_Pin = GPIO_Pin_10;
  12. GPIO_Init(GPIOA,&GPIO_Struct);
  1. //GPIO、usart配置
  2. void USART_GPIO_conf(void)
  3. {
  4. GPIO_InitTypeDef GPIO_Struct;
  5. USART_InitTypeDef USART_Struct;
  6. //设置之前一定要开启相应的外设时钟
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
  8. //初始化USART 1的TX和RX引脚
  9. GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
  10. //USART TX引脚使用复用推挽输出
  11. GPIO_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
  12. GPIO_Struct.GPIO_Pin = GPIO_Pin_9;
  13. GPIO_Init(GPIOA,&GPIO_Struct);
  14. //USART RX引脚使用浮空输入
  15. GPIO_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  16. GPIO_Struct.GPIO_Pin = GPIO_Pin_10;
  17. GPIO_Init(GPIOA,&GPIO_Struct);
  18. //设置USART的波特率为9600,接收发送使能,无奇偶校验,1位停止位,8位数据位,无硬件流控
  19. USART_Struct.USART_BaudRate = 9600;
  20. USART_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  21. USART_Struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  22. USART_Struct.USART_Parity = USART_Parity_No;
  23. USART_Struct.USART_StopBits = USART_StopBits_1;
  24. USART_Struct.USART_WordLength = USART_WordLength_8b;
  25. USART_Init(USART1,&USART_Struct);
  26. USART_Cmd(USART1, ENABLE);
  27. }

接收和发送数据库函数

检测已收到数据代码

  1. while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
  2. ;
  3. printf("已接受到\n");
  4. USART_ClearFlag(USART1,USART_FLAG_RXNE);
  1. /* 发送一个字节数据到USART1 */
  2. USART_SendData(USART1, (uint8_t) ch);
  3. /* 等待发送完毕 */
  4. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  5. ;

来自为知笔记(Wiz)

附件列表

时间: 2024-10-13 22:48:57

USART异步模式配置的相关文章

Creo二次开发异步模式配置

异步模式是Creo二次开发的另外一种形式,被广泛应用于一些外部调用中.其配置过程如下: (1)      创建MFC程序(对话框程序都可以了) (2)      配置工程常规选项 (3)      配置VC目录 (4)      配置附加依赖项 (5)      配置系统变量 通过以上配置可以实现对Creo二次开发异步模式的框架的搭建. 版权声明:本文为博主原创文章,未经博主允许不得转载.

5.USART异步串行口输入输出(轮询模式)

学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在外设中属于比较简单的通讯模式,但是在大型项目调试中又十分重要,理解该外设模块对于以后的通讯协议学习以及软件调试都有重要意义. 通讯协议是指双方实体完成通信或服务所必须遵循的规则和约定,对于串口来说,包含波特率,数据位长度,停止位和数据校验位,当stm32芯片和客户端具有相同的协议约定时即能够正确的接

Spring MVC的异步模式

高性能的关键:Spring MVC的异步模式 我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表的文章,以一个更简单的视角,把异步模式讲清楚. 什么是异步模式 要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式: (图1) 浏览器发起请求,Web服务器开一个线程处理,处理完把处理结果返回浏览器.好像没什么好说的了,绝大多数Web服务器都如此般处理.现在想想如果处理的过程中需要调用

Spring MVC的异步模式DefferedResult

原文:http://www.importnew.com/21051.html 什么是异步模式 要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式: (图1) 浏览器发起请求,Web服务器开一个线程处理,处理完把处理结果返回浏览器.好像没什么好说的了,绝大多数Web服务器都如此般处理.现在想想如果处理的过程中需要调用后端的一个业务逻辑服务器,会是怎样呢? (图2) 调就调吧,上图所示,请求处理线程会在Call了之后等待Return,自身处于阻塞状态.这也是绝大多数Web服务器的做

高性能的关键:Spring MVC的异步模式

我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表的文章,以一个更简单的视角,把异步模式讲清楚. 什么是异步模式 要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式: (图1) 浏览器发起请求,Web服务器开一个线程处理,处理完把处理结果返回浏览器.好像没什么好说的了,绝大多数Web服务器都如此般处理.现在想想如果处理的过程中需要调用后端的一个业务逻辑服务器,会是怎样呢? (图2

CDC不同模式在ODI体现系列之二 异步模式

CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. 已经卸载数据库. ORACLE 例程已经关闭. SQL> startup mount ORACLE 例程已经启动. Total System Global Area  599785472 bytes Fixed Size                  1288820 bytes Variable S

Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结

同步和异步:与消息的通知机制有关. 本质区别 现实例子 同步模式 由处理消息者自己去等待消息是否被触发 我去银行办理业务,选择排队等,排到头了就办理. 异步模式 由触发机制来通知处理消息者 我去银行办理业务,取一个小纸条上面有我的号码,等到排到我这一号时由柜台的人通知我轮到我去办理业务. 阻塞与非阻塞:与线程等待消息(无所谓同步或者异步)时的状态有关. 本质区别 现实例子 阻塞调用 线程挂起,不能做其他事. 上面的那个例子,不论是排队还是使用号码等待通知,如果在这个等待的过程中,等待者除了等待消

实现基于Task的异步模式

返回该系列目录<基于Task的异步模式--全面介绍> 生成方法 编译器生成 在.NET Framework 4.5中,C#编译器实现了TAP.任何标有async关键字的方法都是异步方法,编译器会使用TAP执行必要的转换从而异步地实现方法.这样的方法应该返回Task或者Task<TResult>类型.在后者的案例中,方法体应该返回一个TResult,且编译器将确保通过返回的Task<TResult>是可利用的.相似地,方法体内未经处理的异常会被封送到输出的task,造成返

MSDN搬运 之 [基于事件的异步模式]

基于事件的异步模式概述 那些同时执行多项任务.但仍能响应用户交互的应用程序通常需要实施一种使用多线程的设计方案.System.Threading 命名空间提供了创建高性能多线程应用程序所必需的所有工具,但要想有效地使用这些工具,需要有丰富的使用多线程软件工程的经验.对于相对简单的多线程应用程序,BackgroundWorker 组件提供了一个简单的解决方案.对于更复杂的异步应用程序,请考虑实现一个符合基于事件的异步模式的类. 基于事件的异步模式具有多线程应用程序的优点,同时隐匿了多线程设计中固有