一、IIC简介
1、IIC基本信息
通信标准 | IIC |
---|---|
通信方式 | 同步通信 |
引脚说明 | SCL:同步时钟;SDA数据输入/输出端 |
通信方向 | 半双工 |
IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。经常IIC和SPI接口被认为指定是一种硬件设备,但其实这样的说法是不尽准确的,严格的说他们都是人们所定义的软硬结合体,分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。
常见物理接口:
2、IIC信号
信号 | 说明 |
---|---|
开始信号(必要) | SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。 |
结束信号(可不要) | SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。 |
应答信号(可不要) | 接收方接收到 8bit 数据后,向发送方发出特定的低电平脉冲(应答信号),表示已收到数据。若未收到应答信号,则判断通信失败。 |
具体如下:
起始与终止信号 | |
---|---|
应答信号(以主发从收为例) |
参考 ---- [https://www.cnblogs.com/zhangjiansheng/p/7738390.html]
3、IIC数据传输
①主发从收
②主收从发
注意:
- IIC总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址;
- 在通信前必须弄清主机与从机、发送方与接收方(这两组概念是不同的)。
- IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定;只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。 (数据的有效性)
参考 1---- [https://blog.csdn.net/bluewhaletech/article/details/37876111]
参考2 ---- [https://www.cnblogs.com/aaronLinux/p/6218660.html]
二、IIC的使用(以stm32与24C02为例)
写在前面:IIC有根据历史原因分有硬件IIC与软件模拟IIC两种(有兴趣自己找找),以下的使用以软件模拟IIC为主(后序有机会再弄硬件IIC)。附两者区别:
是什么:
- 模拟IIC:一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形;
- 硬件IIC:对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用。
二者区别:
- 硬件IIC用法比较复杂,模拟IIC的流程更清楚一些;
- 硬件IIC速度比模拟快,并且可以用DMA;
- 模拟IIC可以在任何管脚上,而硬件只能在固定管脚上;
- 模拟I2C 是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。
参考1 ---- [https://blog.csdn.net/faihung/article/details/59146937]
参考2 ---- [https://www.cnblogs.com/wy9264/p/11863239.html]
0、硬件介绍
24C02是什么:【百度百科-24C02】
STM32F1与24C02连接图:
24C02引脚:
引脚名 | 说明 | 引脚名 | 说明 |
---|---|---|---|
A0-A2 | 地址输入线 | WP | 写保护 |
SCL | 时钟线 | SDA | 数据线 |
上面提到从机地址由7位组成,而地址输入线只有三位,因此完整的地址组成需看数据手册:
前面的xK代表不同大小的24Cxx(型号)
1、程序部分
由于是使用软件模拟IIC,因此需要自己加入两个驱动程序,IIC驱动程序+从机设备(24C02)驱动程序,将两个驱动程序分别封装好加入项目即可。
1.1 IIC驱动程序部分
·宏定义(myiic.h)
·下列程序(myiic.c)
①IIC初始化
②产生 IIC 起始信号
③产生 IIC 停止信号
④等待应答信号到来(返回值:1->接收应答失败;0->接收应答成功)
⑤产生 ACK 应答(返回从机有无应答:1->有应答;0->无应答)
⑥不产生 ACK 应答(ack=1 时,发送 ACK;ack=0,发送 !ACK)
⑦发送一个字节
⑧读 1 个字节
·宏定义(myiic.h)
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
//IO方向设置
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//IO操作函数
#define IIC_SCL PBout(6) //SCL
#define IIC_SDA PBout(7) //SDA
#define READ_SDA PBin(7) //输入SDA
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void</