STM32串口通信
数据通信的基础概念
在单片机的应用中,数据通信是必不可少的一部分,比如:单片机和上位机、单片机和外 围器件之间,它们都有数据通信的需求。由于设备之间的电气特性、传输速率、可靠性要求各 不相同,于是就有了各种通信类型、通信协议,我们最常的有:USART、IIC、SPI、CAN、USB 等。
1. 数据通信方式
按数据通信方式分类,可分为串行通信和并行通信两种。串行和并行的对比如下图所示:
串行通信的基本特征是数据逐位顺序依次传输,优点是传输线少、布线成本低、灵活度高 等优点,一般用于近距离人机交互,特殊处理后也可以用于远距离,缺点就是传输速率低。
而并行通信是数据各位可以通过多条线同时传输,优点是传输速率高,缺点就是布线成本 高,抗干扰能力差因而适用于短距离、高速率的通信。
2. 数据传输方向
根据数据传输方向,通信又可分为全双工、半双工和单工通信。全双工、半双工和单工通 信的比较如下图所示:
单工是指数据传输仅能沿一个方向,不能实现反方向传输,如校园广播。
半双工是指数据传输可以沿着两个方向,但是需要分时进行,如对讲机。
全双工是指数据可以同时进行双向传输,日常的打电话属于这种情形。
这里注意全双工和半双工通信的区别:半双工通信是共用一条线路实现双向通信,而全双 工是利用两条线路,一条用于发送数据,另一条用于接收数据。
3.同步通讯与异步通讯
根据通讯的数据同步方式,又分为同步和异步两种,可以根据通讯过程中是否有使用到时钟信号 进行简单的区分。
同步通信要求通信双方共用同一时钟信号,在总线上保持统一的时序和周期完成信息传输。 优点:可以实现高速率、大容量的数据传输,以及点对多点传输。缺点:要求发送时钟和接收 时钟保持严格同步,收发双方时钟允许的误差较小,同时硬件复杂。
异步通信不需要时钟信号,而是在数据信号中加入开始位和停止位等一些同步信号,以便 使接收端能够正确地将每一个字符接收下来,某些通信中还需要双方约定传输速率。优点:没 有时钟信号硬件简单,双方时钟可允许一定误差。缺点:通信速率较低,只适用点对点传输。
4. 通信速率
衡量通讯性能的一个非常重要的参数就是通讯速率,通常以比特率(Bitrate)来表示,即每秒钟传 输的二进制位数,单位为比特每秒(bit/s)。容易与比特率混淆的概念是“波特率”(Baudrate),它 表示每秒钟传输了多少个码元。而码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号 来表示一个二进制数字,这样的信号称为码元。如常见的通讯传输中,用0V表示数字0,5V表 示数字1,那么一个码元可以表示两种状态0和1,所以一个码元等于一个二进制比特位,此时 波特率的大小与比特率一致;如果在通讯传输中,有0V、2V、4V以及6V分别表示二进制数00、 01、10、11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特 位数的一半,这个时候的波特率为比特率的一半。
串口通信协议简介
通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter) 是一个串行通 信设备,可以灵活地与外部设备进行全双工数据交换。有别于USART还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步 通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基 本都是UART。
USART 功能框图
① USART信号引脚
TX:发送数据输出引脚
RX:接收数据输入引脚
SCLK:发送器时钟输出,适用于同步传输
SW_RX:数据接收引脚,属于内部引脚,用于智能卡模式
IrDA_RDI:IrDA模式下的数据输入
IrDA_TDO:IrDA 模式下的数据输出
nRTS:发送请求,若是低电平,表示USART准备好接收数据
nCTS:清除发送,若是高电平,在当前数据传输结束时阻断下一次的数据发送
② 数据寄存器
USART_DR包含了已发送或接收到的数据。由于它本身就是两个寄存器组成的,一个专门 给发送用的(TDR),一个专门给接收用的(RDR),该寄存器具备读和写的功能。TDR寄存器 提供了内部总线和输出移位寄存器之间的并行接口。RDR寄存器提供了输入移位寄存器和内部 总线之间的并行接口。当进行数据发送操作时,往USART_DR中写入数据会自动存储在TDR 内;当进行读取操作时,向USART_DR读取数据会自动提去RDR数据。
USART数据寄存器(USART_DR)低9位数据有效,其他数据位保留。USART_DR的第 9 位数据是否有效跟USART_CR1的M位设置有关,当M位为0表示8位数据字长;当M位 为1时表示9位数据字长,一般使用8位数据字长。
当使能校验位(USART_CR1中PCE位被置位)进行发送时,写到 MSB 的值(根据数据的 长度不同,MSB 是第7位或者第8位)会被后来的校验位取代。
③ 控制器
USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用 USART 之前需要向USART_CR1寄存器的UE位置1使能USART,UE位用来开启供给给串口 的时钟。 发送或者接收数据字长可选8位或9位,由USART_CR1的M位控制。
发送器
在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。
接收器
在接收数据时,编程的时候有几个比较重要的标志位我们来总结下。
④ 时钟与波特率
中断控制
USART 初始化结构体详解
1) USART_BaudRate:波特率设置。一般设置为2400、9600、19200、115200。标准库函数会根据 设定值计算得到USARTDIV值,从而设置USART_BRR寄存器值。
2) USART_WordLength:数据帧字长,可选8位或9位。它设定USART_CR1寄存器的M位的值。 如果没有使能奇偶校验控制,一般使用8数据位;如果使能了奇偶校验则一般设置为9数据位。
3) USART_StopBits:停止位设置,可选0.5个、1个、1.5个和2个停止位,它设定USART_CR2 寄存器的STOP[1:0]位的值,一般我们选择1个停止位。
4) USART_Parity:奇偶校验控制选择,可选USART_Parity_No(无校验)、USART_Parity_Even(偶 校验)以及USART_Parity_Odd(奇校验),它设定USART_CR1寄存器的PCE位和PS位的值。
5) USART_Mode:USART模式选择,有USART_Mode_Rx和USART_Mode_Tx,允许使用逻辑或 运算选择两个,它设定USART_CR1寄存器的RE位和TE位。
6) USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式才有效,可选有使能 RTS、使能CTS、同时使能RTS和CTS、不使能硬件流。
Usart.c
#include "Usart.h"void Usart_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;//打开串口GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//将USARTTx的GPIO配置为推挽复用模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);// 将 USART Rx 的 GPIO 配置为浮空输入模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);// 配置串口的工作参数// 配置波特率USART_InitStruct.USART_BaudRate = 115200;// 配置硬件流控制USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 配置工作模式,收发一起USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 配置校验位USART_InitStruct.USART_Parity = USART_Parity_No;// 配置停止位USART_InitStruct.USART_StopBits = USART_StopBits_1;// 配置 针数据字长USART_InitStruct.USART_WordLength = USART_WordLength_8b;// 完成串口的初始化配置USART_Init(USART1,&USART_InitStruct);// 串口中断优先级配置NVIC_Configuration();//配置指定的USART中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);// 使能串口USART_Cmd(USART1,ENABLE);
}static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 嵌套向量中断控制器组选择 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/* 配置 USART 为中断源 */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;/*使能中断*/NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;/* 抢断优先级为 1 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/*子优先级为2*/NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/*初始化配置NVIC */NVIC_Init(&NVIC_InitStructure);}//发送一个字节
void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch)
{/* 发送一个字节数据到 USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);}//发送两个字节
void Usart_SendHalfWore(USART_TypeDef *pUSARTx,uint16_t data)
{uint8_t temp_h,temp_l;temp_h = (data&0xff00)>>8;temp_l = data&0xff;/* 发送一个字节数据到 USART */USART_SendData(pUSARTx,temp_h);/* 等待发送数据寄存器为空 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);USART_SendData(pUSARTx,temp_l);/* 等待发送数据寄存器为空 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);}/*发送8位数据的数组*/
void Usart_SendArray(USART_TypeDef *pUSARTx,uint8_t *arry,uint8_t num)
{uint8_t i;for(i=0;i<num;i++) {Usart_SendByte(pUSARTx,arry[i]);}while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);}//发送一个字符串
void Usart_SendString(USART_TypeDef *pUSARTx,uint8_t *String)
{uint8_t i = 0;do{Usart_SendByte(pUSARTx,*(String+i));i++;}while(*(String+i) != '\0');while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);
}//中断函数无返回值无参数
void USART1_IRQHandler(void)
{uint8_t Temp;if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET){Temp = USART_ReceiveData(USART1);USART_SendData(USART1,Temp);}}
Usart.h
#ifndef __USART_H
#define __USART_H#include "stm32f10x.h" // Device header
#include "stdio.h"void Usart_Init(void);
static void NVIC_Configuration(void);
void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch);
void Usart_SendHalfWore(USART_TypeDef *pUSARTx,uint16_t data);void Usart_SendArray(USART_TypeDef *pUSARTx,uint8_t *arry,uint8_t num);
void Usart_SendString(USART_TypeDef *pUSARTx,uint8_t *String);#endif
main函数
#include "stm32f10x.h" // Device header
#include "Usart.h"int main(void)
{uint8_t arry[10] = {0,1,2,3,4,5,6,7,8,9};uint8_t arr[] = "huang shi jiang\n";/* 初始化 USART 配置模式为 115200 8-N-1,中断接收 */Usart_Init();//Usart_SendByte(USART1,'A');//Usart_SendHalfWore(USART1,0xff55);//Usart_SendArray(USART1,arry,10);Usart_SendString(USART1,arr);while(1) {}}
相关文章:

STM32串口通信
数据通信的基础概念 在单片机的应用中,数据通信是必不可少的一部分,比如:单片机和上位机、单片机和外 围器件之间,它们都有数据通信的需求。由于设备之间的电气特性、传输速率、可靠性要求各 不相同,于是就有了各种通信…...

Kafka笔记
一、Kafka 概述 1.1.定义 传统定义:Kafka 是一个分布式的基于发布/订阅模式的消息队列,主要用于大数据实时处理领域。最新定义:Kafka 是一个开源的分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务…...

【1.2】神经网络:神经元与激活函数
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏: 神经网络(随缘更新) ✨特色…...

【PythonRS】Pyrsgis库安装+基础函数使用教程
pyrsgis库是一个用于处理地理信息系统(GIS)数据的Python库。它提供了一组功能强大的工具,可以帮助开发人员使用Python语言创建、处理、分析和可视化GIS数据。通过使用pyrsgis库,开发人员可以更轻松地理解和利用地理信息。 pyrsgis库包含了许多常见的GIS操…...

线扫相机DALSA--分频倍频计算公式及原理
分频倍频计算公式及原理 推导原理: 假设编码器脉冲精度为P;同步轮/辊周长为C,Fov为视野,Res为线扫相机分辨率,N代表N倍频编码器,分频为D,倍频为M 线扫项目常规采用N(N 4࿰…...

1818_ChibiOS的计数信号量
全部学习汇总: GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 之前见过计数信号量,也是在FreeRTOS中看到的。也看到过这样的功能在驱动设计中的应用,但是当时没有理解这个使用的方式。 1.…...

企业微信接入芋道SpringBoot项目
背景:使用芋道框架编写了一个数据看板功能需要嵌入到企业微信中,方便各级人员实时观看 接入企业微信的话肯定不能像平常pc端一样先登录再根据权限看页面,不然的话不如直接手机浏览器打开登录账号来得更为方便,所以迎面而来面临两…...

群晖上搭建teamspeak3语音服务器
什么是 TeamSpeak ? TeamSpeak (简称 TS)是一款团队语音通讯工具,但比一般的通讯工具具有更多的功能而且使用方便。它由服务器端程序和客户端程序两部分组成,如果不是想自己架设 TS 服务器,只需下载客户端程…...

Python爬虫(二十四)_selenium案例:执行javascript脚本
本章叫介绍如何使用selenium在浏览器中使用js脚本,更多内容请参考:Python学习指南 隐藏百度图片 #-*- coding:utf-8 -*- #本篇将模拟执行javascript语句from selenium import webdriver from selenium.webdriver.common.keys import Keysdriver webdri…...
Devops团队
DevOps(Development 和 Operations的缩写)是一种软件开发和运维(IT运营)之间协作和沟通的文化、原则和实践。DevOps团队是专注于实施DevOps原则的团队,旨在促进软件开发和运维之间的紧密协作,以加速软件交付…...
力扣labuladong——一刷day10
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣76. 最小覆盖子串二、力扣567. 字符串的排列三、力扣438. 找到字符串中所有字母异位词四、力扣3. 无重复字符的最长子串 前言 一、力扣76. 最小覆盖子串…...

https下载图片
OpenSSL用法示例 OpenSSL源码安装 对于ubuntu,懒得编译源码可以直接安装 sudo apt-get install libssl–dev /usr/include/openssl/ssl.h CMakeLists中添加 link_libraries(ssl crypto) apt-get安装不需要再制定libssl.a, libcrypto.a的路径了, 就像用libc标…...

二叉树的后续遍历(迭代法)
迭代法实现二叉树的后续遍历 1、递归版本 public static void dfs(TreeNode root){if(rootnull){return;}if(root.left!null)dfs(root.left);if(root.right!null)dfs(root.right);System.out.println(root.val); }从递归版本可以看出我们第一步需要遍历完所有的左节点 这里我…...

CVE-2021-41773/42013 apache路径穿越漏洞
影响范围 CVE-2021-41773 Apache HTTP server 2.4.49 CVE-2021-42013 Apache HTTP server 2.4.49/2.4.50 漏洞原理 Apache HTTP Server 2.4.49版本使用的ap_normalize_path函数在对路径参数进行规范化时会先进行url解码,然后判断是否存在…/的路径穿越符…...
前端性能测试工具WebPagetest
简介:一款web性能在线性能评测工具,可测试有关页面在各种条件下的性能,并且提供深入诊断信息。 WebPagetest 的主页:https://www.webpagetest.org/,也就是工具的使用界面。 注意:WebPageTest 并不是完全免…...
易语言软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作
随着信息技术的不断发展,易语言软件定制开发已成为许多公司的一项重要业务。本文将探讨如何利用易语言承接软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作。 一、易语言概述 易语言是一种简单易学的编程语言,它采用中文编程ÿ…...
Windows上配置IP端口转发
在通常涉及到使用网络地址转换(NAT)规则,可以使用一些工具和命令行选项来实现。以下是在Windows上配置端口转发的一般步骤: **注意:端口转发需要管理员权限,因此请确保以管理员身份运行命令行工具。** 1.…...

韦东山D1S板子——汇编启动代码第一行分析(.long 0x0300006f)
1、汇编启动源码 2、分析二进制:0x0300006f 2.1、反汇编代码 2.2、jal指令 jal指令的作用:跳转到当前PC值偏移offset处执行,其中offset由jal指令的bi[31:12]表示; 2.3、分析指令:j 20030 <reset> j 20030 //伪…...

了解单域名证书和通配符证书的区别,选择合适的SSL证书解决方案
随着互联网的不断发展,网站安全性问题一直备受关注,在保护网站数据安全的过程中,SSL证书一直发挥着至关重要的作用。而在选择SSL证书时,单域名证书和通配符证书是两种常见的选择。本文将详细介绍单域名证书和通配符证书的区别&…...

【LeetCode】7. 整数反转
题目链接 文章目录 Python3官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1 ) ⟯ \lgroup O(|x|)、O(1)\rgroup ⟮O(∣x∣)、O(1)⟯写法2写法3 C官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1 ) ⟯ \lgroup O(|x|)、O(1)\rgroup ⟮O(∣x∣)、O(1)⟯ Python3 官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...