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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【STM32】软件i2c的实现 -> 正文阅读

[嵌入式]【STM32】软件i2c的实现

I2C 总线的一些特征

? 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL

? 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地
址 主机可以作为主机发送器或主机接收器

? 它是一个真正的多主机总线 如果两个或更多主机同时初始化数据传输可以通过冲突检测和仲裁
防止数据被破坏

? 串行的 8 位双向数据传输位速率在标准模式下可达 100kbit/s 快速模式下可达 400kbit/s 高速
模式下可达 3.4Mbit/s

? 片上的滤波器可以滤去总线数据线上的毛刺波 保证数据完整

? 连接到相同总线的 IC 数量只受到总线的最大电容 400pF 限制

I2C 总线术语的定义

术语描述
发送器发送数据到总线的器件
接收器从总线接收数据的器件
主机初始化发送 产生时钟信号和终止发送的器件
从机被主机寻址的器件
多主机同时有多于一个主机尝试控制总线 但不破坏报文
仲裁是一个在有多个主机同时尝试控制总线 但只允许其中一个控制总线并使报文不被破坏的过程
同步两个或多个器件同步时钟信号的过程

发送器和接收器外,器件在执行数据传输时也可以被看作是主机或从机,见上表,主机是初始化总线的数据传输并产生允许传输的时钟信号的器件,此时,任何被寻址的器件都被认为是从机

总体特征

SDASCL 都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压,见图 3 当总线空
闲时,这两条线路都是高电平,连接到总线的器件输出级必须是漏极开路集电极开路才能执行线与的功能

因为连接到总线的器件输出级必须是漏极开路集电极开路才能执行线与的功能 ,所以我们在配置IO模式时,配置成开漏输出

数据的有效性

SDA 线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在 SCL 线的时钟
信号是低电平时才能改变

在这里插入图片描述

.h内容如下

#ifndef _BSP_I2C_H
#define _BSP_I2C_H

#include"stm32f10x.h"
#include"stm32f10x_gpio.h"

#define I2C_CLK_FUN        RCC_APB2PeriphClockCmd
#define I2C_CLK            RCC_APB2Periph_GPIOB

//SCL
#define I2C_SCL_PORT   GPIOB
#define I2C_SCL_PIN    GPIO_Pin_6

#define I2C_SCL_Hight  GPIO_SetBits(I2C_SCL_PORT,I2C_SCL_PIN);
#define I2C_SCL_Low    GPIO_ResetBits(I2C_SCL_PORT,I2C_SCL_PIN);  

//SDA
#define I2C_SDA_PORT   GPIOB
#define I2C_SDA_PIN    GPIO_Pin_7

#define I2C_SDA_Hight GPIO_SetBits(I2C_SDA_PORT,I2C_SDA_PIN);
#define I2C_SDA_Low   GPIO_ResetBits(I2C_SDA_PORT,I2C_SDA_PIN);

	
#define I2C_SDA_READ()  ((GPIOB->IDR & I2C_SDA_PIN) != 0)	/* 读SDA口线状态 */


void I2C_Start(void);
void I2C_Stop(void);
uint8_t I2C_Wait_ACK(void);
void I2C_Send_Byte(uint8_t data);
uint8_t I2C_Read_Data(void);
void I2C_Send_Ack(void);
void I2C_Send_NAck(void);
uint8_t I2C_Check_Ack(uint8_t data);


#endif /*_BSP_I2C_H*/

GPIO初始化

void I2C_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    I2C_CLK_FUN(I2C_CLK,ENABLE);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    //SDA
    GPIO_InitStruct.GPIO_Pin = I2C_SDA_PIN;
    GPIO_Init(I2C_SDA_PORT,&GPIO_InitStruct);
    //SCL
    GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN;
    GPIO_Init(I2C_SCL_PORT,&GPIO_InitStruct);

    I2C_Stop();
}

SDA与SCL都配置成开漏输出

起始和停止

起始条件:在 SCL 线是高电平时,SDA 线从高电平向低电平切换
停止条件:当 SCL 是高电平时 SDA 线由低电平向高电平切换

//i2c起始信号
//在SCL为高电平期间,SDA由高电平转化为低电平
void I2C_Start(void)
{
    I2C_SCL_Hight;
    I2C_SDA_Hight;
    //延时一段时间
    Delay_Us(10);
    I2C_SDA_Low;
    Delay_Us(10);
    I2C_SCL_Low;
    Delay_Us(10);
}
//i2c结束信号
//在SCL为高电平期间,SDA由低电平转化为高电平
void I2C_Stop(void)
{
    I2C_SCL_Hight;
    I2C_SDA_Low;
    Delay_Us(10);
    I2C_SDA_Hight;
}

等待响应

等待响应就好比生活中两个人打电话,拨打方打通电话之后,等待接收方回应:“喂,你好”(ACK),然后进行下面的通话。
而在I2C通信过程中,每次发送方传输一字节后,接收方就会回应一个ACK

响应时序图如下:
在这里插入图片描述

//等待响应  1:非应答 0:应答
uint8_t I2C_Wait_ACK(void)
{
    uint8_t ack;

    I2C_SDA_Hight;
    Delay_Us(10);
    I2C_SCL_Hight;
    Delay_Us(10);

    if(I2C_SDA_READ()) //非应答
        ack = 1;
    else
        ack = 0;
    I2C_SCL_Low;
    Delay_Us(10);

    return ack;
}

发送NACK

在24C02芯片手册中,观察Current Address Read这个时序,会发现在数据传输结束后,不再传输时,发送方会发送一个非应答(NACK),所以我们编写一个发送NACK的函数

在这里插入图片描述

//发送非应答
void I2C_Send_NAck(void)
{
	//拉高SDA,生成NACK
    I2C_SDA_Hight;
    Delay_Us(10);
    //读取
    I2C_SCL_Hight;
    Delay_Us(10);
    I2C_SCL_Low;
    Delay_Us(10);
}

发送数据

由上面的数据有效性知:SDA线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在 SCL 线的时钟信号是低电平时才能改变

在这里插入图片描述

//发送数据
void I2C_Send_Byte(uint8_t data)
{
    uint8_t mask;  //发送数据时高位在前

    for(mask=0x80;mask!=0x00;mask>>=1)
    {
        if(data&mask)
        {
            I2C_SDA_Hight;  
        }
        else
            I2C_SDA_Low;

        Delay_Us(10);
        I2C_SCL_Hight;
        Delay_Us(10);
        I2C_SCL_Low;
    }
    I2C_SDA_Hight;     //释放总线,等待ACK

}

发送过程中,由上图可知,高位在前,低位在后
所以定义一个变量mask,这个for循环for(mask=0x80;mask!=0x00;mask>>=1)表示mask从高位为1,到最低为1的过程:10000000、01000000、00100000、、、、00000001,紧接着用data&mask,如果结果为1,即表示data相应位为1,反之为0

读取数据

读取数据过程中,SCL线必须保持高电平,当一位读取结束后,释放SCL,等待一段时间,让SDA改变数据,重复上述过程

//读取数据
uint8_t I2C_Read_Data(void)
{
    uint8_t data=0,mask;

    for(mask=0x01;mask!=0;mask>>=1)
    {
        I2C_SCL_Hight;
        Delay_Us(10);
        if(GPIO_ReadInputDataBit(I2C_SDA_PORT,I2C_SDA_PIN))
            data |= mask;     //读取结束为1
        else
            data &= ~mask;    //读取结束为0
        
        
        I2C_SCL_Low;
        Delay_Us(10);
    }

    return data;
}

mask的用法与发送数据时的类似

寻址

在这里插入图片描述
在这里插入图片描述
由图可以得到
一、寻址过程是通常在起始条件后的第一个字节决定了主机选择哪一个从机
二、当发送了一个地址后 系统中的每个器件都在起始条件后将头 7 位与它自己的地址比较
三、如果一样器件会任务它被主机寻址 至于是从机 接收器还是从机 发送器都由 R/ W 位决定
四、使用这个地址时 理论上所有器件都会发出一个响应

所以可以总结出寻址的步骤:发送起始信号->发送设备地址->等待ACK->发送停止信号

若是代码无误,设备地址正确,会等到一个数值:0

得到设备地址
打开开发板配套的原理图,找到EEPROM(这里是以野火霸道开发板为例)电路,然后再在24C02芯片手册中找到Figure 1. Device Address,由二者可以得到EEPROM的前七位为1010000,然后最低位使用W,所以得到地址:0xA0
在这里插入图片描述
在这里插入图片描述
寻址代码如下

//检测应答
uint8_t I2C_Check_Ack(uint8_t data)
{
    uint8_t Ack;

    I2C_GPIO_Config();
    I2C_Start();

    I2C_Send_Byte(data);
    Ack = I2C_Wait_ACK();

    I2C_Stop();

    return Ack;
}

main.c中调用寻址函数,传入形参为:0xA0
在这里插入图片描述
输出结果如下:
在这里插入图片描述经结果知,驱动代码正确

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-20 15:17:19  更:2021-08-20 15:19: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年11日历 -2024/11/25 23:00:23-

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