单片机——通信协议(FPGA+c语言应用之iic篇)

一.I2C的功能特点

(1)功能包括:

1.只需要两条总线;

2.没有严格的波特率要求,例如使用RS232,主设备生成总线时钟;

3.所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;

4.I²C是真正的多主设备总线,可提供仲裁和冲突检测;

(2) 传输速度

  • 标准模式:Standard Mode = 100 Kbps

  • 快速模式:Fast Mode = 400 Kbps

  • 高速模式:High speed mode = 3.4 Mbps

  • 超快速模式:Ultra fast mode = 5 Mbps

(3)能挂载的iic设备数目

1.最大主设备数:无限制;

2.最大从机数:理论上是127;

二.数据传输

主设备和从设备进行数据传输时遵循以下协议格式。数据通过一条SDA数据线在主设备和从设备之间传输0和1的串行数据。串行数据序列的结构可以分为:

三.协议解析

(1)开始位和停止位

开始位

1.SDA线由高电平切换成低电平;

2.SCL线由高电平切换成低电平;

开始位 c代码实现:

cs 复制代码
// 起始信号
void IIC_start(void)
{
    // 1.首先把数据线设置为输出模式
    // 总线空闲, SCL和SDA输出高
    SCL = 1;  
    SDA = 1;
    delay_us(5);
    
    // SDA由高变低
    SDA = 0;
    delay_us(5);
    
    // 拉低SCL开始传输数据
    SCL = 0;
}

停止位

1.将SDA线从低电压电平切换到高电压电平;

2.再将SCL线从高电平拉到低电平;

停止位c代码实现:

cs 复制代码
/ 停止信号
void IIC_stop(void)
{
    // 1.首先把数据线设置为输出模式
    
    // 拉高时钟线
    SDA = 0;
    delay_us(5);
    SCL = 1;
    delay_us(5);
    
    // SDA由低变高
    SDA = 1;
}

(2)地址位+读写命令位

地址位支持7bit、10bit,主设备如果需要向从机发送/接收数据,首先要发送对应从机的地址,然后会匹配总线上挂载的从机的地址,故地址为主要用来辨识不同设备。

地址位由主机发送,从设备负责接受并识别该地址是否位自己地址。

读写位由主机发送;1表示读操作,0表示写操作。

(3)应答位

应答信号: 出现在1个字节传输完成之后,即第9个SCL时钟周期内,此时主机需要释放SDA总线,把总线控制权交给从机,由于上拉电阻的作用,此时总线为高电平,如果从机正确的收到了主机发来的数据,会把SDA拉低,表示应答响应。

**非应答信号:**当第9个SCL时钟周期时,SDA保持高电平,表示非应答信号。

非应答信号可能是主机产生也可能是从机产生,产生非应答信号的情况主要有以下几种:

  • I2C总线上没有主机所指定地址的从机设备;

  • 从机正在执行一些操作,处于忙状态,还没有准备好与主机通讯;

  • 主机发送的一些控制命令,从机不支持;

  • 主机接收从机数据时,主机产生非应答信号,通知从机数据传输结束,不要再发数据了;

(4)数据位

I2C数据总线传输要保证在SCL为高电平时,SDA数据稳定,所以SDA上数据变化只能在SCL为低电平时

一次传输的数据总共有8位,由发送方设置,它需要将数据位传输到接收方。发送之后会紧跟一个ACK / NACK位,如果接收器成功接收到数据,则从机发送ACK。否则,从机发送NACK。

数据可以重复发送多个,直到接收到停止位为止。

写数据等待应答c代码

cs 复制代码
// 等待ACK   1-无效    0-有效
u8 IIC_wait_ack(void)
{
    u8 ack = 0;
    
    // 数据线设置为输入
    
    // 拉高时钟线
    SCL = 1;
    delay_us(5);
    // 获取数据线的电平
    if(SDA)
    {   // 无效应答
        ack = 1;
        IIC_stop();
    }
    else
    {   // 有效应答
        ack = 0;
        // 拉低SCL开始传输数据
        SCL = 0;
        delay_us(5);
    }
    
    return ack;
}

读数据等待应答 c代码

cs 复制代码
void IIC_ack(u8 ack)
{
    // 数据线设置为输出
    
    SCL = 0;
    delay_us(5);
    
    if(ack)
        SDA = 1; // 无效应答
    else
        SDA = 0; // 有效应答      
    delay_us(5);
    SCL = 1;
    // 保持数据稳定
    delay_us(5);
    // 拉低SCL开始传输数据
    SCL = 0;
}

三.FPGA实现

(1)test_ctrl模块状态机设计

(2) 模块设计

(3)代码实现

(4)测试代码实现

(5)仿真结果

读的前仿真结果

(6)后仿真结果

四.封装iic的IP核并通过linux驱动的方式驱动

1.先生成一个带axi总线的IP核;

2.把要控制的信号通过例化的方式连接寄存器;

3.生成镜像文件;

4.写C语言驱动,并控制寄存器

5.测试,完成

步骤有点复杂,有空再完成

相关推荐
4 分钟前
📌面试答不上的问题-HTTP缓存
前端·面试
AI+程序员在路上16 分钟前
QT与网页显示数据公式的方法
开发语言·qt
赴遥18 分钟前
ESP32S3N16R8驱动ST7701S屏幕(vscode+PlatfoemIO)
vscode·单片机·esp32·st7701s
EasyCVR23 分钟前
EasyRTC嵌入式音视频通话SDK:基于纯C语言的跨平台实时通信系统设计与实践
linux·c语言·开发语言·音视频·webrtc·h.265
沐欣工作室_lvyiyi35 分钟前
基于单片机的防火防盗报警系统设计(论文+源码)
人工智能·stm32·单片机·嵌入式硬件·物联网·目标跟踪
仟濹37 分钟前
【前缀和与差分 二分搜索 C/C++】洛谷 P1083 借教室
c语言·c++·算法
廿二松柏木1 小时前
三级嵌入式学习ing 考点25、26
单片机·嵌入式硬件·学习
是星辰吖~1 小时前
C语言_数据结构_栈
c语言·数据结构
qq_447663052 小时前
《Spring日志整合与注入技术:从入门到精通》
java·开发语言·后端·spring
简简单单做算法2 小时前
基于FPGA的图像退化算法verilog实现,分别实现横向和纵向运动模糊,包括tb和MATLAB辅助验证
fpga开发·verilog·图像退化