IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> UART IIC SPI协议总结 -> 正文阅读

[嵌入式]UART IIC SPI协议总结

总体概述

本文将总结嵌入式当中常用的3种通信协议,重点从协议本身,以及协议的时序图展开概述。在展开概述前,我们还得了解下一些电气特性,例如
在这里插入图片描述
在实际的线路传输数据时,无非就是高低电平,即0和1,上面这个图是从其它地方拷贝过来的,链接我忘记了,对于实际的电气特性来说,有时候是3.3v代表1,有时候是5v代表1,所以为了主机和从机之间的这个电平特性保持一致,一般来说,在外部ic当中都会有电平的转换(有专门的电平转换芯片,例如CH340)。这个对于软件从事人员可以这样简单的了解一下。由于自己对单片机稍微了解一些,所以下面从单片机的角度去总结这三个协议。
如果有朋友对FPGA比较熟悉,也可参考
FPGA协议

UART

通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART。

协议概述

UART协议的话,是异步的,异步是什么意思呢?
大家看以下这个图,有RX和TX,这个是一个串口设备,可以
发送数据到电脑上,电脑上使用一些上位机软件,就可以显示收到的数据是什么。这个设备是支持UART协议的,它没有时钟线,所以是异步的,异步可以理解为发送方和接收方的一个时间上的一致性。这个图当中,左边直接接入电脑,右边可以看到有5v和3.3v这两个电压是给这个模块供电的,具体使用那个,需要看外部ic,而rx和tx需要和外部的tx和rx相连,也就是发送连接接收端,接收端连接发送端。这里的外部ic指的是单片机,我们这里不关心数据是怎么发送和接收的,重点是分析数据是怎么通过rx和tx进行传输的。
在这里插入图片描述

时序分析

比如说,单片机要通过tx的这个引脚发送一个字符给pc,那么数据格式是怎么样的呢?
对于UART协议来说,大体上数据格式可以分为两种,一种是带校验的,一种是不带校验的。校验的话是奇偶校验。
(1)不带校验的。
格式:起始位(一个bit,这里S是起始位,为低电平)+数据位(一个字节/8个bit)+停止位(一个bit,高电平)具体传输数据时是低为再前,高位在后。这里有两个地方需要注意一下,就是我没发数据时,一开始是高电平还是低电平?当然是高电平,从下面这个图也可以看的出来,S的左边是不是高电平?为什么一开始是高呢?其实也容易理解,如果一开始是低电平,那么接收方会误以为是收到了一个起始信号,那后面就会认为是数据部分了,此外,当数据传输了到了停止位这里的时候,如果此时没有数据传输了,那就相当于是空闲了,后面出现的是高电平。如果后面接着有数据进行传输,那么又会接着从起始位+数据部分+停止位的格式进行发送。
在这里插入图片描述
对硬件熟悉的朋友可以用示波器或者逻辑分析仪接到tx或者rx这个引脚上,观察具体的波形是怎么样的,这样可以有助于理解时序图。
(2)带校验的
带校验的话,格式为:
起始位(一个bit,为低电平)+数据位(一个字节/8个bit)+校验位+停止位(一个bit,高电平)
至于校验位是高电平还是低电平需要看数据部分和是奇校验还是偶校验。这里不谈这点。
在实际工作当中,不同的设备可能有校验部分,有的也可能没有,我们到时翻阅手册即可。最后,就是波特率了,因为UART是异步的,所以为了接收以及发送的统一,双发要规定一个时间段。UART的波特率比较固定,以115200来说,就是传输一个bit为要花多长时间,从上面那个图来看大约是9us,即1/115200s。

伪代码概述

UART部分的伪代码的话,这里简单的介绍下,以单片机来说,就是设置了一下引脚的模式,然后设置具体的传输模式,可以是DMA传输,也可以是中断传输,最后都是将数据通过引脚发送出去的。具体的内部原理我们在这里就不介绍了。

IIC

协议概述

IIC协议的话,可以参考下:IIC
个人觉得篇文章讲的非常的不错的。

时序分析

对于IIC协议来说,主要有时钟线和数据线,靠着这两根线,接收方和发送方进行数据的交互。因为有时钟线嘛,所以它是同步的。也就是在一个时钟周期内,接收方会查看数据线上面是高电平还是低电平,在下一个周期内,又会接着去看。

通过IIC协议进行交流时,有以下几个重要的信号。
(1)起始信号
(2)停止信号
这两个信号UART协议也是有的,那么IIC是怎么样表示的呢?
具体可以参考上面那篇文章。
(3)应答信号,也就是说对于通过IIC协议连接的两个设备来说无论是谁发数据,谁接收数据,都要有一个应答
(4)空闲信号,即没有数据发送时,时钟线和数据线是高电平还是低电平?

伪代码概述

#include "iic.h"
/***************************************************************
 * @file       iic.c
 * @brief      IIC初始化
 * @return     无
 * @date       2022/04/11
**************************************************************/
void IIC_Init(void)
{
    /*
     这里是设置引脚的属性,比如是输出还是输入等。
    */
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC_SDA输出模式
 * @return     无
 * @date       2022/04/11
**************************************************************/
void IIC_SDAModeOut(void)
{
    //...数据线是输出模式
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC_SDA输入模式
 * @return     无
 * @date       2022/04/11
**************************************************************/
void IIC_SDAModeIn(void)
{
    //...数据线是输入模式
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC起始信号函数  ---》当 SCL 为高电平时,SDA 由高变低
 * @return     无
 * @date       2022/04/11
 **************************************************************/
void IIC_Start(void)
{
    IIC_SDAModeOut();

    IIC_SDA_OUT(1);
    IIC_SCL_OUT(1);
    delay_us(5);

    IIC_SDA_OUT(0);
    delay_us(5);
    IIC_SCL_OUT(0);
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC停止信号函数   ---》当 SCL 为高电平时,SDA 由低变高
 * @return     无
 * @date       2022/04/11
 **************************************************************/
void IIC_Stop(void) 
{
    IIC_SDAModeOut();

    IIC_SDA_OUT(0);
    IIC_SCL_OUT(0);
    delay_us(5);

    IIC_SCL_OUT(1);
    delay_us(5);

    IIC_SDA_OUT(1);
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC写一个字节函数
 * @return     无
 * @date       2022/04/11
 **************************************************************/
void IIC_WriteByte(uint8_t data)     //01101011
{
    int i = 0;

    IIC_SDAModeOut();
    IIC_SCL_OUT(0);
    delay_us(5);

    for(; i < 8; i++){
        
        if(data & (0x1 << (7-i))){
            IIC_SDA_OUT(1);
        }else{
            IIC_SDA_OUT(0);
        }
        
        IIC_SCL_OUT(1);
        delay_us(5);
        
        IIC_SCL_OUT(0);
        delay_us(5);
        
    }
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC读一个字节函数
 * @return     data
 * @date       2022/04/11
 **************************************************************/
uint8_t IIC_ReadByte(void)   //01101011
{
    uint8_t data;
    int i = 0;
    IIC_SDAModeIn();

    IIC_SCL_OUT(0);
    delay_us(5);

    for(; i < 8; i++) {
        IIC_SCL_OUT(1);
        delay_us(5);
        
        if(IIC_SDA_IN()) {
            data |= (0x1 << (7-i));
        } else {
            data &= ~(0x1 << (7-i));
        }
        IIC_SCL_OUT(0);
        delay_us(5);
    }
    return data;
}
/***************************************************************
 * @file       iic.c
 * @brief      IIC应答函数  --->24C02 写给 STM32 数据,STM32 给 24c02 一个回复
 * @return     无
 * @date       2022/04/11
 **************************************************************/
void IIC_Ack(uint8_t ack)
{
    IIC_SDAModeOut();
    
    IIC_SCL_OUT(0);
    delay_us(5);
    
    if(ack){
        IIC_SDA_OUT(1);     
    }else{
        IIC_SDA_OUT(0);
    }
    
    IIC_SCL_OUT(1);
    delay_us(5);
    
    IIC_SCL_OUT(0);
}

/*
 * 功  能:IIC等待应答
 * 参  数:无
 * 返回值:成功得到的回复 
 *      1   --->不应答
 *      0   --->应答
 */
uint8_t IIC_WaitAck(void)
{
    uint8_t i = 0;
    IIC_SDAModeIn();
        
    IIC_SCL_OUT(0);
    delay_us(5);
    
    IIC_SCL_OUT(1);
    delay_us(5);
    
    if(IIC_SDA_IN()){
        i = 1;
    }else{
        i = 0;
    }    
    IIC_SCL_OUT(0);    
    return i;
}

从上面的伪代码不难看出,具体的函数有,起始信号函数停止函数发送数据函数以及接收数据函数等待应答函数等,他们都是依据时序图来写的,对于写函数来说,发送数据时,也是一个bit一个bit进行发送的。而伪代码里面的延时是为了体现出SCL这根线的作用,也就是制造出一个时钟周期,然后在这个周期里面让SDA引脚进行输入或者输出。

SPI

协议概述

SPI协议相对来说,线就多了几根了。

时序分析和伪代码概述

理论:SPI
参考:视频
最后贴一个利用SPI协议在一个OLED屏上显示自己名字的图。
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:47  更:2022-04-18 18:03:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/18 10:02:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码