串口通信


《用CubeMX学习STM32》

注释 点击上面蓝字进入完整专栏,这个系列所有文章都会整合到这个专栏


本篇博客中用的串口调试助手

链接:https://pan.baidu.com/s/1DN60ojns3Wu88frJ5pqSzA
提取码:6exl
复制这段内容后打开百度网盘手机App,操作更方便哦

时间戳和白字黑字两个比较鸡肋的功能是没有的


3、STM32串口通信

前言: STM32串口介绍

串行通信是单片机与外部设备或其他计算机交换信息的一个方式, 数据一位一位的按顺序传送, 其优点是只需要一条传输线, 协议简单, 但是缺点就是传送速度较慢。
串口是单片机上非常便捷的一个工具, 当写程序需要调试的时候, 它可以很方便的提供调试方法, 只要在一些关键代码执行的地方, 通过串口给串口调试助手发送相关信息, 就可以使我们很方便的查看代码在这个位置的执行情况。

下面看一下我所使用的单片机上串口的原理图接线

外部的发送端TXD就是单片机串口的接收端USART_RX,   外部接收端RXD就是单片机串口的发送端USART_TX
TXD : Transmit(TX) Data(D)  Receive(RX) Data(D))

USART就是Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步/异步串行接收/发送器)的缩写 就是一个全双工的收发器

CH340是串口芯片, 当单片机用一根USB串口线接到电脑的时候, TXD就是指电脑通过数据线给单片机发送数据,对应单片机要接收数据, 因此单片机对应引脚就是RX(接收)

(电脑端发送) TXD -----> USART_RX(单片机接收)

(单片机发送) USART_TX-----> RXD (电脑端接收)

单片机上用跳线帽将PA10, PA9和USART1_RX, USART1_TX连接起来了, 所以我们只需对PA10, PA9配置即可

PA9就是USART1_TX, PA10就是USART1_RX
跳线帽将PA9和CH340的RXD, PA10和CH340的TXD连接起来了

下面开始Cube配置+IAR编程


3.1 操作简介

   使用异步串口通信, 分别以轮询、中断、DMA方式使用串口发送数据进行与电脑的通信。 电脑端使用串口调试助手接收单片机发送的信息


3.2 轮询方式串口通信

单片机会不断查询串口对应引脚, 有通信需求就进行处理, 这样比较浪费CPU资源, 前面在中断里面也讲过, 中断可以很好地弥补这个。 这里先演示轮询方式


Step1 : Cube配置

新建一个工程, 同时也加入LED和按键等对应引脚的配置, 用以配合串口通信

  • (1) RCC和SYS配置

  • (2)USART1串口1配置

注释 :

关于异步传送(Asynchronous)和同步传送(Synchronous)

1、同步发送 : 发送方和接收方以同一个时钟源控制发送和接收。 就是当发送方发出数据后, 等待接收方发回响应后才发下一个数据包。

2、异步传送 : 数据在线路上是以一个字为单位传送, 各个字符之间可以是接连传送也可以是间断传送, 这完全由发送方根据需要来决定。 发送和接收双方分别用自己的饿时钟源来控制发送和接收。   也就是说发送方发出数据后, 不等待接收方回应, 随时可以发送下一组数据

  • (3) 按键和LED引脚配置[Pinout & Configuration]

   跟第二篇博客写的按键的配置一样的 点击下方蓝字快速回到第二篇博客
   第一节补充: 按键操作(CubeMX加HAL库学STM32系列)

  • (4) 时钟树配置[Clock Configuration]

  • (5) 工程配置[Project Manager]

  • (6) 生成代码 (Generate)


Step2 : IAR或Keil编程

  • (1) 重定向printf函数
在学习C语言的时候, 大家肯定都用过printf这个函数, printf可以将指定字符打印到电脑的显示器上。
但是, 单片机要使用这个就要把他打印的方向改一下, 不是打印在电脑的命令行中, 而是打印到串口里面,传输到串口调试助手. 因此我们需要重定向printf函数。
重定向后我们要将调试信息打印到USART1中, 需要对printf所依赖的打印函数fputc()重定向

在usart.c里面添加如下代码

#include "stdio.h"/******************************************************************
*@brief  Retargets the C library printf  function to the USART.
*@param  None
*@retval None
******************************************************************/#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__*/PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}

上面除了重定向的代码, 还包含了一个标准库头函数, 最好加上这个, 因为printf函数就是这个库里面的, 不加的话有时候会出错或者警告

   Tips : HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); 是通过串口1传输一个字符, ch为字符的地址, 0XFFFF表示超时时间 下面是这个函数的定义 Go to definition进入 stm32f4xx_hal_uart.c可以看这个函数定义
   关于串口通信的其他接口函数都可以在 stm32f4xx_hal_uart.h文件里面找到声明

   在stm32f4xx_hal_uart.h里面的一些串口通信相关功能函数

  • (2) 主函数
    由于我们CubeMX配置了串口, 所以主函数里面也自动添加了串口初始化函数

    • 下面添加测试printf的代码
/* USER CODE BEGIN 3 */
// 在while(1)里面循环扫描, 判断读取的按键引脚状态
// 判断 WK_UP 按键是否按下
if (HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET)
{HAL_Delay(10); // 延时10ms, 做一个软件的消抖, 防止因抖动而检测到按键按下if (HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET)         // 如果确实按下了{while(HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) == GPIO_PIN_SET); // 松手检测, 即当这个按键松开后才进行下面的程序, 下同printf("key WK_UP was pressed \r\n");}
}// 判断 KEY0 按键是否按下
if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
{HAL_Delay(10); // 延时10ms, 软件消抖if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET);printf("key KEY0 was pressed \r\n");}
}/* USER CODE END 3 */
  • (3) 编译下载

  what?
  
  

改错

在主函数里面包含一个标准库即可

#include "stdio.h"


注 : 养成习惯, 代码写在规范的位置

因为 printf是C语言标准库里面的函数, 所以我们要使用就最好加上这个, 当然不加也没事, 主要是加上比较完美

0 error(s) , 0 warning(s)

  • (4) 实际效果展示

3.3 中断方式串口通信

操作简介 : 通过中断方式传输指定长度的数据


Step1 : CubeMX配置

与3.1的轮询方式配置几乎都是一样的, 只需要在串口的配置里面勾选使能串口中断即可
先退出IAR或者Keil, 然后更改配置再重新Generate Code

Step2 : IAR或Keil编程

(1) 在main函数外面先增加两个数组用作数据缓冲区

/* USER CODE BEGIN PV */
uint8_t TX_Buffer[] = "\n********** 中断方式串口通信 *********\n输入十个字符 (注:一个汉字为两个字符大小)\n";
uint8_t Rx_Buffer[20]; //接收数据20个字符/* USER CODE END PV */
(2) main函数里面

添加个人代码, 以及通过中断将 TX_Buffer[]里面的数据发送到串口调试助手

并在while(1) 里面不断等待接收数据

while(1) 外面的是我们通过单片机打印到串口的, while(1)里面接收中断发送的数据并显示

/* USER CODE BEGIN 2 */printf("串口通信正常...\n\n");printf("****** Kevin_8_Lee 2020-1-2  ********\n");printf("        *****         *****         *\n");printf("      *********     *********       *\n");printf("    ************* *************     *\n");printf("   *****************************    *\n");printf("   *****************************    *\n");printf("   *****************************    *\n");printf("    ***************************     *\n");printf("      ***********************       *\n");printf("        *******************         *\n");printf("          ***************           *\n");printf("            ***********             *\n");printf("              *******               *\n");printf("                ***                 *\n");printf("                 *                  *\n");printf("*************************************\n");HAL_Delay(500); // 延时500ms, 等待下一步操作  /* 通过中断发送指定长度数据 */HAL_UART_Transmit_IT(&huart1, (uint8_t *)TX_Buffer, sizeof(TX_Buffer));/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_Buffer, 10);}/* USER CODE END 3 */
(3) 再回到main函数外面

在main函数外面添加中断回调函数

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{/* Prevent unused argument(s) compilation warning */UNUSED(huart);printf("\n您发送的消息为: ");     // 提示你所发送的信息HAL_UART_Transmit(&huart1, (uint8_t *)Rx_Buffer, 10,0xFFFF);
}/* USER CODE END 4 */

中断回调函数把串口调试助手发送的数据再发送给串口调试助手, 然后显示出来

(4) 编译下载, 看一下实际效果

关于上述所用到的函数, 大家可以Go to definition去看一下这个函数的定义, 不懂得英文直接谷歌翻译, 问题不大

最后, 常见问题解决办法

  • 1、串口调试助手打印不是一个心形, 而是显示的比较乱

    • 解决办法: 这个可能是由于不同的串口调试助手数据显示的方法不同导致的, 如果你用的是原子的XCOM, 那就把以上所有 \n 这个换行符换为 \r\n 我会在下面把我的串口调试助手分享出来, 可以网盘下载使用
    • 本篇博客中用的串口调试助手(2020年2月2号更新,将调试助手程序修改完善了一部分)

链接:https://pan.baidu.com/s/1DN60ojns3Wu88frJ5pqSzA
提取码:6exl
复制这段内容后打开百度网盘手机App,操作更方便哦

  • 2、上位机发送的字符并未显示出来

    • 解决办法: 这个有可能是由于你没有发够十个字符, 没有触发发送功能. 指定长度传输数据时, 你的函数里面设定的几个字符就一定要发够几个字符, 否则发不出来, 发的多了只会显示一部分, 但是发的少了可能不显示

如果自己试验的时候出现什么问题可以在博客下面评论或者私信我, 知无不言。


最怕一生碌碌无为, 还说平凡难能可贵! 加油吧
Author : 李光辉
date : Thu Jan 2 20:41:56 CST 2020
blog ID: Kevin_8_Lee
blog site : https://blog.csdn.net/Kevin_8_Lee

第三节: 串口通信(用CubeMX学习STM32)相关推荐

  1. 【串口通信】K210与STM32串口通信、K210与OpenMV串口通信

    [串口通信]K210与STM32串口通信.K210与OpenMV串口通信 串口通信 前言 为何需要串口通信 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口发送测试 ...

  2. 蓝桥杯模块学习10——串口通信(深夜学习——单片机)

    一.什么是串口通信? 51单片机--串口通信详解(STC89C51为例)_佛科院深夜学习的博客-CSDN博客 二.IAP15F2K60S2与STC89系列的区别: 1.16位自动重装载模式下波特率的计 ...

  3. 51单片机串口通信【收集学习向】

    本篇整理了学习51串口通信过程中看到的一些比较好的文章,有很多的超链接.并根据自己遇到的情况分析了串口传输乱码的一些原因. 目录 1.原理知识 2.测试程序和虚拟仿真 3.电路设计与公母口连线 电路设 ...

  4. STM32平台的USART串口通信

    本文目的是编写stm32串口通信程序,实现stm32上电自动循环发送hello LYJ!!!,并可通过上位机控制stm32串口发送与否.通过亲自做一下USART串口通信实验,学习如何使用stm32平台 ...

  5. 【K210】K210学习笔记五——串口通信

    [K210]K210学习笔记五--串口通信 前言 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口接收相关定义 K210串口发送接收测试 完整源码 前言 本人大四学生 ...

  6. Matlab 与stm32单片机之间的串口通信

    Matlab 与stm32单片机之间的串口通信 在我们用stm32做信号处理时,我时常需要用到Matlab对我们采集的数据进行分析,拟合.按照传统的方法,我们一般都会先将数据通过串口助手打印出来,再导 ...

  7. GD32串口通信注意事项

    GD32串口通信 虽说GD32与stm32采用同样的ARM® Cortex®-M3内核,而且GD32很大程度上可兼容stm32的程序,但是也存在着一些差异:所以为了使用上减少出错,使用GD32时尽量采 ...

  8. STM32F103ZET6+USART+串口通信

    STM32F103ZET6+USART+串口通信 一. 通信概述 通信就是数据交换.信息交换.嵌入式系统中,微控制器与其他外围设备相互连接,系统各部件之间进行数字信号/数据的传输就是通信,无论是大型嵌 ...

  9. stm8s开发(三) UART的使用:串口通信!

    串口通信是单片机学习的一个最基本.最重要的功能之一.串口通信可以间接的当做调试接口使用,实现单片机与电脑之间的通信.当然可以与一些模块(比如蓝牙.wifi)通信,也可以作为和其他单片机通信的工具. S ...

  10. 多线程的串口通信-1

    多线程的串口通信 1 下位机STM32发送的数据格式与串口参数 1.1下位机上传的数据格式: 1.2串口参数 2 上位机程序 2.1Future: ~~2.2串口参数同上~~ 3 QT程序设计 QT走 ...

最新文章

  1. 黑马程序员--打印流、序列输入流、Vector 类
  2. oracle 日期排序_日期居然用字符串保存?我笑了
  3. ARM/THUMB汇编(补丁开发类)基础教程
  4. 有的人能轻松学会Python编程,不是基础好,而是有了这些刷题网站
  5. H7-TOOL | 以太网 - 动态IP(DHCP)功能测试
  6. 欧洲语言学习统一标准C1C2音频,北京通州区有没有西班牙语培训班(为何选择西班牙语)...
  7. 1万美元奖金,Kaggle 新赛瞄准室内定位
  8. 计算机考试只读,计算机基础考试试题-20210710011550.docx-原创力文档
  9. 读取SqlServer表名及结构
  10. Auto CAD 2020 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 全版本 附带安装教程+入门到精通视频教程
  11. 怀疑chinaitlab的一个Linux模块被黑了!!
  12. 使用FFMPEG将非YUV420p压缩成JPG
  13. OpenGL日常-GLAD
  14. 【5年Android从零复盘系列之二十八】Android存储(3):assets文件详解
  15. JavaEE|IO、存储、硬盘、文件系统相关常识
  16. 硬盘插上后提示“设备未就绪”の解决方案
  17. STM32使用光敏传感器计算光照度Lux,而不是仅仅打印个电压值或者电阻值
  18. vue的页码组件的页码重置为1
  19. 这可能是目前最方便的网站中英文切换(理论支持所有语言)
  20. js生日计算年龄_「周岁怎么算」【js】根据出生日期,计算周岁年龄 - seo实验室...

热门文章

  1. Windows核心编程_锁屏
  2. 【经验之谈】SAP中的普通屏幕使用定制控制
  3. 使用阿里云邮件推送服务架设自己邮件验证与推送体系
  4. sqoop遇到的问题
  5. Widget实例可以添加多个并独立更新
  6. LINUX邮件服务器
  7. HDU 1398 Square Coins
  8. 伪指令 ENTRY 与 END
  9. debugging tools for windows 10下载安装问题
  10. JavaScript_8_比较,条件语句