模拟标准I2C的驱动

模拟I2C标准驱动,使用NRF52832工程为例进行说明

  • 头文件内容
#ifndef __IIC_H__
#define __IIC_H__

#include "nrf_drv_gpiote.h"
#include "nrf_delay.h"
#ifdef __cplusplus
extern "C" {
#endif


#define KSCL		23
#define KSDA		22

#define delay_us_iic nrf_delay_us

#define	 SCL_IIC_1	 nrf_gpio_cfg_input(KSCL,NRF_GPIO_PIN_PULLUP) 
#define	 SCL_IIC_0	do {\
	nrf_gpio_cfg_output(KSCL);\
	nrf_gpio_pin_clear(KSCL); \
}while(0)

#define	 SDA_IIC_1	nrf_gpio_cfg_input(KSDA,NRF_GPIO_PIN_PULLUP)  
#define	 SDA_IIC_0	do { \
	nrf_gpio_cfg_output(KSDA);\
	nrf_gpio_pin_clear(KSDA); \
}while(0)


#define	 SCL_IIC_READ	nrf_gpio_pin_read(KSCL)	
#define	 SDA_IIC_READ	nrf_gpio_pin_read(KSDA)	

void siic_init(void);
#ifdef __cplusplus
           }
#endif
#endif

  • I2C IO初时化
/**
 * @brieaf i2c初时化io引脚
*/
void siic_init(void)
{
    //SDA SCL
    nrf_gpio_pin_set(KSDA);
    nrf_gpio_pin_set(KSCL); 
    nrf_gpio_cfg_output(KSDA);    
	nrf_gpio_cfg_output(KSCL);
}
  • SCL输出高函数
/**
 * @brieaf 时钟线拉高
 * @retval    0-时钟线操作正常
 *            1-时钟线异常
*/
static uint8_t SCL_IIC_SET(void )
{
	    
	SCL_IIC_1;
	delay_us_iic(1);
	//clock stretching/
 	 uint32_t	ucErrTime = HW_TIMEOUT;	
	if(!SCL_IIC_READ)
	{
			while(!SCL_IIC_READ)
			{
				if(--ucErrTime == 0)
				{		
						return 1;	
				}
			}	
				
	}
	return 0;
		
}
  • I2C启动信号
/**
 * @brieaf 产生IIC起始信号
 *         START:when CLK is high,DATA change form high to low
*/ 
void IIC_Start(void)
{	 
	SDA_IIC_1;	  	  
	SCL_IIC_SET();
	delay_us_iic(5);
 	SDA_IIC_0;
	delay_us_iic(5);
	SCL_IIC_0;
}	  
  • I2C停止信号
/**
 * @brieaf 产生IIC停止信号
 *         STOP:when CLK is high DATA change form low to high
*/
void IIC_Stop(void)
{
	SCL_IIC_0;
	SDA_IIC_0;
 	delay_us_iic(5);
	SCL_IIC_SET();
	delay_us_iic(5);	
	SDA_IIC_1;//发送I2C总线结束信号
	delay_us_iic(5);	
}
  • 等待I2C应答信号
/** 
 * @brieaf 等待应答信号到来
 *  @retval  1,接收应答失败
 *           0,接收应答成功
 * /
uint8_t IIC_Wait_Ack(void)
{

		SDA_IIC_1;
		delay_us_iic(1);	   
		//clock stretching/
		if( SCL_IIC_SET() )
		{				
				IIC_Stop();
				return 1;										
		}
	  
		delay_us_iic(1);						
	   uint32_t	ucErrTime = HW_TIMEOUT;					
		while(SDA_IIC_READ)
		{
			
			if(--ucErrTime == 0)
			{	
				IIC_Stop();
				return 1;
			}
		}
		/
		SCL_IIC_0;   
		return 0; 
	
} 
  • I2C应答信号
/**
 * @brieaf 产生ACK应答
 * /
void IIC_Ack(void)
{
	SCL_IIC_0;
	SDA_IIC_0;
	delay_us_iic(2);
	SCL_IIC_SET();
	delay_us_iic(2);
	SCL_IIC_0;
}
  • I2C无应答信号
/**
 * @brieaf 不产生ACK应答		  
 * /  
void IIC_NAck(void)
{
	SCL_IIC_0;
	SDA_IIC_1;
	delay_us_iic(2);
	SCL_IIC_SET();
	delay_us_iic(2);
	SCL_IIC_0;
}			
  • 发送一个字节数据
/**
* @brieaf IIC发送一个字节
* @param[in] txd -要发送的数据
* @retval 1-有应答
*         0-无应答
* /			  
void IIC_Send_Byte(unsigned char txd)
{   
    SCL_IIC_0;
    for(uint8_t t=0;t<8;t++)
    {              
		if((txd&0x80)>>7)
		{
			SDA_IIC_1;
		}
		else
		{
			SDA_IIC_0;
		}
		txd<<=1; 	  
		SCL_IIC_SET();
		SCL_IIC_0;	
    }	
} 	  
  • 接收一个字节数据
/**
* @brieaf 接收一个字节数据
* @param[in] ack 1-产生ACK
*                0-产生NACK
*/
uint8_t IIC_Read_Byte(unsigned char ack)
{	
	uint8_t receive=0;
	SDA_IIC_1; 				
    for(uint8_t i=0;i<8;i++ )
	{
		SCL_IIC_0; 				
		SCL_IIC_SET();
        receive<<=1;
        if(SDA_IIC_READ)
		{
				receive|=0X01;
		} else
		{
				receive&=0XFE; 	
		}					
    }	
	SCL_IIC_0;	
    if (!ack)
        IIC_NAck();
    else
        IIC_Ack();   
    return receive;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值