特性:
(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. ;
 

附件列表

【原创】USART异步模式配置的更多相关文章

  1. [原创]STM32 BOOT模式配置以及作用

    一.三种BOOT模式介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启 ...

  2. STM32学习笔记(五) USART异步串行口输入输出(轮询模式)

    学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在 ...

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

    我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表的文章,以一个更简单的视角,把异步模式讲清楚. 什 ...

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

    CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...

  5. Spring MVC的异步模式

    高性能的关键:Spring MVC的异步模式   我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表 ...

  6. JQuery日记6.5 Javascript异步模式(一)

    理解力JQuery前实现异步队列,有必要理解javascript异步模式. Javascript异步其实并不严重格异步感,js使某些片段异步方式在将来运行,流不必等待继续向下进行. 在多线程的语言中最 ...

  7. Javascript教程:js异步模式编程的4种解决方法

    随着人们对网站视觉效果及用户体验的要求越来越高,所以在未来网站的建设中,设计师们开始越来越多的使用了js文件来达到预期的效果,随着js文件的越来越多,令设计师们最头痛的事情也就来了,那就是Javasc ...

  8. Ansible系列(七):执行过程分析、异步模式和速度优化

    本文目录:1.1 ansible执行过程分析1.2 ansible并发和异步1.3 ansible的-t选项妙用1.4 优化ansible速度 1.4.1 设置ansible开启ssh长连接 1.4. ...

  9. Controller异步模式

    转载: https://blog.csdn.net/yingxiake/article/details/51193319 因为服务器请求处理线程的总数是有限的,如果类似的请求多了,所有的处理线程处于阻 ...

随机推荐

  1. MacBook上那些好用的工具们

    https://blog.csdn.net/qq_33833327/article/details/78454703

  2. css样式表的知识点总结

    css总的来说有三种css样式可供选择: 1,行内样式表 行内样式表,直接写在了html文件的元素中,例如: <div style="color:red;"></ ...

  3. 突破内网限制上网(ssh+polipo)

    最近到客户这里来做项目,发现客户对网络的把控实在严格,很多网站都不能访问到,搜索到的技术文档也屏蔽了.突然想到了FQ工具的原理,刚好自己也有台服务器在外头,部署个Polipo代理然后用ssh隧道连接. ...

  4. Python 虚拟环境 pyenv、venv(pyvenv)、virtualenv之间的区别

    请参考连接 https://blog.zengrong.net/post/2167.html https://blog.csdn.net/lanonjj/article/details/5105021 ...

  5. js监听全屏下的esc事件

    window.onresize = function() { if (!checkFull()) { //触发esc事件,执行业务逻辑. } }; function checkFull() { var ...

  6. SVN客户端操作

    版权声明:本文为博主原创文章,转载请注明原文出处. https://blog.csdn.net/zzfenglin/article/details/50937119   下面我们来了解一下SVN客户端 ...

  7. android-读取MediaProvider

    1.MediaProvider存储手机中的媒体文件,用 SQLite 数据库存储图片.视频.音频等多媒体文件的信息,供视频播放器.音乐播放器.图库使用.以 root 权限进入 adb shell,使用 ...

  8. OC字典的使用

    在OC中,字符串.数组.字典是最常见的对象类型,但是在这三个当中,字典的用法相对较少,因为字典的属性和方法比较少,但是一个字典的用法比较复杂,因为在一个字典当中,既可以包含字符串,也可以包含数组,数组 ...

  9. JObject,JArray的基本操作

    引用:https://www.cnblogs.com/dacongge/p/6957074.html 1.JObject:基本的json对象 /// <summary> /// Gets ...

  10. Redis-09.慢查询

    慢查询指的是redis命令的执行时间,不包括网络传输和排队时间. Redis配置文件redis.conf中描述慢查询相关的选项在SLOW LOG部分 ######################### ...