对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()函数由自己实现;