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;凭借其丰富的图表类型…

多模态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"

【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 生成的漏…

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

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

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…

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

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

Python游戏制作大师,Pygame库的深度探索与实践

写在前言 hello&#xff0c;大家好&#xff0c;我是一点&#xff0c;专注于Python编程&#xff0c;如果你也对感Python感兴趣&#xff0c;欢迎关注交流。 希望可以持续更新一些有意思的文章&#xff0c;如果觉得还不错&#xff0c;欢迎点赞关注&#xff0c;有啥想说的&#x…

笔记3:torch训练测试VGG网络

&#xff08;1&#xff09;利用Netron查看网络实际情况 上图链接 python生成上图代码如下&#xff0c;其中GETVGGnet是搭建VGG网络的程序GETVGGnet.py&#xff0c;VGGnet是该程序中的搭建网络类。netron是需要pip安装的可视化库&#xff0c;注意do_constant_foldingFalse可以防…

【简单介绍下Sass】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Windows 查找端口号关闭端口号关闭进程的操作流程

Windows 查找端口号关闭端口号关闭进程 8000为端口号 1.查看端口占用程序的ID号 netstat -aon|findstr "8000"比如结果是5684 2.查看ID对应的程序进程 tasklist|findstr "6884"3.关闭进程 taskkill -PID 6884 -F成功: 已终止 PID 为 5684 的进程。

华为机试打卡 HJ2 计算某字符出现次数

要机试了&#xff0c;华孝子求捞&#xff0c;功德 描述 写出一个程序&#xff0c;接受一个由字母、数字和空格组成的字符串&#xff0c;和一个字符&#xff0c;然后输出输入字符串中该字符的出现次数。&#xff08;不区分大小写字母&#xff09; 数据范围&#xff1a; 1≤&a…

【复杂网络】如何用简易通俗的方式快速理解什么是“相对重要节点挖掘”?

什么是相对重要节点&#xff1f; 一、相对重要节点的定义二、如何区分相对重要节点与重要节点&#xff1f;1. 相对重要性与节点相似性2. 识别相对重要节点的两个阶段第一阶段&#xff1a;个体重要性值的计算第二阶段&#xff1a;累积重要性值的计算 三、相对重要节点挖掘算法1.…

条件变量解决同步问题之打印金鱼

说明 本代码为jyy老师上课演示条件变量解决同步问题示例(本人只做记录与分享) 本人未使用老师封装的POSIX线程库, 直接在单文件中调试并注释 问题描述 有三类线程 T1 若干: 死循环打印< T2 若干: 死循环打印> T3 若干: 死循环打印_ 任务: 对线程同步&#xff0c;使得屏幕…

ASP.NET一种基于C2C模式的网上购物系统的设计与实现

摘 要 网络购物已经慢慢地从一个新鲜的事物逐渐变成日常生活的一部分&#xff0c;以其特殊的优势而逐渐深入人心。本课题是设计开发一种基于C2C模式的网上购物系统。让各用户使用浏览器进行商品浏览。注册用户可以轻松的展示自己的网络商店&#xff0c;能对自己的用户信息进行…