STM32串口通信入门

文章目录

  • 一、串口协议和RS-232标准,以及RS232电平与TTL电平的区别
    • 1.串口通信协议
    • 2.RS-232标准
    • 3.RS232电平与TTL电平的区别
    • 4.USB/TTL转232“模块(CH340芯片为例)
  • 二、补充实验
    • (一)几个常见的库函数、结构体
      • 1.时钟配置函数
      • 2.GPIO口的初始化类型定义结构体
      • 3.GPIO口的类型定义结构体
      • 4.GPIO口的初始化函数
    • (二)实验
      • 1.标准库实现LED灯闪烁
        • (1)代码
        • (2)Proteus仿真
        • (3)实验现象
      • 2.标准库实现LED流水灯
        • (1)代码
        • (2)Proteus仿真
        • (3)实验现象
      • 3.用STM32发送数据,并用串口助手接收
        • (1)代码
        • (2)串口助手接收
      • 4.串口查询方式点亮LED灯
        • (1)代码
        • (2)实验现象
  • 三、keil波形
      • 1.配置合适的Xtal(External Crystal Oscillator)外部晶振
      • 2.输入正确的芯片参数
      • 3.进入波形仿真界面
      • 4.仿真波形
  • 四、心得体会

一、串口协议和RS-232标准,以及RS232电平与TTL电平的区别

1.串口通信协议

是一种数据传输协议,常用于计算机和其他设备之间的通信。
它定义了数据传输的规则,如数据格式、传输速率等。

2.RS-232标准

是一种标准的串口通信协议。
定义了数据传输的电压范围、信号线功能、连接方式和传输速率等
RS-232 标准主要规定了信号的用途,通讯接口以及信号的电平标准。

由于RS-232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号,才能实现通讯。

3.RS232电平与TTL电平的区别

根据通讯使用的电平标准不同,串口通讯可分为 TTL标准和 RS-232标准。

在这里插入图片描述

从表中可以看出,逻辑电压不同,在电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进制逻辑 1,使用 0V 表示逻辑 0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V表示逻辑 1,+15V 表示逻辑 0。

4.USB/TTL转232“模块(CH340芯片为例)

USB主机检测到USB转串口设备插入后,首先会对设备复位,然后开始USB枚举过程。USB枚举时过程会获取设备描述符、配置描述符、接口描述符等。描述符中会包含USB设备的厂商ID,设备ID和Class类别等信息。操作系统会根据该信息为设备匹配相应的USB设备驱动。
USB虚拟串口的实现在系统上依赖于USB转串口驱动,一般由厂家直接提供,也可以使用操作系统自带的CDC类串口驱动等。驱动主要分为2个功能,其一注册USB设备驱动,完成对USB设备的控制与数据通讯,其二注册串口驱动,为串口应用层提供相应的实现方法。

二、补充实验

在上一次寄存器方式点亮LED灯的基础上,改用标准库方式,完成LED的点灯或流水灯实验。

(一)几个常见的库函数、结构体

1.时钟配置函数

APB2外设时钟控制命令函数
定义
在这里插入图片描述

通俗易懂地解释一下参数的含义:
①uint32_t RCC_APB2Periph:要求参数应当是一个无符号的32位整形数,然而在实际调用过程中,它传入的参数是经过“位掩码”技术处理过的RCC_APB2Periph_GPIOA、等外设名称。说直白点就是RCC_APB2Periph_GPIOA代码的就是一个无符号的32位整形数。这样调用起来会更加方便。
②FunctionalState NewState:参数类型名为函数状态,只有两个值可供传入。ENABLE-时钟开启,DISABLE-时钟关闭。

2.GPIO口的初始化类型定义结构体

GPIO口的初始化类型定义结构体定义
定义
在这里插入图片描述
解释一下成员属性
①uint16_t GPIO_Pin:应该也是采用了位掩码的方式,赋的值可以直接传入引脚号码如:GPIO_Pin_3,而不是整形数据。
②GPIOSpeed_TypeDef GPIO_Speed:赋的值如:GPIO_Speed_50MHz,在GPIO_Speed后面加一个下划线和具体的数值。(这部分传入的参数或赋的值都是以这种形式。在实际操作时,可以先列出他的属性,GPIO_InitStructure.GPIO_Speed=,再复制粘贴GPIO_Speed,再按ctrl+alt+空格,进行操作提示。)
③GPIOMode_TypeDef GPIO_Mode:赋的值如GPIO_Mode_Out_PP。
即类型定义结构体的三板斧是引脚号码、速度和输入输出模式。

3.GPIO口的类型定义结构体

定义
在这里插入图片描述

4.GPIO口的初始化函数

①定义
在这里插入图片描述
②参数实例

在这里插入图片描述

定义太复杂了,在这里简单解释一下:就是将初始化结构体的地址和结构体地址综合起来。GPIOx参数指定了目标GPIO端口的引脚名称(是GPIOA,GPIOB还是GPIOC…),而GPIO_InitStruct则提供了是它已初始好的三个成员属性。
即第一个GPIO口的类型定义结构体参数传入的是A、B、C…的哪种类型的引脚,而第二个GPIO口的初始化类型定义结构体参数提供的是它的已配置好的成员属性。
待会GPIO_WriteBit(GPIO_TypeDef GPIOx, uint16_t GPIO_Pin, BitAction B)等函数调用的时候两者都要用。

(二)实验

1.标准库实现LED灯闪烁

(1)代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"int main(){	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启外设GPIOA的时钟GPIO_InitTypeDef GPIO_InitStructure;   				//调用库函数的中封装好的具体引脚结构体//分别给结构体的三个成员属性赋初值GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 		//配置端口为推挽输出模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;             //启用0号端口GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     //端口输出速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);    //GPIOA的0号口配置完成,准备调试它的高低电平。while(1){GPIO_ResetBits(GPIOA,GPIO_Pin_0);   //设置A0端口为低电平Delay_s(1);GPIO_SetBits(GPIOA,GPIO_Pin_0);		//设置A0端口为高电平Delay_s(1);}
}
(2)Proteus仿真

注意:
在这里插入图片描述
得将外时钟频率设置为70Mhz,时钟比例设置为8倍。

在这里插入图片描述

(3)实验现象

2024_05_09_001

2.标准库实现LED流水灯

(1)代码

在这里插入图片描述

(2)Proteus仿真

在这里插入图片描述

(3)实验现象

20240509_002

3.用STM32发送数据,并用串口助手接收

(1)代码

①main.c文件

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Serial.h"int main()
{	Serial_Init();	char String[]="hello windons!\r\n";while(1){Serial_SendString(String);Delay_s(1);              						  						//间隔1s发送}
}

②Serial.c文件

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);	//打开USART1外设的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//因为要用到GPIOA引脚,所以打开GPIOA的时钟GPIO_InitTypeDef GPIO_InitStructure;  					//用自带的通用输出口结构体,实例化了一个结构体变量GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  			//数据发送,选择复用推挽输出模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);					//配置好引脚输入输出模式USART_InitTypeDef USART_InitStructure;//引出该结构体的所有属性,进行赋值。USART_InitStructure.USART_BaudRate=9600;          									//波特率USART_InitStructure.USART_WordLength=USART_WordLength_8b;         					//不需要校验选择8bit的字长,如果需要一位奇偶校验位,则选择9bit的字长USART_InitStructure.USART_StopBits=USART_StopBits_1;         						//选择一位停止位。USART_InitStructure.USART_Parity=USART_Parity_No;                      				//奇偶性:奇偶校验,选择不校验。odd是奇校验,even是偶校验。USART_InitStructure.USART_Mode=USART_Mode_Tx;           							//选择发送模式 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; 		//硬件流控制:选择无流控制USART_Init(USART1,&USART_InitStructure);					//配置好USART1外设的模式USART_Cmd(USART1,ENABLE);									//使能USART1,串口开始运行。第一个参数是要操作的USART外设,第二个参数是指定是否使能该外设
}void Serial_SendByte(uint8_t Byte)     //int8_t代表字符型
{USART_SendData(USART1,Byte);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET)  //USART_GetFlagStatus(USART1,USART_FLAG_TXE)这个函数的返回值先简单地理解为:数据已经发送了,返回SET;数据还没有发送,返回RESET。{;}
}void Serial_SendString(char *String)				//发送一个字符数组
{uint8_t i;for(i=0;String[i]!='\0';i++){Serial_SendByte(String[i]);}
}
(2)串口助手接收

在这里插入图片描述

4.串口查询方式点亮LED灯

(1)代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "LED.h"
#include <string.h>uint8_t Rdata;int main()
{LED_Init();			//LED初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//因为要用到GPIOA引脚,所以打开GPIOA的时钟GPIO_InitTypeDef GPIO_InitStructure;  					//用自带的通用输出口结构体,实例化了一个结构体变量GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  			//数据发送,选择复用推挽输出模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);					//配置好引脚输入输出模式RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);	//打开USART1外设的时钟GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  			//数据接收,选择上拉输入模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init (GPIOA,&GPIO_InitStructure);					//配置好引脚输入输出模式USART_InitTypeDef USART_InitStructure;//引出该结构体的所有属性,进行赋值。USART_InitStructure.USART_BaudRate=9600;          																		//波特率USART_InitStructure.USART_WordLength=USART_WordLength_8b;         									//不需要校验选择8bit的字长,如果需要一位奇偶校验位,则选择9bit的字长USART_InitStructure.USART_StopBits=USART_StopBits_1;         													//选择一位停止位。USART_InitStructure.USART_Parity=USART_Parity_No;                      											//奇偶性:奇偶校验,选择不校验。odd是奇校验,even是偶校验。USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;           							//选择发送和接收模式 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; 		//硬件流控制:选择无流控制USART_Init(USART1,&USART_InitStructure);					//配置好USART1外设的模式USART_Cmd (USART1,ENABLE);									//使能USART1,串口开始运行。第一个参数是要操作的USART外设,第二个参数是指定是否使能该外设while (1){while (	USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);Rdata = USART_ReceiveData(USART1);if (Rdata == '1'){LED1_ON();}if (Rdata == '0'){LED1_OFF();}while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//USART_GetFlagStatus(USART1,USART_FLAG_TXE)这个函数的返回值先简单地理解为:数据已经发送了,返回SET;数据还没有发送,返回RESET。}
}
(2)实验现象

20240512_02

三、keil波形

1.配置合适的Xtal(External Crystal Oscillator)外部晶振

在这里插入图片描述

2.输入正确的芯片参数

在这里插入图片描述

3.进入波形仿真界面

在这里插入图片描述

这里第四步输入对应的波形源要重点强调。
在这里我配置的是PA1和PA9引脚,那么创建波形源的时候就分别输入:PORTA.1和PORTA.9即可。如果你按上述输入了,报错。

在这里插入图片描述
那么说明你步骤2的四个参数,没有配置正确,请按步骤2的要求重新配置。

4.仿真波形

在这里插入图片描述
在我实验(二)3.用STM32发送数据,并用串口助手接收代码中,PA9口的波形应该是起伏变化的,PA1时不变的。在我实验(二)4.串口查询方式点亮LED灯中,PA1应该是起伏变化的。但是我的两个实验的波形都如上图所示,我也想了许多办法去改进,但都败不旋踵。我估计应该是晶振的问题,我也改了晶振的值但仍得不到波形。这确实很奇怪,因为我的实验现象是正确的,波形仿真却有问题。还望大佬能够不吝赐教,进行指证。

四、心得体会

串口通信是单片机学习十分必不可少的一环,它关系着单片机之间的数据能否顺利的发送和接收,实现机器与机器的数据交换与数据共享。
在本节使用STM32F103C8T6的串口通信时,我主要遇到了两个问题。
问题1:我犯了一个致命的错误就是在连接USART1的引脚时,将发送数据引脚P9连接到了转串口模块的TXD上,将接收数据P10连接到了RXD上。即单片机发送端连接到了电脑发送端,单片机接收端连接到了电脑接收端。导致我浪费了一个下午的时间,去怀疑并验证STM芯片是不是坏了、转串口模块是否坏了、引脚是否坏了…这对于初学者来说确实是一个极其容易犯错的步骤。
问题2:我的实验现象是正确的,但是得不到波形,波形一直保持低电平不变。这一点希望阅读本文章的大佬能够指正一下。
总的来说,串口通信的学习,和前面点亮小灯泡的实验具有很多相似之处,都要进行时钟的配置,初始化结构体的实例化,并用初始化结构体进行输入输出模式的配置。这在代码中的体现是十分直观的。但是,串口模块的学习难度,还是要大一点,因为它涉及的是双向数据的传输,还要合理展示,并且它和很多STM32学习模块密切相关,例如:中断、OLED显示屏…

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习数据可视化-04】Pyecharts数据可视化宝典

一、引言 在大数据和信息爆炸的时代&#xff0c;数据可视化成为了信息传递和展示的关键手段。通过直观的图表和图形&#xff0c;我们能够更好地理解数据&#xff0c;挖掘其背后的信息。Pyecharts&#xff0c;作为一款基于Python的数据可视化库&#xff0c;凭借其丰富的图表类型…

代码随想录刷题笔记

目录 四数相加2&#xff08;Leetcode454&#xff09; 四数相加2&#xff08;Leetcode454&#xff09; public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {int cnt 0;Map<Integer,Integer> map new HashMap();/** 这一步用来存 数组1和数…

多模态EDA论文小记

论文地址 该论文主要改进点是&#xff1a;通过动态化局部搜索中每个集群大小&#xff0c;高斯和柯西分布共同产生个体。总的来说改进点不多&#xff0c;当然也可能是笔者还没发现。 局部搜索 划分集群 划分集群有两个策略分别是&#xff1a; 随机生成一个点作为中心点&…

MySQL表死锁查询语句

步骤1&#xff1a;查询表死锁的sql语句&#xff1a; SELECT * FROM information_schema.PROCESSLIST where length(info) >0 ; 或 SELECT * FROM information_schema.INNODB_TRX; 步骤2&#xff1a;删除 kill "对应的线程id"

Dockerfile 基本结构

Dockerfile 是一个文本文件&#xff0c;用于自动化 Docker 镜像的构建过程。这里是一个简单的 Dockerfile 编写步骤&#xff0c;以及一个基本的例子&#xff1a; Dockerfile 基本结构 FROM: 指定基础镜像。RUN: 执行命令。COPY / ADD: 复制文件或目录到镜像中。CMD: 设置容器…

【JVM】Class文件的格式

目录 概述 Class文件的格式 概述 Class文件是JVM的输入&#xff0c;Java虚拟机规范中定义了Class文件的结构。Class文件是JVM实现平台无关、技术无关的基础。 1:Class文件是一组以8字节为单位的字节流&#xff0c;各个数据项目按顺序紧凑排列 2:对于占用空间大于8字节的数据…

16 华三数据中心最流行的技术 M-LAG

STP和MTP&#xff08;第二十二课&#xff09;-CSDN博客 VRRP技术和浮动路由(第二十六课)_vrrp 浮动路由-CSDN博客 VRRP DHCP ACL NAT 网络核心路由技术综述 (第十课)-CSDN博客 04 交换机的IRF的配置-CSDN博客 1 M-LAG AI介绍 M-LAG&#xff08;Multi-Chassis Link Aggrega…

其他的 框架安全:Apache Solr 远程代码漏洞.(CVE-2019-0193)

什么是 Apache Solr Apache Solr是一个开源的搜索服务&#xff0c;便用Java语言开发&#xff0c;主要基于 HTTP 和ApacheLucene 实现的。Sor是一个高性能&#xff0c;采用Java5开发&#xff0c;基于Lucene的全文搜索服务器。 目录&#xff1a; 什么是 Apache Solr 生成的漏…

python设计模式-策略模式

from abc import abstractmethod,ABCclass BaseProcess(ABC):abstractmethoddef process_file(self,filepath):passclass ExcelProcess(BaseProcess):def process_file(self,filepath):print("处理excel 方法")class CsvProcess(BaseProcess):def process_file(self,…

java final关键字

在Java中,final 是一个关键字,用于表示一个最终变量、方法或类。它可以用于不同的上下文中,具有不同的含义: 1. 最终变量: 用 final 修饰的变量表示一个常量,一旦被赋值后就不能再改变。如果是基本数据类型,一旦赋值后就不能再更改其值。如果是引用类型,一旦引用被初…

基于yolov5+streamlit目标检测演示系统设计

YOLOv5与Streamlit&#xff1a;智能目标检测可视化展示介绍 随着人工智能技术的飞速发展&#xff0c;目标检测技术已成为推动智能化社会进步的关键技术之一。在众多目标检测算法中&#xff0c;YOLOv5以其卓越的性能和实时性&#xff0c;成为了业界的佼佼者。与此同时&#xff…

vben框架是什么

Vben是一个基于Vue3.0、Vite、Ant-Design-Vue、TypeScript的后台解决方案&#xff0c;目标是为开发中大型项目提供开箱即用的解决方案。它包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。项目会使用前端较新的技术栈&#xff0c;可以作为项目的…

Spring Boot 集成 sa-token 实践教程

Spring Boot 集成 sa-token 实践教程 sa-token 是一个轻量级且功能强大的权限认证框架&#xff0c;它基于Java语言&#xff0c;专为Java开发者设计&#xff0c;以简化权限管理的复杂性。在Spring Boot项目中集成sa-token&#xff0c;可以快速实现会话管理、权限控制等功能。本文…

程序员必读书单(CSDN专享)

大家好&#xff0c;我是王有志&#xff0c;一个分享硬核 Java 技术的金融摸鱼侠&#xff0c;欢迎大家加入 Java 人自己的交流群“共同富裕的 Java 人”。 今天是一篇分享资源的汇总&#xff0c;近半年来我总计分享了 202 本&#xff08;将近 10G &#xff09;的计算机领域著作…

智慧法治:AI技术如何赋能法律行业创新

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

Git 的原理与使用(上)

Git是一个分布式版本控制系统&#xff0c;它被广泛用于协作开发和管理软件项目。开发人员可以通过Git来跟踪文件的变化、协调工作、并管理项目的不同版本。 Git允许用户在不同的分支上开发新功能&#xff0c;然后合并这些分支并确保团队成员之间的工作协调一致。此外&#xff…

如何使用Java和高德地图API将经纬度转换为地理位置信息

在开发涉及地图和位置服务的应用时&#xff0c;我们经常需要将GPS设备提供的经纬度坐标转换成人类可读的地理位置。本文将介绍如何使用Java语言和高德地图API来实现这一功能。 开发环境准备 Java环境&#xff1a;确保你的开发环境中已安装Java。高德地图API密钥&#xff1a;访…

OpenCV 滤波方法总结

1.概述 在深度学习出现之前&#xff0c;主要有中值滤波、均值滤波、高斯滤波等. 2.理论对比 3.代码实现 #include <iostream> #include <opencv2/opencv.hpp>int main(int argc, char** argv) {if(argc ! 2) {std::cerr << "Usage: " << a…

微信小程序踩坑,skyline模式下,scroll-view下面的一级元素设置margin中的auto无效,具体数据有效

开发工具版本 基础库 开启skyline渲染调试 问题描述 skyline模式下,scroll-view下面的一级元素的margin写auto的值是没有效果的(二级元素margin写auto是有效果的),关闭这个模式就正常显示 演示效果图 父元素的宽度和高度效果(宽度是750rpx,宽度占满的) 一级元素宽度和css效果…

【2024最新华为OD-C卷试题汇总】API集群访问频次统计(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 文章目录 前…