串口协议、I2C协议、SPI协议总结

目录

一、串口协议

1.串口基本认知

2.RS-232

3.RS-422

4.RS-485

(1)RS232电平:

(2)TTL电平:

6.串口51开发板实现

(1)软件自动配置:

(2)自己手动配置

7.串口STM32开发板实现

(1)常用函数介绍

(2)状态标记变量:

(3)串口接收中断流程

(4)串口通信非中断实现

(5)串口通信中断实现

8.串口ARM + Linux 开发板实现

二、I2C协议

1.IIC协议概述

2.IIC总线传输

(1)起始信号和结束信号:

(2)应答信号:

(3)数据发送的时序

三、SPI协议


一、串口协议

1.串口基本认知

串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方 式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简 单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成 本,特别适用于远距离通信,但传送速度较慢。

  • 是设备间接线通信的一种方式
  • 数据一位一位地顺序传送
  • 双向通信,全双工(两条线,一条发送数据(TX),一条接收数据(RX))
  • 传送速度相对较慢

 串行接口按电气标准及协议来分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422与RS-485 标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。

2.RS-232

RS-232 也称标准串口,最常用的一种串行通讯接口,比如我们的电脑主机的9针串口 ,最高速率为20kb/s。

RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其传送距离最大为约15米。所以RS-232适合本地设备之间的通信。

3.RS-422

由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。

RS-422最大传输距离为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比。

4.RS-485

RS-485是从RS-422基础上发展而来的,无论四线还是二线连接方式总线上可多接到32个设备。

5.串口的电平

异步串行是指UART(Universal Asynchronous Receiver/Transmitter),通用异步接收/发送。 UART包含TTL电平的串口和RS232电平的串口

(1)RS232电平:

逻辑1为 -3 ~ -15 V 的电压, 逻辑0为 3 ~ 15V 的电压

笔记本通过RS232电平和单片机通信:

(2)TTL电平:

TTL是Transistor-Transistor Logic,即晶体管-晶体管逻辑的简称,它是计算机处理器控制的设备 内部各部分之间通信的标准技术。TTL电平信号应用广泛,是因为其数据表示采用二进制规定, +5V等价于逻辑”1”,0V等价于逻辑”0”。

数字电路中,由TTL电子元器件组成电路的电平是个电压范围,规定:

输出高电平>=2.4V,输出低电平=2.0V

输入高电平>=2.0V,输入低电平<=0.8V

笔记本通过TTL电平和单片机通信:使用USB转TTL(CH340)模块

6.串口51开发板实现

输入/输出数据缓冲器都叫做SBUF, 都用99H地址码,但是是两个独立的8位寄存器

代码体现为: 想要接收数据 char data_msg = SBUF 想要发送数据 SBUF = data_msg

(1)软件自动配置:

根据软件自动生成:

软件延时一秒:

代码示例:发送字符z

#include "reg52.h"
#include "intrins.h"

sfr AUXR = 0x8E;

void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	char data_msg = 'z';
	
	UartInit();
	
	while(1) {
		Delay1000ms();
		SBUF = data_msg; // 往发送缓冲区写入数据,完成数据发送
	}
}

如图:

(2)自己手动配置

在这里我们得通过查看数据手册了解相关寄存器的配置以及串口的工作模式,例如:

代码示例:发送字符串zgl nb

#include "reg52.h"
#include "intrins.h"

sfr AUXR = 0x8E;

void UartInit(void)		//9600bps@11.0592MHz
{
	AUXR = 0x01;
	SCON = 0x40; //配置串口工作方式1,REN不使能接收
	TMOD &= 0x0F;
	TMOD |= 0x20;//定时器1工作方式位8位自动重装
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率的初值
	TR1 = 1;//启动定时器
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
	SBUF = data_msg;
	while(!TI);
	TI = 0;
}

void sendString(char* str)
{
	while( *str != '\0'){
		sendByte(*str);
		str++;
	}
}

void main()
{

	//配置C51串口的通信方式
	UartInit();
	
	while(1){
		Delay1000ms();
		
		sendString("zgl nb\r\n"); // 往发送缓冲区写入数据,就完成数据的发送
	}
}

7.串口STM32开发板实现

(1)常用函数介绍

串口发送/接收函数:

  • HAL_UART_Transmit(); 串口发送数据,使用超时管理机制
  • HAL_UART_Receive(); 串口接收数据,使用超时管理机制
  • HAL_UART_Transmit_IT(); 串口中断模式发送  
  • HAL_UART_Receive_IT(); 串口中断模式接收
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,
               uint8_t *pData, uint16_t Size, uint32_t Timeout)

作用:以阻塞的方式发送指定字节的数据

  • 形参 1:UART_HandleTypeDef 结构体类型指针变量
  • 形参 2:指向要发送的数据地址
  • 形参 3:要发送的数据大小,以字节为单位
  • 形参 4:设置的超时时间,以ms单位
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,
                uint8_t *pData, uint16_t Size)

作用:以中断的方式接收指定字节的数据

  • 形参 1:是 UART_HandleTypeDef 结构体类型指针变量
  • 形参 2:是指向接收数据缓冲区
  • 形参 3:是要接收的数据大小,以字节为单位,此函数执行完后将清除中断,需要再次调用以重新开启中断。

串口中断回调函数:

  • HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
  • HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送中断回调函数
  • HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收中断回调函数

(2)状态标记变量:

USART_RX_STA

从0开始,串口中断接收到一个数据(一个字节)就自增1。当数据读取全部OK时候(回车和换行 符号来的时候),那么 USART_RX_STA的最高位置1,表示串口数据接收全部完毕了,然后main 函数里面可以处理数据了。

(3)串口接收中断流程

(4)串口通信非中断实现

我用STM32CubeMX配置如下,仅供参考:

 RCC:配置外部高速晶振        

SYS:Debug设置成Serial Wire

 时钟树配置:

串口配置:

代码示例:将接收到的数据发送到串口

#include <string.h>

// main.c

  HAL_UART_Transmit(&huart1, "hello zgl\n", strlen("hello zgl\n"), 100);

	
  unsigned char ch[20] = {0};

  while (1)
  {
		HAL_UART_Receive(&huart1, ch, 19, 100);
		HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
		memset(ch, 0, strlen(ch));
  }    

使用串口重映射功能,打开MicroLIB库

代码示例:printf 替换 HAL_UART_Transmit

#include <stdio.h>
#include <string.h>

unsigned char ch[20] = {0};

int fputc(int ch, FILE *f)
{
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);
	return ch;
}

// main函数部分

  HAL_UART_Transmit(&huart1, "hello zgl\n", strlen("hello zgl\n"), 100);

  while (1)
  {
		HAL_UART_Receive(&huart1, ch, 19, 100); 
		printf(ch);
		memset(ch, 0, strlen(ch));
  }

(5)串口通信中断实现

通过中断的方法接受串口调试助手发送的字符串,并将其发送回串口调试助手。

CubeMX新增加一个打开中断,其它同上

代码示例:

#include <stdio.h>

int fputc(int ch, FILE *f)
{      
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);  
	return ch;
}

//串口接收缓存(1字节)
uint8_t buf=0;

//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200

// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];

//  接收状态
//  bit15,      接收完成标志
//  bit14,      接收到0x0d
//  bit13~0,    接收到的有效字节数目
uint16_t UART1_RX_STA=0;

// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	// 判断中断是由哪个串口触发的
	if(huart->Instance == USART1)
	{
		// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
		if((UART1_RX_STA & 0x8000) == 0)
		{
			// 如果已经收到了 0x0d (回车),
			if(UART1_RX_STA & 0x4000)
			{
				// 则接着判断是否收到 0x0a (换行)
				if(buf == 0x0a)
					// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
					UART1_RX_STA |= 0x8000;
				else
					// 否则认为接收错误,重新开始
					UART1_RX_STA = 0;
			}
			else	// 如果没有收到了 0x0d (回车)
			{
				//则先判断收到的这个字符是否是 0x0d (回车)
				if(buf == 0x0d)
				{
					// 是的话则将 bit14 位置为1
					UART1_RX_STA |= 0x4000;
				}
				else
				{
					// 否则将接收到的数据保存在缓存数组里
					UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
					UART1_RX_STA++;
					
					// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
					if(UART1_RX_STA > UART1_REC_LEN - 1)
						UART1_RX_STA = 0;
				}
			}
		}
		// 重新开启中断
		HAL_UART_Receive_IT(&huart1, &buf, 1);
	}
}

// main函数部分

	// 开启接收中断
  HAL_UART_Receive_IT(&huart1, &buf, 1);
	
  while (1)
  {
		//判断判断串口是否接收完成
		if(UART1_RX_STA & 0x8000)
		{
			printf("收到数据:");
			// 将收到的数据发送到串口
			HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff);
			// 等待发送完成
			while(huart1.gState != HAL_UART_STATE_READY);
			printf("\r\n");
			// 重新开始下一次接收
			UART1_RX_STA = 0;
		}
		printf("hello zgl \r\n");
		HAL_Delay(1000);
  }

8.串口ARM + Linux 开发板实现

以香橙派和树莓派示例,可以看我之前写过的文章(比较简略)

香橙派:

linux下实现串口功能_linux 串口实例-CSDN博客

树莓派:

树莓派串口通信_树莓派和电脑串口连接-CSDN博客

二、I2C协议

1.IIC协议概述

  • IIC全称Inter-Integrated Circuit (集成电路总线)
  • 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双工同步通信方式(只有一根双向的数据线SDA)

特点

  • 简单性和有效性

由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件

  • 多主控(multimastering)

其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当 然,在任何时间点上只能有一个主控。

构成

IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL,其时钟信号是由主控 器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线 的SCL上。对于并联在一条总线上的每个IC都有唯一的地址。

2.IIC总线传输

IIC总线在传输数据的过程中一共有三种类型信号,分别为:起始信号、结束信号和应答信号,同时还要进行数据发送。

(1)起始信号和结束信号:

代码示例:

void IIC_Start()
{
	scl = 1;
	sda = 1;
	_nop_();
	sda = 0;
	_nop_();
}

void IIC_Stop()
{
	scl = 1;
	sda = 0;
	_nop_();
	sda = 1;
	_nop_();
}

(2)应答信号:

发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;

应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

代码示例:

char IIC_ACK()
{
	char flag;
	
	scl = 1; // 在时钟脉冲期间释放数据线
	_nop_();
	sda = 0;
	flag = sda;
	_nop_();
	sda = 1;
	_nop_();	
	
	return flag;
}

(3)数据发送的时序

代码示例:

void IIC_Send_Byte(char dataSend)
{
	int i;
	 
	/* 发一位字节数据 */
	for (i = 0; i < 8; i++)
	{
		scl = 0; // 时钟线拉低,让数据线做好开始发送准备
		sda = dataSend & 0x80; // 数据线获得发送数据最高位
		_nop_(); // 延迟一会
		scl = 1; // 时钟线拉高,发送数据
		_nop_(); // 延迟一会让数据发送
		scl = 1; // 发送完毕,时钟线重新拉低
		_nop_();
		dataSend = dataSend << 1;
	}
}

三、SPI协议

有关SPI协议可以看我之前写过的文章:SPI协议和W25Q128详解-CSDN博客

三种协议对比图:

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

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

相关文章

Docker容器化技术(使用Dockerfile制作Nginx镜像)

编写Dockerfile制作Web应用系统nginx镜像&#xff0c;生成镜像名为nginx:v1.1&#xff0c;并推送其到私有仓库。 1、基于centos7基础镜像&#xff1b; 2、指定作者为Chinaskill&#xff1b; 3、安装nginx服务&#xff0c;将提供的dest目录传到镜像内&#xff0c;并将de…

从政府工作报告探计算机行业发展(在医疗健康领域)

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

使用 Jenkins 管道在 Docker Hub 中构建 Docker 镜像

Jenkins Pipeline 是一个强大的工具&#xff0c;可以自动执行部署。在各个阶段之间拆分的灵活和自定义操作是尝试此功能的一个很好的理由。 构建您自己的 Docker 镜像并将其上传到 Docker Hub 以保持存储库更新是了解 Jenkins Pipeline 如何改进您的工作方式的一个很好的示例。…

Oracle Primavera P6 Analytics 是什么,与P6的关系?

前言 Oracle Primavera P6 Analytics 是与P6有关的一个相对较新的模块&#xff0c;Primavera 用户社区在很大程度上尚未对其进行探索。 那么它到底有什么作用呢&#xff1f; 通过了解得知它旨在通过深入了解组织的项目组合绩效&#xff0c;帮助高级管理层对其项目组合做出更好…

DM数据库安装(Windows)

先解压安装包 点击setup安装 下一步 勾选接受然后下一步 下一步 选择典型安装下一步 下一步 搜索DM数据库配置助手然后一直下一步 然后搜索DM管理工具 登录 登录成功 widows版本安装成功

热门骨传导耳机深度评测:南卡、韶音、墨觉全面对比分析!

蓝牙耳机现在已经融入了我们的日常生活&#xff0c;尤其对于运动爱好者而言&#xff0c;一款好的蓝牙耳机不仅能够丰富锻炼时的听觉体验&#xff0c;还能激发运动热情。而骨传导耳机凭借着创新的设计理念和听音方式广受欢迎。骨传导耳机的优势可以让用户在听音乐的同时保持对周…

C++训练营:引用传递

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答。 一、引用传递 简单来说&#xff0c;“引用”就是给已有的变量起一个别名。引用并没有自己单独的内存空间&#xff0c;作为引用&#xff0c;它和原变量共用一段内存空间。引用的定义格…

程序员想要搞钱不迷茫,这篇文章你可得码好啦!!!

年已经过完了&#xff0c;现在大家基本都已经返工返校了吧&#xff01;咱又要投入到新一年的战斗了&#xff01;春色恼人不等闲&#xff0c;相信咱都有一个实实在在的愿望和期许&#xff1a;身体健康&#xff0c;财源广进&#xff01;新的一年我们还得继续努力&#xff0c;多多…

Linux:设置别名命令alias

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 在Linux中alias命令用于为一串字符&#xff08;常代表命令&#xff09;设置一个别名&#xff0c;该别名在Bash读取并解析一行命令时会被展开。 下面是该命令的语法。 用…

IPFoxy的正确打开方式

IPFoxy是一个全球动静态代理IP服务器软件&#xff0c;为全球用户提供优质的大数据代理服务&#xff0c;促进网络业务高校进行。目前拥有千万真实纯净IP资源&#xff0c;覆盖超过220个国家和地区&#xff0c;汇聚成优质海外代理池&#xff0c;支持http、https、socks5多种协议类…

WPF —— Grid网格布局

1 &#xff1a;Grid网格布局简介 Grid为WPF中最常用的布局容器, 作为View中的主要组成部分, 负责框架中整体的页面布局。 2&#xff1a;网格标签Grid.ColumnDef Grid.ColumnDefinitions自定义列 只能设置宽度 不能设置高度ColumnDefinition 每一个列可以设置宽度&#xff0c;…

计数类Dp

文章目录 AcWing 900. 整数划分思路1. 完全背包AC CODE 2. 计数DpAC CODE AcWing 900. 整数划分 链接&#xff1a;https://www.acwing.com/activity/content/problem/content/1008/ 思路 1. 完全背包 完全背包的链接&#xff1a;https://blog.csdn.net/2301_78981471/artic…

安装小知识:无源无线测温传感器可以安装在哪些部位?

一、无源无线测温传感器介绍 无源无线测温传感器采用超低功耗设计&#xff1a;主芯片采用美国TI公司&#xff0c;功耗低&#xff0c;低可至0.03mw&#xff0c;区别于传统的感应供电&#xff0c;不存在发热现象。测温元件采用耐高温、高精度热敏电阻&#xff0c;测温范围宽至-40…

ETH共识升级之路

简介 根据我们之前的介绍&#xff0c;了解到ETH网络的共识方式&#xff0c;已经从 PoW 切换到了 PoS&#xff0c;今天我们就回顾下升级之路&#xff0c;以及升级带来的影响 最早的共识机制 PoW 以太坊创建之初采用了类似比特币的工作量证明机制&#xff0c;即矿工通过计算哈希函…

案例分析篇12:可靠性设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

爬虫入门到精通_框架篇18(Scrapy中选择器用法)_sector,xpath,css,re

官方文档 Using selectors To explain how to use the selectors we’ll use the Scrapy shell (which provides interactive testing) and an example page located in the Scrapy documentation server: https://docs.scrapy.org/en/latest/_static/selectors-sample1.html…

LeetCode.2864. 最大二进制奇数

题目 2864. 最大二进制奇数 分析 这道题目其实我们只需要保证最后一位是1&#xff0c;其余的1都放在最前面&#xff0c;这样得到的就是最大二进制奇数。 所以&#xff0c;我们先统计给定的字符串有多少个 1&#xff0c;多少个 0&#xff0c;把其中一个 1 放在最后一位&…

使用STM32+ESP8266(ESP-01S)+点灯科技(手机端Blinker)实现远程控制智能家居

硬件准备&#xff1a;STM32单片机、ESP8266&#xff08;ESP-01S&#xff09;、CH340C下载烧录器 软件准备&#xff1a;STM32CubeMX、Keil uVision5、Arduino IDE、 点灯科技&#xff08;手机端APP Blinker&#xff09;点灯科技 (diandeng.tech)点击进入 值得注意的是&#x…

工业界真实的推荐系统(小红书)-用户行为序列建模:LastN、DIN、SIM

课程特点&#xff1a;系统、清晰、实用&#xff0c;原理和落地经验兼具 b站&#xff1a;https://www.bilibili.com/video/BV1HZ421U77y/?spm_id_from333.337.search-card.all.click&vd_sourceb60d8ab7e659b10ea6ea743ede0c5b48 讲义&#xff1a;https://github.com/wangsh…

武汉灰京文化:RPG手游营造的奇幻世界

近年来&#xff0c;RPG手游在游戏市场上异军突起&#xff0c;成为年轻玩家追逐的焦点。这类游戏以其深度的游戏体验和吸引人的故事情节&#xff0c;吸引了大批玩家投入其中。那么&#xff0c;为何热衷于RPG手游&#xff1f;本文武汉灰京文化将从社交互动、沉浸式体验、成就感和…
最新文章