手把手教你写IIC(要是学不会,来找我)(C语言)

本文详细解释了IIC电路的工作原理,包括起始、终止和应答信号的发送与检测,以及数据的一字节发送和读取方法,适用于250KHz速度下的串行通信。
摘要由CSDN通过智能技术生成

1.IIC电路原理图(由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空闲状态为高电平

注意:这里面最重要的的就是三个信号(起始信号,终止信号,应答信号)

 2us的延时, 读写速度在250Khz以内 

2.起始信号

SCL为高电平期间, SDA从高电平往低电平跳变

void IIC_Start(void)
{
    	IIC_SDA ( 1 );	
	    IIC_SCL ( 1 );
    	delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 	    IIC_SDA ( 0 );	
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
    	IIC_SCL ( 0 );	
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
        /* 钳住总线, 准备发送/接收数据 */
}

3.终止信号

SCL为高电平期间, SDA从低电平往高电平跳变

void IIC_Stop(void)
{ 
    	IIC_SDA ( 0 );	
	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 	    IIC_SCL ( 1 );	
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
    	IIC_SDA ( 1 ); 	/* 发送总线停止信号*/
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
}

4.主机检测应答信号

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

uint8_t IIC_WaitAck (void)        /* return 1:fail 0:succeed*/
{	
	IIC_SDA (1);  /* 主机释放SDA线 */
	delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
	IIC_SCL (1);  /* 从机返回ACK*/ 	
 	delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
	if ( IIC_READ_SDA ) /* SCL高电平读取SDA状态*/ 
	{
		iic_stop();	    /* SDA高电平表示从机nack */ 
		return 1;
	}
	IIC_SCL(0);	 /* SCL低电平表示结束ACK检查 */ 
 	delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
	return 0;
}

5.发送应答信号

void IIC_Ack(void)
{ 
    	IIC_SCL (0);	
	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 	    IIC_SDA (0);  /* 数据线为低电平,表示应答 */
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
    	IIC_SCL (1); 	
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
}

6.发送非应答信号 

void IIC_Nack(void)
{ 
    	IIC_SCL (0);	
	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 	    IIC_SDA (1);  /* 数据线为高电平,表示非应答 */
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
    	IIC_SCL (1); 	
 	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
}

7.发送一字节数据

 

void IIC_SendByte(uint8_t data)
{
	for (uint8_t t = 0; t < 8; t++)
	{	/* 高位先发 */
		IIC_SDA((data & 0x80) >> 7);
 		delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 		IIC_SCL ( 1 );	
 		delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
 		IIC_SCL ( 0 );
		data <<= 1; /* 左移1位, 用于下一次发送 */
	}
	IIC_SDA ( 1 ); 	/* 发送完成,主机释放SDA线 */ 
}

8.读取一字节 

uint8_t IIC_ReadByte (uint8_t ack) /* 1:ack 0:nack*/
{ 
	uint8_t receive = 0 ;
	for (uint8_t t = 0; t < 8; t++)
	{	
        /* 高位先输出,先收到的数据位要左移 */ 
		receive <<= 1;		
		IIC_SCL ( 1 );	
 		delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
		if ( IIC_READ_SDA ) receive++;
 		IIC_SCL ( 0 );
	    delay_us(2);    /* 2us的延时, 读写速度在250Khz以内 */
	}
	if ( !ack ) 
        IIC_Nack();
	else
        IIC_Ack();
	return receive; 	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值