STM32——串口

1、串口是什么

串口呢,作为硬件调试的时候,是很有用的,我觉得搞嵌入式是经常和串口打交道的

串口(Serial Port)是一种用于计算机和外部设备之间进行数据通信的接口。它通过串行通信方式传输数据,即一次只传输一个比特(位)。串口通信在早期的计算机系统中非常常见,用于连接键盘、鼠标、调制解调器、打印机等外部设备。

串口的主要特点包括:

  1. 简单性:串口通信协议相对简单,易于实现。
  2. 低成本:串口通信的硬件成本较低,适合一些低成本的应用。
  3. 广泛应用:虽然现代计算机更多地使用USB等高速接口,但串口在工业控制、嵌入式系统和调试设备中仍然广泛应用。

常见的串口类型包括 RS-232、RS-485 和 RS-422。RS-232 是最常见的串口标准,广泛用于个人计算机和各种嵌入式系统中。

总之,串口是一种重要的通信接口,尽管在现代计算机中不再那么常见,但在许多专业和工业应用中仍然非常有用。

2、串口的时序

在很多时候,我们经常忘记串口作为一种通信协议,是有自己的时序的,不过在使用串口的过程中,时序的特点以及需求,已经被波特率替代了,所以我们了解串口,不需要去了解他的时序,了解波特率就可以了

串口通信确实有时序(timing),这是因为串口通信是基于时间的。在串口通信中,数据以一定的速率(波特率,单位为比特每秒,bps)发送和接收。波特率决定了每秒钟传输的比特数。

以下是串口通信中的一些关键时序参数:

  1. 波特率(Baud Rate):决定了数据传输的速度。常见的波特率包括 9600 bps、19200 bps、115200 bps 等。
  2. 数据位(Data Bits):通常是 8 位,表示每个字符的长度。
  3. 停止位(Stop Bits):通常是 1 位或 2 位,用于标识一个字符的结束。
  4. 奇偶校验位(Parity Bit):用于检测传输错误,可以是无校验(None)、奇校验(Odd)或偶校验(Even)。

在串口通信中,这些参数需要在发送方和接收方之间一致,才能正确地进行数据传输。如果这些参数不匹配,可能会导致数据传输错误或通信失败。

总之,串口通信有明确的时序要求,这些时序参数确保数据在发送和接收端之间能够正确同步和解析。

3、自己生成串口时序

波特率: 9600 bps

数据位: 8 位

停止位: 1 位

奇偶校验位: Odd

时序示意图:

  1. Start Bit(开始位):高电平,表示新的数据传输开始(1 bit)
  2. Data Bits(数据位):8 个比特,表示要传输的数据(8 bits)
    • 高电平表示 1,低电平表示 0
  3. Parity Bit(奇偶校验位):1 个比特,用于检测传输错误(1 bit)
    • 高电平表示奇校验,低电平表示偶校验
  4. Stop Bit(停止位):1 个比特,表示数据传输结束(1 bit)
    • 高电平表示停止位

时序示例:

假设要传输的数据为 0x12(00010010),波特率为 9600 bps。

  1. Start Bit:高电平(1 bit)
  2. Data Bits
    • 00010010(8 bits)
      • 高电平(1):0
      • 低电平(0):0
      • 高电平(1):0
      • 低电平(0):1
      • 高电平(1):0
      • 低电平(0):0
      • 高电平(1):1
      • 低电平(0):0
  3. Parity Bit:高电平(1 bit)
    • 奇校验,因为数据中有奇数个 1
  4. Stop Bit:高电平(1 bit)

总共传输 11 个比特(1 + 8 + 1 + 1),每秒钟传输 9600 个比特。

所以呢,数据位很简单啦~

奇偶校验位虽然比较复杂,但是呢,一般不用,所以

奇偶校验位(Parity Bit)是串口传输中的一种错误检测机制,它用于检测传输数据中的错误。奇偶校验位是一种简单的错误检测方法,它通过在数据中添加一个额外的比特来检测数据是否包含错误。

奇偶校验位的计算过程如下:

  1. 计算数据中 1 的个数(Odd Count):将要传输的数据中的 1 个数计数。
  2. 如果 Odd Count 是奇数,那么添加一个 1 作为奇校验位(Odd Parity Bit)。
  3. 如果 Odd Count 是偶数,那么添加一个 0 作为偶校验位(Even Parity Bit)。

奇偶校验位的作用是:

  1. 检测数据中的错误:如果数据中包含错误,奇偶校验位将不同于预期的值。
  2. 检测数据的完整性:如果数据中缺少或添加了比特,奇偶校验位将不同于预期的值。

奇偶校验位的类型有两种:

  1. 奇校验(Odd Parity):如果数据中 1 的个数是奇数,那么添加一个 1 作为奇校验位。
  2. 偶校验(Even Parity):如果数据中 1 的个数是偶数,那么添加一个 0 作为偶校验位。

奇偶校验位的优缺点:

优点:

  • 简单易行,计算成本低
  • 可以检测简单的错误,例如数据中缺少或添加了比特

缺点:

  • 不可靠,无法检测复杂的错误,例如数据中的某些比特被损坏
  • 可能会产生误报,例如数据中包含多个错误时,奇偶校验位可能不同于预期的值

总的来说,奇偶校验位是一种简单的错误检测方法,但它并不是 foolproof 的解决方案。在实际应用中,通常会使用其他错误检测和纠正方法来确保数据的可靠传输。

4、STM32——配置

各位,请把目光集中,重点来了

其实呢串口到现在已经发展出了很多不同的通信协议,咱们主要还是以stm32的为主

首先,串口本身可以是全双工、半双工或单工,取决于具体的硬件实现和通信协议。

串口的数据线一般为两条一条TX输出一条RX接受

  

如图~串口的特点呢就是一方的RX————TX另一方的

电源呢随意,能通电就行,注意共地就ok

4.1、通信协议——TTL

 

串口作为一种通信协议,又有着不同的标准,stm32一般使用TTL协议

5VTTL电平标准

2.4V~5V:逻辑1。

0~0.4V: 逻辑0。

TTL信号的抗干扰能力较差,所以其通信距离很短,一般只能用于一个电路板上的两个不同芯片之间的通信。 

4.2、stm32的寄存器

 

重点呢还是这张图;

其实呢仔细一看,发送和接受的都有着同样的配置,唯一的区别呢就是接收多了一个唤醒单元

 4.3、配置流程(寄存器)

  1. 通过在USART_CR1寄存器上置位UE位来激活USART
  2. 编程USART_CR1的M位来定义字长
  3. 在USART_CR2中编程停止位的位长
  4. 如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器,关于DMA下期再详细讲解。
  5. 利用USART_BRR寄存器选择要求的波特率。
  6. 设置USART_CR1中的TE位,发送一个空闲帧帧(一个数据帧长度的高电平)作为第一次数据发送
  7. 把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。
  8. 在USART_DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束(移位寄存器中的数据全部发送完毕)。当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。

4.4、标准库源码

usart.h

#ifndef __USART_H
#define __USART_H

#include "stm32f10x.h"                  // Device header

void Usart1_Init(int baud);
void Usart1_SendByte(u8 ch);
void Usart1_SendStr(u8* str, u32 len);

#endif

usart.c

#include "stm32f10x.h"                  // Device header
#include "usart.h"
#include "stdio.h"

#define USART1_IDLE_ON
//启动文件 startup_stm32f10x_md.s 中
//中断处理函数
//RXNE标志,每次收到一个字节时触发中断

//接收数据
//解析数据
//执行指令
u8 g_U1_RecvBuf[32] = "";
u8 g_U1_RecvFlag = 0;//接收完成标志 告诉main


#ifndef USART1_IDLE_ON
//定长数据 4个字节
void USART1_IRQHandler(void)
{
	static int index = 0;
	if(SET == USART_GetITStatus(USART1, USART_IT_RXNE))//检测中断源
	{
		if(0 == g_U1_RecvFlag){
			g_U1_RecvBuf[index] = USART_ReceiveData(USART1);
			index++;
			if(index >= 4){
				g_U1_RecvFlag = 1;
				index = 0;
			}
		}else{
			USART_ReceiveData(USART1);
		}
	}

}

#else 
//不定长
//1.规定接收字符 \r\n AT指令
//2.使用空闲中断 IDLE -- 上一帧数据后,一帧时间内没有收到新的一帧,则视作空闲事件
//3.超时检测 收到一帧后,定时器定时10ms,接收接收完成,触发定时器中断视作接收完成,收到新数据,清空计数器
void USART1_IRQHandler(void)
{
	static int index = 0;
	if(SET == USART_GetITStatus(USART1, USART_IT_RXNE))//检测中断源
	{
		if(0 == g_U1_RecvFlag){
			g_U1_RecvBuf[index] = USART_ReceiveData(USART1);
			index++;
		}else{
			USART_ReceiveData(USART1);
		}
	}
	if(SET == USART_GetITStatus(USART1, USART_IT_IDLE))//空闲中断
	{
		g_U1_RecvFlag = 1;
		index = 0;
		
		//清除中断标志位
		USART1->SR;
		USART1->DR;
	}

}


#endif

//给printf进行重定向,fputc
int fputc(int ch, FILE* file)
{
	Usart1_SendByte(ch);
	return ch;
}

//USART1
//PA9 -- TX
//PA10 -- RX 
void Usart1_Init(int baud)
{
	//打开时钟 GPIOA,USART1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
	
	//PA9 -- 复用推挽输出
	GPIO_InitTypeDef gpio_struct;
	gpio_struct.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio_struct.GPIO_Pin = GPIO_Pin_9;
	gpio_struct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpio_struct);
	
	//PA10 -- 浮空输入
	gpio_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio_struct.GPIO_Pin = GPIO_Pin_10;
	GPIO_Init(GPIOA, &gpio_struct);
	
	//USART1 的初始化
	USART_InitTypeDef usart_struct;
	usart_struct.USART_BaudRate = baud; //波特率
	usart_struct.USART_WordLength = USART_WordLength_8b; //8位数据位长度
	usart_struct.USART_Parity = USART_Parity_No; //无校验
	usart_struct.USART_StopBits = USART_StopBits_1; //1位停止位
	usart_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
	usart_struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收,发送使能
	USART_Init(USART1, &usart_struct);
	
	//USART使能中断
	//接收中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
#ifdef USART1_IDLE_ON 
	//空闲中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
#endif	

	//NVIC设置USART对应的中断通道
	NVIC_InitTypeDef nvic_struct;
	nvic_struct.NVIC_IRQChannel = USART1_IRQn; //中断通道 再头文件stm32f10x.h 200多行
	nvic_struct.NVIC_IRQChannelCmd = ENABLE;   //通道使能
	nvic_struct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
	nvic_struct.NVIC_IRQChannelSubPriority = 1;		   //响应优先级	 
	NVIC_Init(&nvic_struct);
	
	
	//USART 使能
	USART_Cmd(USART1, ENABLE);

}
void Usart1_SendByte(u8 ch)
{
	USART_SendData(USART1, ch);//发送
	//等待发送 
	//TXE -- 发送数据寄存器空标志位 -- 数据被发送移位寄存器取走就会 置一
	while(SET != USART_GetFlagStatus(USART1, USART_FLAG_TXE));
}
void Usart1_SendStr(u8* str, u32 len)
{
	while(len--)
	{
		Usart1_SendByte(*str);
		str++;
	}
}

 

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

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

相关文章

sparkSQL的UDF,最常用的regeister方式自定义函数和udf注册方式定义UDF函数 (详细讲解)

- UDF:一对一的函数【User Defined Functions】 - substr、split、concat、instr、length、from_unixtime - UDAF:多对一的函数【User Defined Aggregation Functions】 聚合函数 - count、sum、max、min、avg、collect_set/list - UDTF:…

水库大坝安全监测预警方法

一、监测目标 为了确保水库大坝的结构安全性和运行稳定性,我们需要采取一系列措施来预防和减少因自然灾害或其他潜在因素所引发的灾害损失。这不仅有助于保障广大人民群众的生命财产安全,还能确保水资源的合理利用和可持续发展。通过加强大坝的监测和维护…

Java:网络原理-TCP/IP

1.应用层 主要涉及两种情况: (1)使用大佬们已经创建好的应用层协议. (2)自己定义应用层协议. [1]明确前后端交互过程中,需要传递哪些信息. 比如开发一个外卖软件,展示"商家列表" 此处就需要先确定传递的信息是啥. a.请求:用户id; 用户所处的位置 b.响应:商家…

C++类的多重继承演示

一个派生类可以继承多个基类 以下代码演示派生类zzj继承两个基类people、student #include <iostream>using namespace std;class people { private:int m_age; public:people(int age);void print();~people(); };people::people(int age) {cout << "peopl…

信息安全建设方案,网络安全等保测评方案,等保技术解决方案,等保总体实施方案(Word原件)

1 概述 1.1 项目简介 1.2 测评依据 2 被测信息系统情况 2.1 定级情况 2.2 承载的业务情况 2.3 网络结构 2.4 被测对象资产 2.5 上次测评问题整改情况说明 3 测评范围与方法 3.1 测评指标 3.1.1 安全通用要求指标 3.1.2 安全扩展要求指标 3.1.3 其他安全要求指标 3.1.4 不适用安…

vue3学习---案例实现学习

目录 一&#xff0c;京东秒杀导航栏 1&#xff0c;静态样式展示 2&#xff0c;设计步骤 1&#xff0c;html骨架 2&#xff0c;css样式设计 3&#xff0c;vue3动态样式设计 1&#xff0c;v-for使用 1&#xff0c;先在js模块做如下准备 2&#xff0c;v-for遍历 2&#xff…

架构师:如何提高web网站的请求并发响应量?

文章目录 一、提出问题二、相关概念三、如何提高网站请求响应能力&#xff1f;四、负载均衡有那些方式&#xff1f;五、常用微服务架构图及推荐书籍 一、提出问题 今天&#xff0c;突然想到一个问题&#xff0c;双十一&#xff0c;那些电商网站的并发量是多大&#xff1f; 简…

中酱:健康生活的先行者

中酱&#xff1a;健康生活的先行者 在追求品质生活的道路上&#xff0c;健康是永恒的主题。每一个关乎健康的选择&#xff0c;都像是为生活点亮一盏明灯&#xff0c;指引我们走向更美好的生活。而在饮食这个与健康息息相关的领域&#xff0c;调味品的选择至关重要。中酱 —— 作…

使用CentOS宝塔面板docker搭建EasyTier内网穿透服务

0. 前言 EasyTier是一个简单、安全、去中心化的内网穿透 VPN 组网方案&#xff0c;部署方便&#xff0c;支持 MacOS/Linux/Windows/FreeBSD/Android平台&#xff0c;而且作者搭建了一个公共服务器&#xff0c;不想折腾自建服务&#xff0c;可以使用默认的公共服务器地址 tcp:/…

如何以开源加速AI企业落地,红帽带来新解法

CSDN 看到&#xff0c;生成式 AI 的火爆正在引发计算、开发、交互三大范式全面的升级和转换&#xff0c;全行业或将迎来一次全新的科技变革周期&#xff0c;可能比移动与云计算变革更加剧烈。不过 AI 经历了追求千亿模型效果和芯片、集群硬件的军备竞赛后&#xff0c;如何真正落…

计算机毕业设计Python+图神经网络手机推荐系统 手机价格预测 手机可视化 手机数据分析 手机爬虫 Django Flask Spark 知识图谱

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【C语言】分支和循环详解(下)猜数字游戏

与诸君共进步&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 文章目录 1. 随机数的生成2. 猜数字小游戏的实现 1. 随机数的生成 掌握了前⾯学习的这些知识&#xff0c;我们就可以写⼀些稍微有趣的代码了&#xff0c;⽐如&#xff1a; 写⼀个猜数字游戏 游戏要求…

iOS灵动岛动画小组件怎么播放动画

这个灵动岛相关的展示位置分几个地方&#xff1a; 紧凑型&#xff0c;最小化&#xff0c;扩展型&#xff0c;还有锁屏位置 我们先来看一下我这边实现的动画效果 demo下载&#xff1a; iOS灵动岛GIF动画 灵动岛样式 灵动岛有三种渲染模式&#xff1a; 第一种是 紧凑型&…

西门子KTP系列HMI用户自定义弹窗-多弹窗共用

接上一个文章内容《西门子KTP系列HMI用户自定义弹窗》西门子KTP系列HMI用户自定义弹窗-CSDN博客 当我需要别的操作并且需要弹窗时&#xff0c;整个弹窗的内容和变量都需要重复重新绑定&#xff1b;如下图所示&#xff1a; 由上图可看出当前的自定义弹窗有以下缺点&#xff1a; …

Unity使用Spine导致设备发烫

spine制作过程中&#xff0c;美术同学使用裁剪技术 将一个特效文件做固定范围显示&#xff0c;实际上非常消耗CPU算力。 解决办法&#xff1a; 交给程序来实现裁剪&#xff0c;只要加Mask组件即可

您与此网站之间建立的连接不安全解决方法

如果你打开网站&#xff0c;地址栏有警告&#xff0c;点进去是这样的提示&#xff1a;您与此网站之间建立的连接不安全&#xff0c;了解详细信息。 请勿在此网站上输入任何敏感信息&#xff08;例如密码或信用卡信息&#xff09;&#xff0c;因为攻击者可能会盗取这些信息。 …

【flask开启进程,前端内容图片化并转pdf-会议签到补充】

flask开启进程,前端内容图片化并转pdf-会议签到补充 flask及flask-socketio开启threading页面内容转图片转pdf流程前端主js代码内容转图片-browser端browser端的同步编程flask的主要功能route,def 总结 用到了pdf,来回数据转发和合成,担心flask卡顿,响应差,于是刚好看到threadi…

R7:糖尿病预测模型优化探索

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、实验目的&#xff1a; 探索本案例是否还有进一步优化的空间 二、实验环境&#xff1a; 语言环境&#xff1a;python 3.8编译器&#xff1a;Jupyter notebo…

张氏宗谱序言白话文翻译

序言&#xff1a; 回想千家有赤松子的传承&#xff0c;张家有 “百忍” 的风范。感慨因迁徙和战乱、水灾之苦&#xff0c;远居他乡而失去了家族秩序。想起自从从泗州来到淮安&#xff0c;安家在安东县东北乡众湖荡之地。&#xff08;这里可能在回忆家族的迁徙历史&#xff09;…

从0开始学习Linux——Yum工具

往期目录&#xff1a; 从0开始学习Linux——简介&安装 从0开始学习Linux——搭建属于自己的Linux虚拟机 从0开始学习Linux——文本编辑器 上一个章节我们简单了解了Linux中常用的一些文本编辑器&#xff0c;本次教程我们将学习yum工具。 一、Yum简介 Yum&#xff08;全名…