文章目录

  • 串行通讯
    • 串行和并行比较
    • 数据帧
    • 波特率
  • USART模块原理图及主要寄存器
    • USART框图介绍
    • 主要寄存器
      • 状态寄存器
      • 数据寄存器
      • 控制寄存器
  • USART发送实现
  • USART接收实现
  • 总结

串口这个功能应该是很常用、基础的一个功能,无论是电脑与设备还是设备与设备之间都可以采用串口进行传输数据。在前段时间调试单片机与Dwin串口屏通信的过程中,对于接收走了很多的弯路,后来准备系统地学习下单片机的串口收发,写成一篇博客,供以后参考。

串行通讯

串行和并行比较

在数据传送过程中,分为串行和并行通信,其中并行通讯就是将数据的每一位一起发送,达到并行的效果,但是这种并行通信在面对位数比较大的数据时,需要大量的线缆连接,非常的不实用。这时就出来了串行通讯,就是将数据按照一定的规则排好队,一位一位的在数据线上进行传输。这种方式虽然相比于并行通讯效率会有一定的降低,但是需要的线缆数据量大大减少,普通的全双工串行通信只需要2根即可。

数据帧

串行通讯为了达到更好的传送效率,规定了数据帧的格式,发送端发送的数据和接收端接收的数据帧格式相同,目前常用的数据帧格式为1位停止位,8位数据位,无奇偶校验。

波特率

波特率就是设备每秒传送数据的位数,常用的数值为9600 115200.如果发送和接收端的波特率不一致,就会出现乱码的情况,或者没有数据,在出现乱码时要及时检查波特率是否一致。

USART模块原理图及主要寄存器

USART框图介绍

对于32位的单片机比51单片机功能复杂,下图为《STM32中文参考手册》中提供的串口结构框图。
在左侧部分是串口提供的一些引脚,需要关注的是TX、RX引脚,其他的引脚一般不会用到。对于结构图的理解为:从下向上走,首先是波特率发生器,波特率发生器就是为发送数据和接收数据提供必要的时钟,其在程序中对波特率寄存器进行设置以改变波特率的值。波特率提供的时钟经过16分频到达发送控制和接收控制器。发送和接收控制器通过时钟和一些相关的控制寄存器去控制发送移位寄存器和接收移位寄存器,如图中紫色线所示。发送移位寄存器根据发送控制器的信号将数据寄存器的数据通过TX口发送出去,接收移位寄存器通过接收控制器的控制,将RX口的数据存入到数据寄存器。以此来完成发送和接收。在发送和接收过程中,还有与之相关的控制器和标志寄存器。

主要寄存器

状态寄存器

  • TXE:发送数据寄存器为空;0:发送缓冲区有数据 1:发送缓冲区没有数据;根以根据判断这一位是1还是0来知道上一帧的数据有没有发送完成,一般在发送下一帧数据时,要等待前面的数据帧发送完成,也就是这一位为1.
  • TC:发送完成;0:发送没有完成,1:发送完成;这一位就是判断这个数据包什么时候发送完成,如果发送缓冲区为空,那么当前数据发送完成之后,就代表发送完成,TC=1.
  • RXNE:读缓冲区非空;0:读缓冲区为空,1:读缓冲区不为空;这一位用于判断是否接收到数据,如果接收到一帧的数据,这一位就等于1.
  • IDLE:空闲线检测标志,0:未检测到空闲帧,1:检测到空闲帧;这一位主要是用于判断接收的数据是否完成,如果完成就代表有空闲帧,这一位就会置1.
数据寄存器


数据寄存器32位,但是只有其中8位用于接收和发送数据暂存。

控制寄存器

控制寄存器有三个,但是只有第一个最常用,所以主要介绍第一个控制寄存器。

  • UE:串口使能位;0:USART分频器和输出被禁止 1:USART模块使能
  • PEIE:中断使能;0:禁止产生中断 1:可以产生中断
  • TXEIE:发送缓冲区空中断使能;0:禁止产生中断 1:可以产生中断
  • TCIE:发送完成中断使能;0:禁止产生中断 1:可以产生中断
  • RXNEIE:接收缓冲区非空中断使能;0:禁止产生中断 1:可以产生中断
  • TE:发送使能;0:禁止产生中断 1:可以产生中断
  • RE:接收使能;0:禁止产生中断 1:可以产生中断

USART发送实现

手册中已经给出详细的串口发送配置,其流程如下:

  1. 在USART_CTL1寄存器中置位UE位,使能USART;
  2. 通过USART_CTL1寄存器的M设置字长;
  3. 在USART_CTL2寄存器中写STB[1:0]位来设置停止位的长度;
  4. 在USART_BAUD寄存器中设置波特率;
  5. 在USART_CTL1寄存器中设置TE位;
  6. 等待TXE置位;
  7. 向USART_DATA寄存器写数据;
    依据上面的大致流程就是开启串口时钟,写入相应参数,对串口以及发送使能。相关的C语言代码如下:
//串口参数配置与使能
usart_deinit(USART1);   //复位串口1
usart_baudrate_set(USART1, 115200U);  //串口1波特率设置成115200
usart_word_length_set(USART1, USART_WL_8BIT);  //配置串口1数据长度8位
usart_stop_bit_set(USART1, USART_STB_1BIT);  //配置串口1停止位为1位
usart_parity_config(USART1, USART_PM_NONE);  //配置奇偶校验:无
usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);  //配置串口1硬件控制流:除能RTS
usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);  //配置串口1硬件控制流:除能CTS
usart_receive_config(USART1, USART_RECEIVE_ENABLE);   //使能接收
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);  //使能发送
usart_enable(USART1);  //使能串口
//发送子程序如下:
while(sendCount--){/* wait until end of transmit */while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));usart_data_transmit(USART1, *sb++);}

对于发送子程序的详细分析有while循环中如果usart_flag_get(USART1, USART_FLAG_TBE) == RESET,那么程序就一直在while循环中循环,直到usart_flag_get(USART1, USART_FLAG_TBE) != RESET,那么数据就会由这句usart_data_transmit(USART1, *sb++)写入到数据寄存器,由此通过TX引脚发出。usart_flag_get(USART1, USART_FLAG_TBE)这句话就是获取发送缓冲区是否为空,也就是判断状态寄存器中的TXEIE位,如果为空,则返回SET,while循环中判断条件不成立,程序跳过循环,执行下面那句,就把数据写入到了寄存器中,如果为RESET,那说明数据发送缓冲区还不为空,说明上一次的数据还没有发送完,需要在此等待。

USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U),
#define USART_STAT_REG_OFFSET                     (0x00000000U)        /*!< STAT register offset */

程序中对TBE这个字符的定义如上所示,USART_STAT_REG_OFFSET代表状态寄存器的地址偏移,7U代表TBE为状态寄存器的第7位。

USART接收实现

手册同样给出了USART配置成接收器的操作,在初始化串口完成的前提之下,需要完成

  1. 在USART_CTL0中设置REN位;
  2. 开启串口中断
  3. 开启串口接收缓冲区的中断
  4. 判断接收缓冲区是否为非空,如果为非空,就读数据寄存器中的数据
    USART的接收一般采用中断的方式进行,根据上面的流程,编写出相关的C程序代码如下:
nvic_irq_enable(USART1_IRQn, 0, 1); //开启串口1中断
usart_interrupt_enable(USART1, USART_INT_RBNE);//使能串口1发送缓冲区非空中断
usart_interrupt_enable(USART1, USART_INT_IDLE);//使能串口1发送缓冲区空闲帧中断
void USART1_IRQHandler(void)
{    if(RESET != usart_flag_get(USART1, USART_FLAG_RBNE))  //USART_INT_RBNE{/* receive data */rxbuffer[rxcount++] = usart_data_receive(USART1); //rxcount++}else if(usart_flag_get(USART1, USART_FLAG_IDLEF) != RESET ){usart_data_receive(USART1);bReceStatus = 1;}
}

对于数据的接收子程序详细的分析如下:当数据接收缓冲区有数据时,会触发相应的中断,在中断中,再次判断标志寄存器的RBNE接收缓冲区非空的标志位是否为1,如果为1则代码这个缓冲区有数据,然后将数据从数据寄存器中取入到提前定义的buf中。正常的采用这种接收方式去接收字符串是没有错误的,但是上次在调试单片机与串口屏幕的通信时出现了问题,注意他们的通信采用的是16进制,也就是hex格式进行数据信息收发。错误的现象就是,无论串口屏给单片机发送多长的字节,例如0x5AA567AC,单片机接收到是始终只有前两个,也就是0x5AA5。导致通信无法解析,后来经过查阅资料发现,可以开启接收空闲帧的中断,这个意思大概就是0x5AA567AC是有很多帧组成的,在发送过程中,如果不加入空闲帧,那么说明数据现在还没有接收完成,加入空闲帧之后,当这个标志位为1时,说明现在数据帧接收完毕,线路上出现了空闲帧,这时就可以读取刚刚线路上接收到的完整数据帧了。

总结

通过这篇博客的总结,使我对串口的理解有了更进一步的认识,尤其是串口的接收和发送的实现代码,之前总是直接拿来使用,却没有想过为什么这么去写,有了这一次的总结,也使我以后对串口调试有了快速的解决方法。鉴于笔者知识面有限,如上述内容存在问题,请联系笔者更正,谢谢!

对32位单片机串口的理解相关推荐

  1. CYPRESS S6E1C3 系列 FM0+ 32位单片机串口uart0 问题

    /-----------------------------前奏-----------------------------------/ mcu型号s6e1c32c(48pin).s6e1c32b(3 ...

  2. 嵌入式入门-32位单片机简介

    一.单片机 参见单片机_百度百科 这是单片机的基本介绍,千篇一律搬运工的工作就不打算浪费时间了,就从目前学习到的知识面总结一下单片机吧,当然,入行不到两个月菜狗一枚,不正之处请指正. 单片机,也就是微 ...

  3. 32位单片机 一个32位地址代表一个字节而不是4个字节(32位)

    在数据手册上,BSRR的偏移地址为0X18,然后手册讲完BSRR后直接讲LCKR了,并且LCKR的偏移地址是 OX1C .所以根据 OX1C-0X18=0X04 就知道BSRR是32位寄存器了.因为一 ...

  4. 分享一款电机控制国产32位单片机MM32SPIN360C

    国产32位单片机MM32SPIN360C拥有M0内核的高性能32位微控制器,5V输出的LDO稳压器.三组具备有自举二极管的N通道半桥栅极驱动器.MCU最高工作频率可达96MHz,并内置SRAM高速存储 ...

  5. 灵动微32位单片机LQFP64引脚MM32F3273G7P

    灵动微MM32F3273G7P采用ARM®Cortex®-M3内核的高性能32位单片机,工作频率高达120兆赫兹,内置512KB Flash和128KB RAM的高速存储器,具有丰富的I/O端口和外设 ...

  6. 什么是32位单片机?32位单片机有哪些优点和缺点?8位,16位,32位是什么区别?

    一.什么是32位单片机 单片机有8位单片机.16位单片机.32位单片机等多种,这里位指的是数据处理一次能的够处理的数据的位宽,32位单片机,就是指一次能够处理的数据的位宽是32个比特位的单片机.简单地 ...

  7. 适用于温控器应用的灵动微32位单片机MM32L0130

    温控器的工作原理是通过温度传感器对环境温度自动进行采样.即时监控,当环境温度高于控制设定值时控制电路启动,可以设置控制回差.如温度还在升,当升到设定的超限报警温度点时,启动超限报警功能.当被控制的温度 ...

  8. 32位浮点数的一些理解

    32位浮点数的一些理解 1.定点的缺点:对于一个系统可能出现一些特别大的数和特别小的数,如果用定点表示就会很僵硬,位数一定就不能同时表达特别大的数和特别小的数. 2.对于定点123.625,用科学计数 ...

  9. 国产32位单片机有哪些

    国产32位单片机有哪些 国产32位单片机有哪些呢 1.兆易创新GD32系列 2.灵动微MM32系列 3.华大HC32系列 4.南京沁恒CH32系列 5.华芯微特SWM32系列 2021年单片机价格 国 ...

最新文章

  1. 一文搞定7大流行后端框架:Spring、Netty、MyBatis、Hibernate、Dubbo...
  2. 时间序列预测---差分自回归移动平均模型(ARIMA模型)
  3. matlb中如何设置坐标轴的参数以及进行绘图的如何进行注释
  4. 二叉查找树的简单实现
  5. python super()函数(用来调用父类方法)
  6. ant build里如何指定classpath
  7. Codeforces 338 D. GCD Table
  8. linux中国用户,Linux中国 适合新用户的Linux
  9. Educational Codeforces Round 54 (Rated for Div.2)
  10. github删除文件_github 仓库中删除历史大文件
  11. 【文章】你和自己聊过吗?你很重要
  12. sql nolock_SQL Server NOLOCK和最佳优化
  13. CEO 职位也不保,盘点 2017 年 IT 界残酷的裁员事件
  14. Objective-C 日记② 关于self用法
  15. js扁平数组对象转成树结构
  16. 四阶行列式计算_通过考试01 / 行列式的计算
  17. 2021-06-05按键精灵实现远程获取消息内容
  18. <冈萨雷斯图像处理>局部直方图处理:直方图统计(Histogram Statistics)
  19. Tomcat 何时解压war包
  20. [4G5G专题-129]:RF-架构演进的驱动力与RF常见术语

热门文章

  1. 「消防知识」2018注册消防工程师学习要点(含解析)
  2. TCP以及三次握手和四次挥手的区别
  3. Sql Server之临时表操作
  4. html页面推送功能的实现,想实现Web页面内容自动更新?你需要了解WEB实时推送技术!...
  5. 场效应管调光电路图_场效应管做开关电路图(两款电路图分享)
  6. 按键精灵大漠插件自动寻路自动打怪代码片段
  7. 华为3g网卡 linux,华为Huawei E1550 HSDPA 3G网卡在Ubuntu 10.04 LTS中的使用
  8. 05-SSM版文件上传和下载
  9. 揪出Win7里隐藏的微软官方Windows7主题包
  10. win10远程服务器404错误,win10系统无法打开http://localhost出现404错误的修复教程