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.xdnf.cn/news/1420728.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C++小程序:同一路由器下两台计算机间简单通信(2/2)——客户端

客户端的程序结构前半部分与服务器端基本相同&#xff0c;后半部分也相对简单。相关函数的解释可以参考前文服务器端的内容。有关客户端的内容除个别地方外&#xff0c;就不再做长篇大论的解释。强调一点&#xff0c;如果将此程序移到其它电脑上运行&#xff0c;编译需要releas…

Vue路由拆分

1.在src下建立router&#xff0c;在router中建立文件index 2.将main.js中部分内容复制 App <template> <div><a href"#/friend">朋友</a><br><a href"#/info">信息</a><br><a href"#/music&quo…

支持播放h265的插件

插件源码地址&#xff1a;GitCode - 开发者的代码家园https://gitcode.com/mirrors/nanguantong/flv-h265.js/overview 1. 下载代码 运行以下命令 npm i npm run build npm run build 后生成 flv.min.js 文件&#xff0c;引入使用 2. 调用 js 文件&#xff1a; let flvj…

完全背包问题(c++)

完全背包问题 当前有 N 种物品&#xff0c;第 i 种物品的体积是 ci​&#xff0c;价值是 wi​。 每种物品的数量都是无限的&#xff0c;可以选择任意数量放入背包。 现有容量为 V 的背包&#xff0c;请你放入若干物品&#xff0c;使总体积不超过 V&#xff0c;并且总价值尽可…

msvcp140dll怎么修复,分享5种有效的解决方法

MSVCP140.dll文件丢失这一现象究竟是何缘由&#xff0c;又会引发哪些令人头疼的问题呢&#xff1f;在探索这个问题的答案之前&#xff0c;我们先来深入了解这个神秘的DLL文件。MSVCP140.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它扮演着至关重要的…

景源畅信:抖音小店的商品怎么同步到橱窗?

在数字营销的海洋中&#xff0c;抖音小店与橱窗的同步操作无疑是商家们关注的焦点。这不仅能增加商品的曝光度&#xff0c;还能提高交易的可能性。那么&#xff0c;如何将抖音小店的商品同步到橱窗呢? 一、核心步骤解析 要实现商品从抖音小店同步到橱窗&#xff0c;你需要确保…

汇昌联信:做拼多多网点需要具备什么能力?

在当前电商行业高速发展的背景下&#xff0c;拼多多以其独特的商业模式迅速崛起&#xff0c;成为众多创业者和商家关注的焦点。想要运营一家成功的拼多多网点&#xff0c;不仅需要对平台规则有深入的了解&#xff0c;还需要具备多方面的能力。这些能力是确保网点稳定运营并实现…

VBA_NZ系列工具NZ07:日期录入控件

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…

Multisim 14 常见电子仪器的使用和Multisim的使用

multisim multisim&#xff0c;即电子电路仿真设计软件。Multisim是美国国家仪器&#xff08;NI&#xff09;有限公司推出的以Windows为基础的仿真工具&#xff0c;适用于板级的模拟/数字电路板的设计工作。它包含了电路原理图的图形输入、电路硬件描述语言输入方式&#xff0…

利用PS在不伤背景的前提下根据颜色去除图像上不想要的内容

下面为一个例子&#xff0c;去除图像上红色的虚线 Step1.用套索工具框选带有颜色的部分 Step2.切换到魔术棒工具&#xff0c;上端选项中&#xff0c;点击与选区交叉&#xff0c;连续这一项不要勾选 Step3.在需要去除的部分点击一下即可在框选范围内选中所有同颜色的区域&#x…

# 从浅入深 学习 SpringCloud 微服务架构(十七)--Spring Cloud config(1)

从浅入深 学习 SpringCloud 微服务架构&#xff08;十七&#xff09;–Spring Cloud config&#xff08;1&#xff09; 一、配置中心的 概述 1、配置中心概述 对于传统的单体应用而言&#xff0c;常使用配置文件来管理所有配置&#xff0c;比如 SpringBoot 的 application.y…

事件高级。

一、注册事件&#xff08;绑定事件&#xff09; 就是给元素添加事件 注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 1 传统注册方式 方法监听注册事件 2、 addEventListener 事件监听方式 里面的事件类型是字符串&#xff0c;必定加引号&#xff0c;而且不带o…

VScode 修改 Markdown Preview Enhanced 主题与字体

VScode 修改 Markdown Preview Enhanced 主题与字体 1. 修改前后效果对比2. 修改主题2.1 更改默认主题2.2 修改背景色 3. 修改字体 VS Code基础入门使用可查看&#xff1a; VS Code 基础入门使用&#xff08;配置&#xff09;教程 其他Vs Code 配置可关注查看&#xff1a; Vs C…

C++:9.scanf扩展——原来这么好用!

——scanf&#xff1a;我**不常用了&#xff1f; 有一天看到了一道题&#xff1a; C 输入一个时间&#xff0c;输出它属于&#xff0c;白天&#xff0c;下午还是黑夜。 输入样例&#xff1a; 15:20 00:00 13:14 05:20 11:45 14:00 ……??? 大胆题目小瞧我的编程水平!!!!!…

[图解]实现领域驱动设计译文暴露的问题02

0 00:00:00,500 --> 00:00:02,190 今天呢&#xff0c;我们 1 00:00:02,470 --> 00:00:04,820 继续来谈一谈 2 00:00:05,150 --> 00:00:07,790 实现领域驱动设计的中译本 3 00:00:08,630 --> 00:00:09,690 的译文 4 00:00:10,070 --> 00:00:11,710 暴露的问题…

BUU-二维码

题目 解题 打开是一张图片&#xff0c;扫描二维码后显示 secret is here 一时没有思路&#xff0c;看别人的wp https://blog.csdn.net/wusimin432503/article/details/125692459https://blog.csdn.net/weixin_45728231/article/details/120988424?spm1001.2101.3001.6661.1…

1.1. 离散时间鞅-条件期望

1.1. 离散时间鞅-条件期望 条件期望1. 条件期望的定义1.1. 条件期望的定义1.2. 条件期望的存在唯一性 2. 条件期望的示例2.1. X ∈ F X \in \mathcal{F} X∈F&#xff0c; X X X与 F \mathcal{F} F独立的情形2.2. X X X是有限 σ \sigma σ代数情形2.3. X X X是随机变量生成…

基于springboot的篮球联盟管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

物流单打印机怎么调格式距离,佳易王物流托运单管理系统软件打印单据左边距调节教程

物流单打印机怎么调格式距离&#xff0c;佳易王物流托运单管理系统软件打印单据左边距调节教程 一、前言 以下软件操作教程以&#xff0c;佳易王物流单打印管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、佳易王物流单管理系统打印…

HTTP和HTTPS之间有何区别?

每次使用互联网的时候&#xff0c;您有没有发现网址有两种格式呢&#xff1f;一种以http://开头&#xff0c;一种https://开头。看似相差不大&#xff0c;那么它们之间有何区别呢&#xff1f;HTTP和HTTPS之间存在多个显著的区别&#xff0c;主要体现在以下几个方面&#xff1a;…