总线驱动-------IIC模拟时序驱动

对GPIO口的初始化

void GPIO_IIC_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6); 	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ;  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_7); 	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;  
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_10); 	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_11); 
}
```c
drv_i2c.h 

```c
#ifndef _DRV_I2C_H_
#define _DRV_I2C_H_
#include "sys.h"
typedef enum
{
  IIC1  = 0,
	IIC2  = 1
}IICType_e;
typedef enum
{
  IIC_R= 0,
	IIC_W
}RW_e;
typedef struct 
{
	  IICType_e iic;
    void (*set_sda)(IICType_e iic, uint8_t state);//out
    void (*set_scl)(IICType_e iic, uint8_t state);//out
    uint8_t (*get_sda)(IICType_e iic);//in
    uint8_t (*get_scl)(IICType_e iic); //in 
	  void (*rw_sda)(IICType_e iic,RW_e state);// config out/in
	  void (*rw_scl)(IICType_e iic,RW_e state);//config out/in
}ops_iic_t;
extern ops_iic_t iic1;
extern ops_iic_t iic2;
//IO·½ÏòÉèÖÃ
//#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
//#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

#define IIC1_SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define IIC1_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

#define IIC2_SDA_IN()  {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=(u32)8<<6;}
#define IIC2_SDA_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=(u32)3<<6;}
//IO²Ù×÷º¯Êý	 
#define IIC1_SCL    			PBout(6) //SCL
#define IIC1_SDA    			PBout(7) //SDA	 
#define READ_IIC1_SDA   	GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)//PBin(7)  //ÊäÈëSDA 
#define READ_IIC1_SCL   	PBin(6)  //ÊäÈëSDA 

#define IIC2_SCL    			PBout(10) //SCL
#define IIC2_SDA    			PBout(11) //SDA	 
#define READ_IIC2_SDA   	PBin(11)  //ÊäÈëSDA
#define READ_IIC2_SCL   	PBin(10)  //ÊäÈëSDA
//IICËùÓвÙ×÷º¯Êý
void IIC_Init(void);                //³õʼ»¯IICµÄIO¿Ú				 
void I2C_Start(ops_iic_t *ops);				//·¢ËÍIIC¿ªÊ¼ÐźÅ
void I2C_Stop(ops_iic_t *ops);	  			//·¢ËÍIICÍ£Ö¹ÐźÅ
void I2C_Send_Byte(ops_iic_t *ops,u8 txd);			//IIC·¢ËÍÒ»¸ö×Ö½Ú
u8 I2C_Read_Byte(ops_iic_t *ops,unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
u8 I2C_Wait_Ack(ops_iic_t *ops); 				//IICµÈ´ýACKÐźÅ
void I2C_Ack(ops_iic_t *ops);					//IIC·¢ËÍACKÐźÅ
void I2C_NAck(ops_iic_t *ops);				//IIC²»·¢ËÍACKÐźÅ

void I2C_Write_One_Byte(ops_iic_t *ops,u8 daddr,u8 addr,u8 data);
u8 I2C_Read_One_Byte(ops_iic_t *ops,u8 daddr,u8 addr);
#endif

drv_i2c

#include "drv_i2c.h"
ops_iic_t iic1;
ops_iic_t iic2;
static void IIC_SET_SDA(IICType_e iic,uint8_t state);
static void IIC_SET_SCL(IICType_e iic,uint8_t state);
static uint8_t IIC_GET_SDA(IICType_e iic);
static uint8_t IIC_GET_SCL(IICType_e iic);
static void IIC_RW_SDA(IICType_e iic,RW_e state);
static void IIC_RW_SCL(IICType_e iic,RW_e state);

static const ops_iic_t iic_ops_default =
{
 .iic = IIC1,
 .get_scl = IIC_GET_SCL,
 .get_sda = IIC_GET_SDA,
 .set_scl = IIC_SET_SCL,
 .set_sda = IIC_SET_SDA,
 .rw_scl  = IIC_RW_SCL,
 .rw_sda  = IIC_RW_SDA,
};
void IIC_Init(void)
{					     
 GPIO_IIC_Init();
 iic1 = iic_ops_default;
 iic2 = iic_ops_default;
 iic1.iic = IIC1;
 iic2.iic = IIC2;	
}
static void IIC_SET_SDA(IICType_e iic,uint8_t state)
{
  if(iic == IIC1)IIC1_SDA = state;
	else if(iic == IIC2)IIC2_SDA = state;
}
static void IIC_SET_SCL(IICType_e iic,uint8_t state)
{
  if(iic == IIC1)IIC1_SCL = state;
	else if(iic == IIC2)IIC2_SCL = state;
}
static uint8_t IIC_GET_SDA(IICType_e iic)
{
  if(iic == IIC1)return READ_IIC1_SDA;
	else if(iic == IIC2)return READ_IIC2_SDA;
}
static uint8_t IIC_GET_SCL(IICType_e iic)
{
  if(iic == IIC1)return READ_IIC1_SCL;
	else if(iic == IIC2)return READ_IIC2_SCL;
}
static void IIC_RW_SDA(IICType_e iic,RW_e state)
{
  if(iic == IIC1)
	{
		
	}
	else if(iic == IIC2)
	{

	}
}
static void IIC_RW_SCL(IICType_e iic,RW_e state)
{
  ;
}
void I2C_Start(ops_iic_t *ops)
{
	ops->rw_sda(ops->iic,IIC_W);
  ops->set_sda(ops->iic,1);	
	ops->set_scl(ops->iic,1);	
	delay_us(4);
	ops->set_sda(ops->iic,0);	
	delay_us(4);
	ops->set_scl(ops->iic,0);	
	delay_us(4);
}
void I2C_Stop(ops_iic_t *ops)
{
	ops->rw_sda(ops->iic,IIC_W);	
	ops->set_scl(ops->iic,0);	
	ops->set_sda(ops->iic,0);	
 	delay_us(4);
	ops->set_scl(ops->iic,1);	
	ops->set_sda(ops->iic,1);	
	delay_us(4);							   	
}
u8 I2C_Wait_Ack(ops_iic_t *ops)
{
	u8 ucErrTime=0;		
  ops->rw_sda(ops->iic,IIC_R);		
	ops->set_sda(ops->iic,1);	
	delay_us(1);	   
	ops->set_scl(ops->iic,1);	
	delay_us(1);	 
	while(ops->get_sda(ops->iic))
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			I2C_Stop(ops);
			return 1;
		}
	}
  ops->set_scl(ops->iic,0);		
	return 0;  
} 
void I2C_Ack(ops_iic_t *ops)
{
	ops->set_scl(ops->iic,0);	
	ops->rw_sda(ops->iic,IIC_W);	
	ops->set_sda(ops->iic,0);	
	delay_us(2);
	ops->set_scl(ops->iic,1);	
	delay_us(2);
	ops->set_scl(ops->iic,0);	
}
//²»²úÉúACKÓ¦´ð		    
void I2C_NAck(ops_iic_t *ops)
{
	ops->set_scl(ops->iic,0);	
	ops->rw_sda(ops->iic,IIC_W);	
	ops->set_sda(ops->iic,1);	
	delay_us(2);
	ops->set_scl(ops->iic,1);	
	delay_us(2);
	ops->set_scl(ops->iic,0);	
}					 				     		  
void I2C_Send_Byte(ops_iic_t *ops,u8 txd)
{
    u8 t;   
    ops->rw_sda(ops->iic,IIC_W);		
	  ops->set_scl(ops->iic,0);	
    for(t=0;t<8;t++)
    {              
		if((txd&0x80)>>7)
		 ops->set_sda(ops->iic,1);	
		else
		ops->set_sda(ops->iic,0);	
		txd<<=1; 	  
		delay_us(2);  
		ops->set_scl(ops->iic,1);	
		delay_us(2); 
		ops->set_scl(ops->iic,0);	
		delay_us(2);
    }		
} 	    
u8 I2C_Read_Byte(ops_iic_t *ops,unsigned char ack)
{	
	unsigned char i,receive=0;
	ops->rw_sda(ops->iic,IIC_R);
  ops->set_sda(ops->iic,1);	
    for(i=0;i<8;i++ )
	{
        ops->set_scl(ops->iic,0);			
        delay_us(2);
		    ops->set_scl(ops->iic,1);	
        receive<<=1; 
        if(ops->get_sda(ops->iic))receive++;		
		    delay_us(1); 
   }					 
    if (!ack)
        I2C_NAck(ops);
    else
        I2C_Ack(ops); 
    return receive;
}

注:delay_us()函数由自己实现;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值