【STM32HAL库学习】通信方式:USART、IIC、SPI

通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统

通信接口区别

名称引脚双工时钟电平设备
USARTTX、RX全双工异步单端点对点
I2CSCL、SDA半双工同步单端多设备
SPISCLK、MOSI、MISO、CS全双工同步单端多设备
CANCAN_H、CAN_L半双工异步差分多设备
USBDP、DM半双工异步差分点对点

以下是一些常见概念:

  • 双工:通信设备是否同时能进行双方通信,一般全双工的都有两根通讯线,如 USART 就有TX/RX这两根通讯线。 I2C 只有一根通讯线SDA(另外一根是时钟线),所以 I2C 半双工的通信

  • 时钟:分为同步异步
    同步:有单独的时钟信号线,保证通讯时用的是同一个时钟
    异步:没有单独的时钟信号线,只能双方规定制定的时钟频率。如串口发送方中可以指定波特率来实现间隔多少时间向TX发送一个数据(变化一次高低电平),那么接收方也要根据这个波特率来接收数据(间隔多长时间读取一次RX的电平)

  • 电平
    单端:电平参考需要一样,即如串口通讯中,发送方与接收方需要共地,保证它们的参考电压是一样的。
    差分:不需要共同的参考电平,是根据两根通讯线的电平差异来获取结果的。如两根通讯线的电平不同则表示结果0,相同则表示结果1。

  • 电平标准
    即通讯协议中,双方数据1和0的表达方式标准。即传输过程中人为规定电压与数据的对应关系,常用的有以下3种,抗干扰性RS485 > RS232 > TTL

    • TTL电平:+3.3V或+5V表示1,0V表示0
    • RS232电平:(-3 , -15V)表示1,(+3 , +15V)表示数据0
    • RS485标准:使用的不是绝对电压,而是两根信号线的相对电压(差分信号)作为标准。两根线电压差(+2, +6V)表示1,相差(-2, -6V)表示0。抗干扰信号非常强,距离可达到上千米
    • 当电平标准不一致时,需要加电平转换芯片
  • 波特率
    用于指定发送的频率和接收的频率,假如发送方1秒发送1位,那么接收方也必须1秒接收(读取一次RX的电平)1位,假如接收方频率更快,那么有可能相同一个数据被接收方多次接收。其单位是bps,即1秒发
    送的位数。1000bps就是1秒发送1000位数据,1位数据的发送耗时是1ms(二进制下,1位=1baud)

  • 数据模式

    • HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
    • 文本模式/字符模式:以原始数据编码后的形式显示
    • 如果要显示汉字,就得制定汉字的字符集如GB2312、GBK,另外Unicode字符集:全球的语言,最常用的传输形式是UTF8

    串口通信

    1、参数

  • 波特率

  • 1位起始位(标志一个数据帧的开始,固定为低电平)

  • 1位停止位(标志一个数据帧的结束,固定为高电平)一般停止位为1位,也可设置为0.5、1、1.5、2,停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

  • 8/9位数据位(是否奇偶校验,如偶校验:第9位保证9位数据中1的个数为偶数),数据低位先行
    因此,在无奇偶校验的情况下一帧的数据长度为10位。

3、利用CubMX配置串口通信

配置只需要一步,关键掌握如何收发各种格式的数据。
在这里插入图片描述

发送数据
//1、发送一个字节
void hhSerialSendByte(uint8_t Byte){
	HAL_UART_Transmit(&huart1, &Byte, 1, HAL_MAX_DELAY);
}

//2、发送一个数组
void hhSerialSendArray(uint8_t *Array,uint16_t Length){
	for(uint16_t i=0;i<Length;i++){
		hhSerialSendByte(Array[i]);
	}
}

//3、发送一个字符串
void hhSerialSendString(char * mString){
	for(uint16_t i=0;mString[i]!='\0';i++){
		hhSerialSendByte(mString[i]);
	}
}

//4、发送一个数字
uint32_t Serial_Pow(uint32_t X, uint32_t Y){
	uint32_t Result = 1;
	while (Y --){
	Result *= X;
	}
	return Result;
}
void hhSerial_SendNumber(uint32_t Number, uint8_t Length){
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		hhSerialSendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
	}
}


在这里插入图片描述

//5、发送浮点数 前设置
#include <stdarg.h>
#include "stdio.h"
void Serial_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	hhSerialSendString(String);
}
接收数据

1、查询法接收
在前面配置好USART的波特率等信息后,循环不断查询是否有数据传输过来

uint8_t ByteRecv;
int main(void){
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	OLED_Init();
	OLED_Clear();
	while (1){
		HAL_UART_Receive(&huart1, &ByteRecv, 1, HAL_MAX_DELAY);
		hhSerialSendByte(ByteRecv);
	}
}

2、中断法接收

//1.单字节发送
void hhSerialSendByte(uint8_t Byte){
	HAL_UART_Transmit(&huart1, &Byte, 1, HAL_MAX_DELAY);
}
uint8_t Serial_RxFlag;
uint8_t Serial_GetRxFlag(void){
	if (Serial_RxFlag == 1){
	Serial_RxFlag = 0;
	return 1;
	}
	return 0;
}
uint8_t ByteRecv;
//接收中断函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	if (huart == &huart1){
	Serial_RxFlag=1;//已接收标志位,说明已经接收完一次
	HAL_UART_Receive_IT(&huart1, &ByteRecv, 1);//接收了一次后需要再次打开接收中断为下次中断接收做准备
	}
}

int main(void){
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	OLED_Init();
	OLED_Clear();
	HAL_UART_Receive_IT(&huart1, &ByteRecv, 1);//启动中断接收一个字节
	OLED_ShowString(1, 1, "RxData:");
	while (1){
		if (Serial_GetRxFlag() == 1){
		hhSerialSendByte(ByteRecv);//将接收到的数据重新发送返回给电脑串口
		OLED_ShowHexNum(1, 8, ByteRecv, 2);
		}
	}
}

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

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

相关文章

【数值计算库-超长笔记】Python-Mpmath库:高精度数值计算

原文链接&#xff1a;https://www.cnblogs.com/aksoam/p/18279394 更多精彩&#xff0c;关注博客园主页&#xff0c;不断学习&#xff01;不断进步&#xff01; 我的主页 csdn很少看私信&#xff0c;有事请b站私信 博客园主页-发文字笔记-常用 有限元鹰的主页 内容&#xf…

类与对象完结

1.匿名类 先看一个例子 class A { public:A(int a 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}void Print(){cout << _a << endl;} private:int _a; };int main() {A aa1(10);aa1.Print(…

【Redis7】零基础篇

1 课程概述 2 Redis入门概述 2.1 是什么 Redis是基于内存的KV键值对内存数据库 Redis&#xff1a;Remote Dictionary Server(远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value数据库提供了丰富的数据结构&#xff0c…

Halcon机器视觉定位--模板匹配

一 Halcon模板匹配归纳 二 形状匹配算子介绍 find_shape_model( Image ,//待搜索图像 ModelID, //模版图像 AngleStart, //起始角度 AngleExtent, //角度范围 MinScore, //最小匹配分数 NumMatches, //匹配数目 MaxOverlap, //重叠度 SubPixel, //搜索精度 Greediness ,//自信度…

【FFmpeg】av_read_frame函数

目录 1.av_read_frame1.2 从pkt buffer中读取帧&#xff08;avpriv_packet_list_get&#xff09;1.3 从流当中读取帧&#xff08;read_frame_internal&#xff09;1.3.1 读取帧&#xff08;ff_read_packet&#xff09;1.3.2 解析packet&#xff08;parse_packet&#xff09;1.3…

和小红书一起参会! 了解大模型与大数据融合的技术趋势

在过去的两年中&#xff0c;“大模型”无疑成为互联网行业的焦点话题&#xff0c;曾经炙手可热的大数据架构似乎淡出公众视野。然而&#xff0c;大数据领域并未停滞不前&#xff0c;反而快速演进&#xff0c;传统依赖众多开源组件的大数据平台正逐步过渡到以融合与简化为核心特…

C++ ariac2 Windows库编译

cd "F:\\aria2" gmp-6.1.2.tar.lz expat-2.2.0.tar.bz2 sqlite-autoconf-3160200.tar.gz zlib-1.2.11.tar.gz c-ares-1.12.0.tar.gz libssh2-1.8.0.tar.gz --enable-libaria2 --enable-static libgnutls-dev&#xff08;对于HTTPS&#xff0c;BitTorrent&#xff0…

Verilog开源项目——百兆以太网交换机(五)TCAM单元设计

Verilog开源项目——百兆以太网交换机&#xff08;五&#xff09;TCAM单元设计 &#x1f508;声明&#xff1a;未经作者允许&#xff0c;禁止转载 &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f511;全新原创以太网交换机项目&#xff0c;Blog内容将聚焦整体架…

LLM-Transformer:经典与前沿方法详解

LLM-Transformer&#xff1a;经典与前沿方法详解 前言 大规模语言模型&#xff08;LLM&#xff09;是当前自然语言处理&#xff08;NLP&#xff09;领域的核心技术&#xff0c;而Transformer架构作为LLM的基础&#xff0c;极大地推动了这一领域的发展。本文将详细介绍LLM-Tra…

DP:子序列问题

文章目录 什么是子序列子序列的特点举例说明常见问题 关于子序列问题的几个例题1.最长递增子序列2.摆动序列3.最长递增子序列的个数4.最长数对链5.最长定差子序列 总结 什么是子序列 在计算机科学和数学中&#xff0c;子序列&#xff08;Subsequence&#xff09;是指从一个序列…

【2024德国签证】去德国读博士需要申请什么签证?

德国留学签证面签的经过及注意事项 ✨&#xff01;希望我的经验可以帮助大家顺利通过签证&#xff0c;顺利开启德国留学之旅 。记得带上足够的现金和材料哦 &#xff01; 一、选择适合自己的签证类型 在选择签证类型时&#xff0c;一定要根据自己的实际情况来选择合适的签证种…

Wp-scan一键扫描wordpress网页(KALI工具系列三十二)

目录 1、KALI LINUX 简介 2、Wp-scan工具简介 3、信息收集 3.1 目标IP&#xff08;服务器) 3.2kali的IP 4、操作实例 4.1 基本扫描 4.2 扫描已知漏洞 4.3 扫描目标主题 4.4 列出用户 4.5 输出扫描文件 4.6 输出详细结果 5、总结 1、KALI LINUX 简介 Kali Linux 是一…

JAVA极简图书管理系统,初识springboot后端项目

前提条件&#xff1a; 具备基础的springboot 知识 Java基础 废话不多说&#xff01; 创建项目 配置所需环境 将application.properties>application.yml 配置以下环境 数据库连接MySQL 自己创建的数据库名称为book_test server:port: 8080 spring:datasource:url:…

存储故障导致Oracle 19c 数据文件处于recover状态的恢复案例

1.背景 某次平台分布式存储故障&#xff0c;导致数据库出现ORA-00376、ORA-01110数据文件不可读报错&#xff0c;本文将整个恢复过程进行整理记录。 2.报错信息 在进行租户数据库打开操作时&#xff0c;出现了如下报错&#xff1a; ORA-00376: file 17 cannot be read at t…

DICOM灰度图像、彩色图像的窗宽、窗位与像素的最大最小值的换算关系?

图像可以调整窗宽、窗位 dicom图像中灰度图像可以调整窗宽、窗位&#xff0c;RGB图像调整亮度或对比度&#xff1f;_灰度 图 调节窗宽-CSDN博客 窗宽、窗位与像素的最大最小值的换算关系? 换算公式 max-minWindowWidth; (maxmin)/2WindowCenter; 详细解释 窗宽&#xff0…

谷歌重磅:告别RAG,长上下文的大语言模型无需检索增强

当今人工智能领域正在经历一场静默的革命。随着大语言模型(LLM)的快速发展&#xff0c;它们不仅能够处理更长的上下文&#xff0c;还展现出惊人的推理和检索能力。 难道我们要告别基于LLM的检索增强生成(RAG)了吗&#xff1f; 结果还真是这样&#xff0c;最近谷歌发布专门用于…

贪心算法算法,完全零基础小白教程,不是计算机的都能学会!超详解

目录 一、基本概念 二、举几个例子&#xff0c;便于理解 1、找零问题 2、最小路径和 3、背包问题 1&#xff09;只考虑体积的贪心策略&#xff1a; 2&#xff09; 只考虑价值的贪心策略&#xff1a; 三、贪心策略的特点 四、贪心策略证明 四、如何学习贪心 五、例题…

eNSP中WLAN的配置和使用

一、基础配置 1.拓扑图 2.VLAN和IP配置 a.R1 <Huawei>system-view [Huawei]sysname R1 GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 200.200.200.200 24 b.S1 <Huawei>system-view [Huawei]sysname S1 [S1]vlan 100 [S1-vlan100]vlan 1…

IAR工程目录移动报错(改变文件目录结构)

刚开始用IAR&#xff0c;记录一下。 工作中使用华大单片机&#xff0c;例程的文件目录结构太复杂了想精简一点。 1.如果原本的C文件相对工程文件&#xff08;.eww文件&#xff09;路径变化了&#xff0c;需要先打开工程&#xff0c;再将所有的.c文件右键Add添加进工程&#xf…

PHP7源码结构

PHP7程序的执行过程 1.PHP代码经过词法分析转换为有意义的Token&#xff1b; 2.Token经过语法分析生成AST&#xff08;Abstract Synstract Syntax Tree&#xff0c;抽象语法树&#xff09;&#xff1b; 3.AST生成对应的opcode&#xff0c;被虚拟机执行。 源码结构&#xff1…