STM32-NUCLEO-F411RE-USART_串口

  • 串口基本原理
    • 异步串行通信的特点
    • 异步串行通信的两个关键点
    • 异步串行通信的数据接收过程
    • 串行内部寄存器结构框图
    • 串行状态标志位
    • 串囗初始化过程
  • 一、配置时钟
  • 二、配置调试模式
  • 三、串口参数配置
  • 四、生成 Keil 工程
  • 代码部分
    • UART结构体定义
    • UART函数
      • 1、串口发送/接收函数
      • 2、串口中断函数
      • 3、串口查询函数
    • 主程序
  • 七、实验效果
  • 八、重定向 printf

使用STM32CubeMX生产初始化代码,底板硬件使用NUCLEO-F411RE开发板

串口基本原理

异步串行通信的特点

特点:数据传输以单个字符为单位,字符和字符之间的间隙任意,字符内部每一位持续的时间相同。收发双方没有专门的时钟信号,而是依靠事先约定的字符格式和通信速率来完成通信。


常用字符格式:1位起始位 8位数据位 无奇偶校验 1位停止位

波特率:每秒钟传送二进制数码的位数,以bit/s(bps)为单位
常用的波特率有:9600、19200、38400、57600和115200;

波特率为115200,表示每秒传输115200位,且每一位数据在数,据线上持续时间为Tbit=1/115200=8.68us。 波特率为9600时起始位长度为104.2us。

异步串行通信的两个关键点

异步串行通信的数据接收过程

串行内部寄存器结构框图

串行状态标志位

串囗初始化过程

一、配置时钟

开发板焊接了外部晶振,所以我 RCC(Reset and Cock Control) 配置选择了 Crystal/Ceramic Resonator(石英/陶瓷谐振器),配置完成后,右边的 Pinout view 里相关引脚就会被标绿。

外部高速时钟配置完成后,进入 Clock Configuration 选项,根据实际情况,将系统时钟配置为 96 MHz,配置步骤如下,最后按下回车,软件会自动调整分频和倍频参数。

二、配置调试模式

ST-Link 就是 Serial Wire 调试模式,一定要设置!!!
以前使用 M0 的芯片,不配置这个模式没出现问题,但现在这个型号,如果不配置 Serial Wire 模式,程序一旦通过 ST-Link 烧录到芯片中,芯片就再也不能被ST-Link 识别了。(后来我是通过 STMISP 工具烧录程序/擦除后才恢复正常的)

三、串口参数配置

串口为 USART1,按照下面步骤配置 USART1,将其设置为异步模式(Asynchronous),波特率 115200(默认),字长 8 Bits(默认),无校验(默认),停止位 1(默认),使能发送和接收(默认):

使能中断

四、生成 Keil 工程

设置 IDE 和 工程目录及名称:

将每种外设的代码存放到不同的 .c /.h 文件中,便于管理(不然都会被放到 main.c 中)。

代码部分

UART结构体定义

typedef struct __UART_HandleTypeDef
{USART_TypeDef                 *Instance;        /*!< 串口寄存器的基地址定义           */UART_InitTypeDef              Init;             /*!< 串口初始化数据类型             */uint8_t                       *pTxBuffPtr;      /*!< 串口发送缓冲区首地址                */uint16_t                      TxXferSize;       /*!< 串口待发送数据个数             */__IO uint16_t                 TxXferCount;      /*!< 串口发送数据计数器               */uint8_t                       *pRxBuffPtr;      /*!< 串口接收缓冲区首地址              */uint16_t                      RxXferSize;       /*!< 串口待接收数据个数             */__IO uint16_t                 RxXferCount;      /*!< 串口接收数据计数器             */__IO HAL_UART_RxTypeTypeDef ReceptionType;      /*!< 持续接收类型                        */DMA_HandleTypeDef             *hdmatx;          /*!< 串口发送的DMA通道句柄定义        */DMA_HandleTypeDef             *hdmarx;          /*!< 串口接收的DMA通道句柄定义        */HAL_LockTypeDef               Lock;             /*!< 保护锁类型定义                   */__IO HAL_UART_StateTypeDef    gState;           /*!< 串口全局状态和发送状态信息*/__IO HAL_UART_StateTypeDef    RxState;          /*!< 串口接收状态信息*/__IO uint32_t                 ErrorCode;        /*!< 串口错误代码                      */
} UART_HandleTypeDef;

UART函数

1、串口发送/接收函数

HAL_UART_Transmit();串口发送数据,使用超时管理机制
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
这几个函数的参数基本都是一样的,我们挑两个讲解一下

串口发送数据:

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

功能:串口发送指定长度的数据。如果超时没发送完成,则不再发送,返回超时标志(HAL_TIMEOUT)。

参数:

UART_HandleTypeDef *huart UATR的别名 如 : UART_HandleTypeDef huart1; 别名就是huart1
*pData 需要发送的数据
Size 发送的字节数
Timeout 最大发送时间,发送数据超过该时间退出发送

举例:   HAL_UART_Transmit(&huart1, (uint8_t *)ZZX, 3, 0xffff);   //串口发送三个字节数据,最大传输时间0xffff

中断接收数据:

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

功能:串口中断接收,以中断方式接收指定长度数据。
大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断。
再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)

参数:

UART_HandleTypeDef *huart UATR的别名 如 : UART_HandleTypeDef huart1; 别名就是huart1
*pData 接收到的数据存放地址
Size 接收的字节数

举例:    HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,1);   //中断接收一个字符,存储到value中

2、串口中断函数

HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();串口接收错误函数

串口接收中断回调函数:

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

功能:HAL库的中断进行完之后,并不会直接退出,而是会进入中断回调函数中,用户可以在其中设置代码。

串口中断接收完成之后,会进入该函数,该函数为空函数,用户需自行修改

参数:

UART_HandleTypeDef *huart UATR的别名 如 : UART_HandleTypeDef huart1; 别名就是huart1

举例:   HAL_UART_RxCpltCallback(&huart1){           //用户设定的代码               }

串口中断处理函数

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);

功能:对接收到的数据进行判断和处理 判断是发送中断还是接收中断,然后进行数据的发送和接收,在中断服务函数中使用

如果接收数据,则会进行接收中断处理函数

 /* UART in mode Receiver ---------------------------------------------------*/if((tmp_flag != RESET) && (tmp_it_source != RESET)){ UART_Receive_IT(huart);}

如果发送数据,则会进行发送中断处理函数

  /* UART in mode Transmitter ------------------------------------------------*/if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)){UART_Transmit_IT(huart);return;}

3、串口查询函数

HAL_UART_GetState(); 判断UART的接收是否结束,或者发送数据是否忙碌

举例:

while(HAL_UART_GetState(&huart4) == HAL_UART_STATE_BUSY_TX)   //检测UART发送结束

主程序

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"uint8_t RxBuffer;
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, 1, 10);  // 把收到的字节发送出去,10ms超时时间HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);  // 开启下一次串口中断}
}/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);  // 开启下一次串口中断HAL_UART_Transmit(&huart1, "HAL_UART_Transmit test\r\n", 24, 0xffff);  //发送字符串/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */HAL_UART_Transmit(&huart1, "hello world\r\n", 13, 0xffff);HAL_Delay(500);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 4;RCC_OscInitStruct.PLL.PLLN = 96;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

七、实验效果

八、重定向 printf

在工程中添加下面代码,重定义 fputc

#include "usart.h"
#include <stdio.h>/* USER CODE BEGIN 0 */
int fputc(int ch,FILE *f)
{HAL_UART_Transmit(&huart1,(uint8_t *)&ch, 1, 0xFFFF);return ch;
}
/* USER CODE END 0 */

需要使用C语言函数

将前文示例代码中的 HAL_UART_Transmit() 替换成 printf() 将实现同样的功能

STM32-NUCLEO-F411RE-USART_串口相关推荐

  1. 如何让Arduino IDE支持你手里的STM32 nucleo开发板

    Arduino IDE开发环境在默认情况下不支持STM32 NUCLEO开发板,只有通过添加附加开发板管理包才能使用.目前为止,只有一部分板子支持使用Arduino IDE开发环境进行开发,分别是 N ...

  2. STM32 Nucleo开发板入门(一)——概述

    在实验室找到一块 STM32 的开发板,型号是STM32 Nucleo-L031K6.趁着十一假期,入门一下,顺便随便记点东西. NUCLEO-L031K6 | Mbedhttps://os.mbed ...

  3. stm32学习笔记----双串口同时打开时的printf()问题

    stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...

  4. STM32使用DMA发送串口数据

    1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ...

  5. STM32工作笔记0017---ISP串口下载

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 这个安装也是有教程的. 串口一般来说就是PA9,PA10 stm32,一般通过串口1下载ÿ

  6. STM32与中显串口屏的通信

    STM32与中显串口屏的通信 本文将简要介绍STM32单片机和武汉中显串口屏之间的通信实现过程.不过使用大彩.迪文这些公司的串口屏的同学也能参考一下,它们的通信协议好像一样. 注意:我代码用的ardu ...

  7. K_A13_001 基于STM32驱动霍尔开关传感器 串口与OLED0.96双显示

    K_A13_001 基于STM32驱动霍尔开关传感器 串口与OLED0.96双显示 一.资源说明 二.基本参数 参数 引脚说明 三.驱动说明 对应程序: 四.部分代码说明 1.接线引脚定义 STM32 ...

  8. STM32平台的USART串口通信

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

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

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

  10. STM32 NUCLEO开发板通过Mini USB供电

    STM32 NUCLEO开发板可以通过Mini USB(CN1)供电 但不能插上去就使用,需要用跳线帽短接JP1(红色方框位置) 资料原文: JP1 jumper can be set in case ...

最新文章

  1. 2018微信年度数据报告:00后最爱表情捂脸哭 80后呲牙笑
  2. 用Tcl定制Vivado设计实现流程
  3. 编译包含Google Play服务App的SDK版本问题
  4. mysql 开发进阶篇系列 22 磁盘I/O问题(从linux操作系统上优化)
  5. 幕课网产品总监:教你从0到1打造600W下载量的爆款APP
  6. Jupyter notebook Ipython 魔法函数 Magic 计算代码(函数)耗时 Timing(%%time %time %timeit)
  7. SAP 电商云 Spartacus UI SSR 单元测试里的 callFake
  8. 【One by One系列】IdentityServer4(三)使用用户名和密码
  9. FIFO队列 ADT接口 链表实现
  10. 剑指offer面试题[31]-连续数组的最大和
  11. html水平垂直居中
  12. python微信自动发朋友圈_Python自制微信机器人:群发消息、自动接收好友
  13. Java 调用阿里云小蜜示例代码
  14. Nvidia Tesla M40 装机保姆教程
  15. 计算机程序ppt,计算机和计算机程序.ppt
  16. Think Pad E570重装Win10系统没有外放喇叭声音
  17. 5-27 冒泡法排序 (20分)
  18. Performing Basic Amazon S3 Bucket Operations
  19. 烘焙门店 | 解锁公众号精准引流5W+的流量密码
  20. 异构计算, GPU和框架选型指南

热门文章

  1. 空间杜宾模型-多种权重矩阵制作、空间相关性检验、SDM、SEM、SAR模型的命令、相关检验及其结果分析
  2. centos下配置nagios监控主机及服务的总结
  3. java新手入门指南
  4. angularJs实现排序效果
  5. 新华三又获一奖“中国IT服务领军企业”,专业能力再受认可
  6. 新基建浪潮来袭 企业快速上云应一切从“简”
  7. (附源码)小程序 心理治愈 毕业设计041506
  8. PHP----下载断点后续传
  9. 计算机u盘 硬盘无法读取,解读:在Lenovo计算机U盘的启动PE中看不到硬盘的解决方案(无法识别)...
  10. 直击2023云南移动生态合作伙伴大会,聚焦云南移动的“价值裂变”