STM32学习(八)

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();
		//初始化IO
		GPIO_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函数只在测试函数时用,否则可能会影响整个项目的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/3167.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式烧录/刷写文件】-1-详解Motorola S-record(S19/SREC/mot/SX)格式文件

目录 1 什么是Motorola S-record 2 Motorola S-record的格式 2.1 Motorola S-record的结构 2.1.1 “Record type记录类型”的说明 2.1.2 “Record length记录长度”的说明 2.1.3 如何计算“Checksum校验和” 2.2 Record order记录顺序 2.3 Text line terminator文本行终…

HTTP/2.x:最新的网页加载技术,快速提高您的SEO排名

2.1 http2概念HTTP/2.0&#xff08;又称HTTP2&#xff09;是HTTP协议的第二个版本。它是对HTTP/1.x的更新&#xff0c;旨在提高网络性能和安全性。HTTP/2.0是由互联网工程任务组&#xff08;IETF&#xff09;标准化的&#xff0c;并于2015年发布。2.2 http2.x与http1.x区别HTTP…

spring5(三):IOC操作Bean管理(基于xml方式)

IOC操作Bean管理&#xff08;基于xml方式&#xff09;前言一、基于 xml 方式创建对象二、基于 xml 方式注入属性1. 使用 set 方法进行属性注入2. 使用有参数构造进行属性注入3. p 名称空间注入简化操作&#xff08;了解&#xff09;三、xml 注入其它类型属性1. 字面量2. 注入属…

【云原生之企业级容器技术 Docker实战一】Docker 介绍

目录一、Docker 介绍1.1 容器历史1.2 Docker 是什么1.3 Docker 和虚拟机&#xff0c;物理主机1.4 Docker 的组成1.5 Namespace1.6 Control groups1.7 容器管理工具1.8 Docker 的优势1.9 Docker 的缺点1.10 容器的相关技术1.10.1 容器规范1.10.2 容器 runtime1.10.3 容器管理工具…

看齐iOS砍掉祖传功能,Android 16G内存也危险了

手机内存发展是真的迅速&#xff0c;12GB 没保持几年现在又朝着 16GB 普及。 相比 iOS 的墓碑机制&#xff0c;Android 后台就主打一个真实&#xff0c;只是可惜 APP 不那么老实。 如果你较早接触 Android 机&#xff0c;各种系统管理、优化 APP 的一键加速、清理应该还历历在…

AD9235芯片手册阅读笔记

特征 单个3 V电源操作&#xff08;2.7 V至3.6 V&#xff09; SNR70 dBc至65 MSPS时的奈奎斯特 SFDR85 dBc至65MSPS时奈奎斯特低功率&#xff1a; 300 mW至65 MSPS差分输入&#xff0c;带500 MHz带宽 片上参考和SHA DNL0.4 LSB 灵活模拟输入&#xff1a;1 V p-p至2 V p-p范围 偏…

Python的加密与解密,你知道几类?

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 据记载&#xff0c; 公元前400年&#xff0c; 古希腊人发明了置换密码。 1881年世界上的第一个电话 保密专利出现。 在第二次世界大战期间&#xff0c; 德国军方启用“恩尼格玛”密码机&#xff0…

[数据结构] 用两个队列实现栈详解

文章目录 一、队列实现栈的特点分析 1、1 具体分析 1、2 整体概括 二、队列模拟实现栈代码的实现 2、1 手撕 队列 代码 queue.h queue.c 2、2 用队列模拟实现栈代码 三、总结 &#x1f64b;‍♂️ 作者&#xff1a;Ggggggtm &#x1f64b;‍♂️ &#x1f440; 专栏&#xff1…

入职第一天就被迫离职,找工作多月已读不回,面试拿不到offer我该怎么办?

大多数情况下&#xff0c;测试员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 前言 前几天&#xff0c;我们一个粉丝跟我说&#xff0c;正常入职一家外包&#xff0c;什么都准备好了&#xff0…

Portainer堪称最优秀的容器化管理平台

一、Portainer是什么&#xff1f; Portainer是一款开源的容器管理平台&#xff0c;支持多种容器技术&#xff0c;如Docker、Kubernetes和Swarm等。它提供了一个易于使用的Web UI界面&#xff0c;可用于管理和监控容器和集群。Portainer旨在使容器管理更加简单和可视化&#xf…

WinForm | C# 界面弹出消息通知栏 (仿Win10系统通知栏)

ApeForms 弹出消息通知栏功能 文章目录ApeForms 弹出消息通知栏功能前言全局API通知栏起始方向通知排列方向通知栏之间的间隔距离无鼠标悬停时的不透明度消息通知窗体的默认大小示例代码文本消息提示栏文本消息提示栏&#xff08;带选项&#xff09;图文消息提示栏图文消息提示…

【Spring-boot源码剥析】| 启动原理之侠客行篇

目录一. 传说篇二. 快速启动原理三. 自动配置原理3.1 准备阶段3.2 配置阶段3.3 运行阶段三. Pefect Ending一. 传说篇 江湖传说&#xff0c;有一个神秘的江湖大侠&#xff0c;他名叫SpringBoot&#xff0c;擅长于开发出快速启动的应用程序。这个侠客的江湖名号传遍了整个江湖&a…

did not find expected key while parsing a block mapping at line 2 column 1的解决方法

问题描述 真的是困扰了好久的一个问题&#xff0c;真的是邪乎了&#xff0c;报的错误实际上是错的 完整报错&#xff1a; Error: YAML Exception reading /path_to_your_blog/_publications/2020-08-21.md: (<unknown>): did not find expected key while parsing a b…

JQuery

概述&#xff1a; JQuery&#xff1a;JavaScript和查询&#xff0c;他是辅助JavaScript开发的js类库。 他的的核心思想就是write less&#xff0c;do moire 实现了很多浏览器兼容问题 JQuery的核心函数 $(参数) 1 参数是函数&#xff1a;$(function(){}) window.onlooad fun…

AI风暴 :文心一言 VS GPT-4

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 文心一言 VS GPT-4 文心一言&#xff1a;知识增强大语言模型百度全新一代知识增强大语言模型&#xff0c;文心大模型家族的新成员&#xff0c;能够与人对话互动&#…

TryHackMe-Zeno(boot2root)

Zeno 你有和伟大的斯多葛派哲学家芝诺一样的耐心吗&#xff1f;试试吧&#xff01; 端口扫描 循例 nmap Web枚举 进到12340端口 目录扫描 /rms是一个业务站点 在admin登录页面尝试弱口令和注入&#xff0c;也都没有成功 SQLI 在点餐这发现了个get参数id&#xff0c;尝试sql…

八大排序算法之归并排序(递归实现+非递归实现)

目录 一.归并排序的基本思想 归并排序算法思想(排升序为例) 二.两个有序子序列(同一个数组中)的归并(排升序) 两个有序序列归并操作代码: 三.归并排序的递归实现 递归归并排序的实现:(后序遍历递归) 递归函数抽象分析: 四.非递归归并排序的实现 1.非递归归并排序算法…

如何从 Vue CLI 迁移到 Vite

如何从 Vue CLI 迁移到 Vite 十一月11 2021如果你在 2021 年之前一直在使用 Vue 进行开发&#xff0c;那么你选择的构建工具很有可能是 Vue CLI。一段时间以来&#xff0c;它一直是脚手架 Vue.js 项目的事实标准。不过现在&#xff0c;Evan You的下一代构建工具Vite已经引起了很…

精选7个 Python 学习资源库,助你成为优秀的开发者

当你在学习编程时&#xff0c;很容易被大量的资源所吓到&#xff0c;不知道该从何开始。 GitHub 仓库是一个很好的起点&#xff0c;因为它们提供了一种非常实用的方式来了解实际的编程应用。你可以查看其他人的代码&#xff0c;并将其与自己的代码进行比较和学习。 当涉及到 …

kubernetes(k8s)为容器和 Pod 分配内存资源

kubernetes(k8s)为容器和 Pod 分配内存资源 展示如何将内存请求&#xff08;request&#xff09;和内存限制&#xff08;limit&#xff09;分配给一个容器。 我们保障容器拥有它请求数量的内存&#xff0c;但不允许使用超过限制数量的内存。 创建新的命名空间 kubectl creat…