前言

这篇记录一下怎么调用标准库的函数来初始化一个串口,并调库实现发数据和收数据,以及串口收中断的使用。

越往深处学习越感觉其实32就是一个功能更加齐全和强大的MCU,其实跟51没有什么本质上的区别。很多设置的地方都是同质化的。比如需要用到某个中断,无非就是初始化一个结构体变量,然后给这个变量的成员配好初值再调用NVIC_Init这个初始化函数新建一个中断。

比如这里我需要用到一个串口接收中断,

static void USART1_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStruct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
}

新建一个NVIC_InitTypeDef的结构体变量,然后给这个变量的成员都配置好相应的值,我这里设置串口接收中断的中断优先级为分组2 主优先级为1 子优先级为1,然后写好当前要配置的是哪一个中断,当前配置的中断为USART1_IRQn,并且配置的这个中断是使能状态,最后调用NVIC(嵌套中断控制器)初始化函数NVIC_Init新建一个中断,并把刚刚配置的结构体的地址作为形参传入进去,库函数就会帮我们新建一个串口中断。

因为我是需要一个串口接收中断。根据手册描述,只要接收寄存器收到数据,USART_SR这个串口的状态寄存器中的RXNE(读数据寄存器非空 (Read data register not empty)) 这一位就会自动置一,如果开启了串口接收中断的话,这时候就会进入相应串口的中断服务函数。

写好配置串口中断的函数之后,在下面的串口初始化函数中调用它:

void USART1_Config(void)
{//初始化GPIOGPIO_InitTypeDef  GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;//打开USART1 RX和TX的时钟 103R8T6 是PA9-TXD  PA10-RXDRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开串口外设的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//将PA9 改为推挽复用GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//将PA10 改为浮空输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);USART_InitStruct.USART_BaudRate = 115200;       //波特率115200USART_InitStruct.USART_WordLength = USART_WordLength_8b;        //字长8bitUSART_InitStruct.USART_StopBits = USART_StopBits_1;             //停止位 1bitUSART_InitStruct.USART_Parity = USART_Parity_No;                //不校验USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //发送和接收都使能USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //不使用硬件流控制USART_Init(USART1,&USART_InitStruct);USART1_NVIC_Config();           //配置串口中断的 分组、优先级等USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);
}

类似新建串口中断的方法,初始化串口的方法也大同小异。首先先新建两个结构体变量,一个用来配置IO,另一个用来配置串口。至于为什么调用一个Init的库函数就能新建好一个串口,这其实不用纠结,库函数其实本质上是根据用户传入的参来判断需要给内部的哪些寄存器赋怎样的值,如果我们使用LL库开发,那么这部分就需要用户自己来写,目前使用标准库,这种工作就交给库来做。

有个日后需要注意的地方,103R8T6的USART1是挂载在APB2时钟线上的,所以在配置USART1这个串口的时候需要开APB2这条时钟线上的USART1外设的时钟;USART2-5都是挂载在APB1这条时钟线上的,所以在使用串口2-5的时候要注意不要开错了时钟。

配置Pin脚就是调用GPIO_Init,配置串口就是调用USART_Init,不过USART_Init这个函数的第一个形参,库已经帮我们新建好了,直接填需要用哪一个USART就行。

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 这一句就是配置串口中断的,因为能触发串口中断有很多种方法,比如发送寄存器空 中断、发送完成 中断、接收寄存器非空 中断 等等…这里就是把串口中断配置成 只有接收寄存器非空 产生一次中断 ,推测如果再同时开启一个 发送完成 中断,当两个条件任意成立一个,就会进入串口1中断服务函数里面,那么在服务函数里面就需要判断一下到底是哪个中断标志成立了产生的中断,再做相应的处理。这个功能就比51强大很多的,不同的组合可以玩出很多不同的效果。

这里还要另说一句,发送寄存器空了 并不代表数据就已经全部发送出去了,发送数据时,MCU会把数据先丢到发送寄存器去,然后发送寄存器再把数据丢到发送移位寄存器去,然后发送移位寄存器再把数据发送到编码模块发给上位机。框图如下:

最后就是开启串口这个外设的库函数 USART_Cmd(USART1,ENABLE);
相应的关闭串口就是 USART_Cmd(USART1,DISABLE);

在主函数初始化的时候调用这个串口初始化函数USART1_Config,就可以把串口外设开起来了。

此时上位机发送一次数据,串口接收到数据之后就会产生一次中断,中断服务函数就可以写为:

void USART1_IRQHandler(void)
{uint8_t rece_data=0;if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET){rece_data = USART_ReceiveData(USART1);USART_SendData(USART1,rece_data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET) {;}}
}

中断回调函数的名字 USART1_IRQHandler 这个是在启动文件里面规定好的,如果自己没有写,库会默认帮我们编译库里面弱定义好的回调函数,内容就是while(1) 即一直停留在回调函数里面。

这个回调函数的内容就是,判断一下接收寄存器非空 这一位是否被置1了(即接收到数据了),如果确定收到数据,那么就调用USART_ReceiveData函数把数据从 数据寄存器(USART_DR) 这里面取出来,当我们在读USART_DR这个寄存器的时候,RXNE这一位自动清零。

把数据读出来之后,调用串口发送函数USART_SendData,把刚刚接收到的数据通过串口1又发送出去,发送期间一直调用USART_GetFlagStatus 获取一下串口1的USART_SR的TC位(发送完成标志位)是否还是0,如果为0则是没法送完,就一直阻塞在这等串口发送完毕,当串口发送完毕之后,发送完成标志位被置一,跳出循环。同时我们就可以在上位机的接收窗口看到刚刚发送了什么数据过去给MCU。

到这一步串口的基础功能就实现完毕了,野火教程里面根据上位机发送的内容来点亮不同的灯,其实就是用switch(或说是if else)根据收到的数据判断一下然后再把相应的IO拉高或是拉低,没什么难度就不写了。

[标准库]STM32F103R8T6 串口的收发相关推荐

  1. 为什么printf可以直接uart输出_AURIX 学习笔记(6)标准库中串口控制台输出

    串口控制台输出 开发单片机与开发 PC 机上软件最大的一点不同就是不像 PC 上,有丰富的调试手段.虽然今天调试器非常先进,只要有配套的 IDE,单步.断点调试已经和 PC 上体验差距不大[1],但 ...

  2. 【STM32】标准库与HAL库对照学习教程八--串口通信详解

    [STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...

  3. STM32 标准库+ESP8266+华为云物联网平台

    文章内容: STM32标准库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台,并完成基本通信与控制,包括设备属性上报和命令下发解析与响应,并将相关代码打包成HuaweiIOT_a ...

  4. STM32F103标准库开发----CAN总线通信实验----发送和接收

    STM32F103标准库开发----目录 STM32F103标准库开发----CAN总线通信实验----基本原理 STM32F103标准库开发----CAN总线通信实验----初始化/波特率 STM3 ...

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

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

  6. STM32 HAL库串口同时收发,接收卡死?

    STM32 使用 HAL库串口同时收发,使用踩坑史 = =!......by 矜辰所致 目录 前言 一. HAL 库串口收发 1.1 串口发送 1.2 串口接收 1.2.1 标准库接收 1.2.1 H ...

  7. hal库串口dma卡死_HAL库版DMA循环模式串口数据收发

    在<STM32CubeMX初识与工程创建>的基础上,首先对串口进行设置,以实现通过串口对数据的收发.STM32CubeMX生成的HAL库中,提供了三类串口数据收发的接口,分别为阻塞模式,非 ...

  8. STM32F103VE基于标准库下DHT11数据串口打印输出

    STM32F103VE基于标准库下DHT11数据串口打印输出

  9. STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库)

    目录 DS1302的性能指标 DS1302的寄存器及片内RAM 标准库实现 HAL库实现 源码链接 单片机型号:STM32F103C8T6 在日常生活中,很多情况下会需要使用时间,单片机中虽然也是有定 ...

最新文章

  1. Delphi 2009 中 TStrings 与 TStream 的增强
  2. Vivado HLS基本应用
  3. 项目测试基础:黑盒测试相关知识笔记
  4. input 文本框和 img 验证码对齐问题
  5. css移动端页面单位,视窗单位在移动端上的使用技巧
  6. Android开启桌面模式,Android Q自带桌面模式:支持大宽屏幕
  7. 神经网络matlab 验证集,机器学习中训练集、验证集、测试集的定义和作用
  8. SAI2和PS如何查看当前鼠标位置内容的图层
  9. @人生随笔:一年一影帝,百年周星驰
  10. 零延迟!海康大华宇视网络监控摄像头RTSP浏览器网页无插件播放终极解决方案
  11. Python 微信自动化工具开发系列01_自动获取微信聊天信息(2023年1月可用)
  12. 翁恺 python_翁恺 - 主页
  13. win7升级ie到ie10后打不开的解决办法
  14. 分散性与变异性的度量——全距、四分位距、标准差、标准分
  15. java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
  16. POJ 2431 丛林探险(优先队列)
  17. 长沙有哪些点餐系统服务商?长沙点菜软件哪家好?
  18. Android进阶必备:滑动冲突解决与事件分发机制(附视频讲解)这篇看完还不懂请寄刀片
  19. socket中的read返回0
  20. Redis 地理坐标(GEO)方法使用详解

热门文章

  1. Android 实现答题器功能(通过手势实现翻页效果)
  2. 大学生须知:毕业当程序员想要提升“核心竞争力”,主要看这六点!
  3. 开源数据库 SQLite 发布 3.37.0 版本
  4. 清华大学张长水教授:机器学习和图像识别(附视频、PPT下载)
  5. matlab 控制硬件,自动控制原理实验教程(硬件模拟与MATLAB仿真)
  6. iPhone开发初试锋芒 一个简单的iPhone播放器 --紫枫凝潇烟
  7. js 个性标签图片生成
  8. P2P知识(2)--P2P详解
  9. 海水淡化膜:反渗透膜在水处理行业的应用价值
  10. ubuntu下qnx7.0交叉编译qt5.9.7源码