STM32学习(八)

news/2024/11/27 17:44:03/

STM32串口与电脑USB口通信

在这里插入图片描述
特别注意:两个设备之间的TXD和RXD,必须交差连接,方可正常通信

RS-232异步通信协议

在这里插入图片描述

  1. 启动位:必须占1个位长,必须保持逻辑0电平。
  2. 有效数据位:可选5、6、7、8、9个位长,LSB(最低有效位)在前,MSB在后
  3. 校验位:可选1个位长,也可以没有该位。
  4. 停止位:必须有,可选占0.5、1、1.5、2个位长,保持逻辑1电平

USART

实现串口通信的外设:Universal Synchronous asynchronous receiver transmitter,通用同步异步收发器。
Universal asynchronous receiver transmitter,通用异步收发器。
USART/UART都可以与外设进行全双工(同时接收或发送数据)异步(无时钟信号)通信。

1,全双工异步通信
2,单线半双工通信
3,单独的发送器和接收器使能位
4,可配置使用DMA的多缓冲器通信
5, 多个带标志的中断源

在这里插入图片描述在这里插入图片描述
3+2:USART+UART
在这里插入图片描述
在这里插入图片描述

  1. TX:发送引脚
  2. RX:接收引脚
  3. 串口发送数据,就需要对USART进行写操作,先对DR进行写操作,写完后,数据自动传输到发送数据寄存器TDR,TDR等待发送移位寄存器为空时,再将数据传入到发送移位寄存器。
  4. 灰色框图内的寄存器,用户无法直接访问,通过操作数据寄存器DR,才能实现对应功能。

在这里插入图片描述

设置USART/UART波特率(F1)

在这里插入图片描述
波特率计算公式:
在这里插入图片描述
其中fck是串口的时钟,如:USART1的时钟是PCLK2,其他串口都是PCLK1
在这里插入图片描述

  • DIV_Mantissa是UARTDIV整数部分
  • DIV_Fraction是UARTDIV小数部分
  • 上面两个值存放在USART_BRR中。

波特比率寄存器BRR
在这里插入图片描述
把USARTDIV的整数部分写入位[15:4], USARTDIV的小数部分写入[3:0]

如何使用寄存器操作的方式设置波特率 - USART1为例
在这里插入图片描述

uint16_t mantissa; 
uint16_t fraction; 
mantissa=39; 
fraction=0.0625*16+0.5=0x01;          /* USARTDIV = DIV_Mantissa + (DIV_Fraction/16) +0.5是四舍五入*/
USART1->BRR = (mantissa << 4) + fraction;

在这里插入图片描述
控制寄存器1(CR1)
该寄存器需要完成的配置:
位13:使能USART
位12:配置8个数据位
位10:禁止检验控制
位5:使能接收缓冲区非空中断
位3:使能发送
位2:使能接收

控制寄存器2(CR2)
在这里插入图片描述
控制寄存器3(CR3)
在这里插入图片描述
数据寄存器(DR)
在这里插入图片描述
设置好控制寄存器和波特率寄存器后,往该寄存器写入数据即可发送,接收数据则读该寄存器。

状态寄存器(SR)
在这里插入图片描述

需要配置的时序总结
在这里插入图片描述
在这里插入图片描述

HAL库外设初始化MSP回调机制

在这里插入图片描述
HAL库外设初始化MSP回调机制- USART为例
在这里插入图片描述

HAL库中断回调机制

在这里插入图片描述
在这里插入图片描述
串口反初始化函数:失能串口

在这里插入图片描述

USART/UART异步通信配置步骤

  1. 配置串口工作参数:HAL_UART_Init()
  2. 串口底层初始化:重定义HAL_UART_MspInit(),配置GPIO、NVIC、CLOCK等。
  3. 开启串口异步接收中断:HAL_UART_Receive_IT()
  4. 设置优先级,使能中断:HAL_NVIC_SetPriority()、HAL_NVIC_EnableIRQ()
  5. 编写中断服务函数,UARTx_IRQHandler()
  6. 串口数据发送,USART_DR,HAL_UART_Transmit()
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
typedef struct 
{    uint32_t BaudRate; 		/* 波特率 */ uint32_t WordLength; 	/* 字长 */uint32_t StopBits; 		/* 停止位 */ uint32_t Parity; 			/* 奇偶校验位 */ uint32_t Mode; 			/* UART 模式 */ uint32_t HwFlowCtl; 		/* 硬件流设置 */ uint32_t OverSampling; 	/* 过采样设置 */ 
}UART_InitTypeDef
typedef enum
{HAL_OK       = 0x00U,HAL_ERROR    = 0x01U,HAL_BUSY     = 0x02U,HAL_TIMEOUT  = 0x03U
} HAL_StatusTypeDef;

在这里插入图片描述

typedef struct
{__IO uint32_t SR;         /*!< USART Status register,                   Address offset: 0x00 */__IO uint32_t DR;         /*!< USART Data register,                     Address offset: 0x04 */__IO uint32_t BRR;        /*!< USART Baud rate register,                Address offset: 0x08 */__IO uint32_t CR1;        /*!< USART Control register 1,                Address offset: 0x0C */__IO uint32_t CR2;        /*!< USART Control register 2,                Address offset: 0x10 */__IO uint32_t CR3;        /*!< USART Control register 3,                Address offset: 0x14 */__IO uint32_t GTPR;       /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  1. 以中断的方式接收指定字节的数据
  2. 形参1:UART_HandleTypeDef结构体类型指针变量
  3. 形参2:指向接收数据缓冲区
  4. 形参3:接收的数据大小,以字节为单位
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
  1. 以阻塞的方式(必须发送完)发送指定字节的数据。
  2. 形参1:UART_HandleTypeDef结构体类型指针变量
  3. 形参2:指向要发送的数据地址
  4. 形参3:要发送的数据大小,以字节为单位
  5. 形参4:设置的超时时间,以ms为单位

IO引脚复用功能

  1. 通用:IO端口的输入或输出是由GPIO外设控制,我们称之为通用。
  2. 复用:IO端口的输入或输出是由其它非GPIO外设控制,我们称之为复用。

在这里插入图片描述
同一时间IO只能用作一种复用功能,否则会发生冲突,遇到IO复用功能冲突,可考虑重映射功能。

为了解决F1系列存在的IO复用功能冲突问题,F4往后的系列都加入了复用器。
复用器特点:

  1. 每个IO引脚都有一个复用器。
  2. 复用器采用16路复用功能输入(AF0到AF15)
  3. 复用器一次仅允许一个外设的复用功能(AF)连接到IO引脚
  4. 通过GPIOx_AFRL和GPIOx_AFRH寄存器进行配置。
  5. 复位完成后,所有IO都会连接到系统的复用功能0(AF0)

通过串口接收或者发送一个字符

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PA9对应的是TXD,连接的是RXD。
PA10对应的是RXD,连接的是TXD。

输出不用设置上下拉,输入不用设置速度。

因为空闲的时候是高电平,所以输入设置为上拉。
usart.h

#ifndef __USART_H_
#define __USART_H_
//当有一个变量需要在多个文件中用到时,不能定义在头文件中,会导致重复定义,要把该变量定义在某个.c文件中,另一个需要用到该变量的.c文件在该变量的声明前加extern
extern UART_HandleTypeDef UART1_Handler;
extern u16 USART_RX_STA;
#define RXBUFFERSIZE 1
extern u8 aRxBuffer[RXBUFFERSIZE];

usart.c

u16 USART_RX_STA=0;//接收状态标记
UART_HandleTypeDef UART1_Handler;/*UART串口句柄*/
u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲区void usart_init(uint32_t baudrate)
{UART1_Handler.Instance = USART1; //寄存器基地址UART1_Handler.Init.BaudRate = baudrate;UART1_Handler.Init.WordLength = UART_WORDLENGTH_8B;UART1_Handler.Init.StopBits = UART_STOPBITS_1;UART1_Handler.Init.Parity = UART_PARITY_NONE;UART1_Handler.Init.Mode = UART_MODE_TX_RX;HAL_UART_Init(&UART1_Handler);//开启串口接收中断HAL_UART_Receive_IT(&UART1_Handler,(u8 *)aRxBuffer,RXBUFFERSIZE)
}//串口初始化MSP回调函数
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{//GPIO端口设置GPIO_InitTypeDef GPIO_Initure;if(huart->Instance == USART1){//使能USART和对应IO时钟__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_AFIO_CLK_ENABLE();//初始化IOGPIO_Initure.Pin = GPIO_PIN_9;GPIO_Initure.Mode = GPIO_MODE_AF_PP;//不能使用开漏式,因为不能使用高电平,除非有外部上拉,输出不需要上下拉GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA,&GPIO_Initure);GPIO_Initure.Pin = GPIO_PIN_10;GPIO_Initure.Mode = GPIO_MODE_AF_INPUT;GPIO_Initure.Pull = GPIO_NOPULL;//默认状态是高电平,所以要上拉HAL_GPIO_Init(GPIOA,&GPIO_Initure);//使能USART1中断,设置优先级HAL_NVIC_EnableIRQ(USART1_IRQn);HAL_NVIC_SetPriority(USART1_IRQn,3,3);}
}/*串口1中断服务函数*/
void USART1_IRQHandler(void) 
{HAL_UART_IRQHandler(&UART1_Handler);//失能中断,并且会调用Callback函数HAL_UART_Receive_IT(&UART1_Handler,(u8 *)aRxBuffer,RXBUFFERSIZE);
}//串口数据接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
printf函数只在测试函数时用,否则可能会影响整个项目的性能。


http://www.ppmy.cn/news/35021.html

相关文章

【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛客观题以及详细题解

题1 概念题。 USRAT&#xff1a;异步串口通信&#xff0c;常用于数据传输&#xff1b;SW-DP&#xff1a;SWD 的全称应该是 The Serial Wire Debug Port (SW-DP),也就是串行调试端口&#xff0c;是 >ARM 目前支持的两种调试端口之一&#xff1b;JTAG-DP&#xff1a;另一个调试…

Python|蓝桥杯进阶第五卷——数论

欢迎交流学习~~ 专栏&#xff1a; 蓝桥杯Python组刷题日寄 蓝桥杯进阶系列&#xff1a; &#x1f3c6; Python | 蓝桥杯进阶第一卷——字符串 &#x1f50e; Python | 蓝桥杯进阶第二卷——贪心 &#x1f49d; Python | 蓝桥杯进阶第三卷——动态规划 ✈️ Python | 蓝桥杯进阶…

LeetCode:242. 有效的字母异位词

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 文章目录一、&#x1f331;[242. 有效的字母异位词](https://leetcode.cn/problems/valid-…

【数据结构】树和二叉树的介绍

文章目录前言一、树1.1 树的概念1.2 树的相关概念1.3 树的表示1.4 树的用途二、二叉树2.1 二叉树的概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储方式总结前言 树是一种让程序员们既爱又恨的数据结构。它就像是一棵大树&#xff0c;让你可以轻松地摘取其中的果实…

【10】核心易中期刊推荐——模式识别与机器学习

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

【数据结构】二叉树的遍历以及基本操作

目录 1.树形结构 1.概念 2.二叉树 2.1概念 2.2 两种特殊的二叉树 2.3二叉树的存储 2.4二叉树的基本操作 1.手动快速创建一棵简单的二叉树 2.二叉树的遍历 (递归) 3.二叉树的层序遍历 4.获取树中节点的个数 5.获取叶子节点的个数 6.获取第K层节点的个数 7.获取二叉…

【算法】一文详解贪心法

一、概述 贪心法将一个复杂问题分解为一系列较为简单的局部最优解&#xff0c;每一步都是对当前解的一个扩展&#xff0c;直到获得问题的完全解。贪心法的典型应用时求解最优化问题&#xff0c;而且即使是非最优解&#xff0c;最终得出的解也和最优解比较近似 1.1 贪心法设计…

集合之HashMap 1.7总结

文章目录底层数据结构&#xff1a;HashMap有什么特点&#xff1f;HashMap 1.7 是如何解决Hash冲突的&#xff1f;HashMap 1.7 是如何降低Hash冲突概率的&#xff1f;HashMap 的长度为什么是2的幂次方&#xff1f;HashMap 容量应该如何设置&#xff1f;高并发下如何使用HashMap?…