IIC协议讲解+代码

本文详细介绍了IIC总线的基本概念、物理特性、协议时序,包括起始、停止和应答信号的发送,以及如何通过代码实现IIC通信和配置步骤。
摘要由CSDN通过智能技术生成

一、什么是IIC?

IIC属于两线式串行总线,由飞利浦公司开发用于微控制器(MCU)和外围设备(从设备)进行通信的一种总线,属于一主多从(一个主设备(Master),多个从设备(Slave))的总线结构总线上的每个设备都有一个特定的设备地址,以区分同一I2C总线上的其他设备

物理I2C接口有两根双向线,串行时钟线(SCL)串行数据线(SDA)组成,可用于发送和接收数据,但是通信都是由主设备发起,从设备被动响应,实现数据的传输。

二、总体特征

SDA 和SCL 都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压当总线空闲时,这两条线路都是高电平。连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。I²C总线上数据的传输速率在标准模式下可达100kbit/s, 在快速模式下可达400kbit/s, 在高速模式下可达3.4Mbit/s。 连接到总线的接口数量只由总线电容是400pF 的限制决定。

三、IIC协议时序

起始信号(S):当SCL为高电平时,SDA从高电平变为低电平。

停止信号(P):当SCL为高电平时,SDA从低电平变为高电平。

应答信号:上拉电阻影响下SDA默认为高,而从机拉低SDA就是确认收到数据即ACK,否则NACK。

注:1.数据先发送高位 2.数据以字节(8bit)传输 3.数据在SCL高电平稳定 4.空闲状态:高电平

四、代码编写

//起始信号
void iic_start(void)
{//SCL为高电平期间,SDA从高电平往低电平跳变
    IIC_SDA(1);
	IIC_SCL(1);
	iic_delay();//延时看从机(器件)
	IIC_SDA(0);
	iic_delay();
	IIC_SCL(0);
	iic_delay();//钳住总线,准备发送/接受数据
}
//停止信号
void iic_stop(void)
{//SCL为高电平期间,SDA从低电平往高电平跳变
	IIC_SDA(0);
	iic_delay();
	IIC_SCL(1);
	iic_delay();
	IIC_SDA(1);//发送总线停止信号
	iic_delay();
}
//发送应答信号
void iic_ack(void)
{
	IIC_SCL(0);
	iic_delay();
	IIC_SDA(0);//数据线变为低电平,表示应答
	iic_delay();
	IIC_SCL(1);
	iic_delay();
}
/*·¢ËÍ·ÇÓ¦´ðÐźÅ*/
void iic_nack(void)
{
	IIC_SCL(0);
	iic_delay();
	IIC_SDA(1);//数据线变为高电平,表示非应答
	iic_delay();
	IIC_SCL(1);
	iic_delay();
}
uint8_t iic_read_byte(uint8_t ack)//1:ack 0:nack
{
    uint8_t receive=0;
    for(uint8_t t=0;t<8;t++)
    {//高位先输出,先收到的数据位要左移
    receive<<=1;
    IIC_SCL(1);
    iic_delay();
    if(IIC_READ_SDA)receive++;
    IIC_SCL(0);
    iic_delay();
}
    if(!ack)iic_nack();
    else iic_ack();
    return receive;

五、IIC配置步骤

1、使能SCL和SDA对应时钟:__HAL_RCC_GPIOB_CLK_ENABLE()

2、设置GPIO工作模式:SDA开漏/SCL推挽输出模式,使用HAL_GPIO_Init初始化

3、编写基本信号:起始信号 停止信号 应答信号

主机:send ack/send nack 从机:wait ack

4、编写读和写函数:iic_read_byte/iic_send_byte

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32模拟IIC代码是在STM32单片机上实现IIC通讯协议的模拟仿真代码。下面以F103为例,以软件模拟IIC通信为主要讲解。 首先,我们需要定义IIC相关的GPIO引脚及其功能,以及一些IIC初始化函数。 ```c GPIO_InitTypeDef GPIO_InitStruct; void IIC_Init(void) { //使能GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //配置IIC_SCL引脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); //配置IIC_SDA引脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); //初始化IIC总线 IIC_Start(); IIC_Stop(); } void IIC_Start(void) { IIC_SDA_OUT(); IIC_SCL_HIGH(); IIC_SDA_HIGH(); IIC_DELAY(); IIC_SDA_LOW(); IIC_DELAY(); IIC_SCL_LOW(); } void IIC_Stop(void) { IIC_SDA_OUT(); IIC_SCL_LOW(); IIC_SDA_LOW(); IIC_DELAY(); IIC_SCL_HIGH(); IIC_DELAY(); IIC_SDA_HIGH(); } void IIC_SendByte(uint8_t data) { uint8_t i; IIC_SDA_OUT(); for (i = 0; i < 8; i++) { IIC_SCL_LOW(); if ((data & 0x80) == 0x80) IIC_SDA_HIGH(); else IIC_SDA_LOW(); data <<= 1; IIC_DELAY(); IIC_SCL_HIGH(); IIC_DELAY(); } IIC_SCL_LOW(); } uint8_t IIC_ReceiveByte(void) { uint8_t i, data = 0; IIC_SDA_IN(); for (i = 0; i < 8; i++) { IIC_SCL_LOW(); IIC_DELAY(); IIC_SCL_HIGH(); data <<= 1; if (IIC_READ_SDA()) data |= 0x01; IIC_DELAY(); } IIC_SCL_LOW(); return data; } ``` 以上代码是模拟IIC基本操作的函数,包括初始化IIC总线、启动和停止信号的发送、发送和接收数据等。其中,根据实际需求可能需要根据具体的GPIO引脚和时钟配置来修改。 在使用模拟IIC通信时,需要注意的是,STM32的I2C外设与模拟IIC通信并不相同。I2C外设直接在硬件层面上实现了I2C通信,而模拟IIC需要通过GPIO口的软件控制来模拟实现。所以在使用STM32模拟IIC时,需要禁用I2C外设,并根据实际需求修改代码中的引脚定义。 以上是关于STM32模拟IIC代码的基本讲解,通过使用这些函数,我们可以在STM32单片机上实现模拟IIC通信。当然,具体的代码实现可能会因为不同的项目需求而有所变化,需要根据实际情况进行修改与优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值