IIC模拟代码
#define SCL_PORT GPIOC
#define SCL_PIN GPIO_Pin_6
#define SDA_PORT GPIOC
#define SDA_PIN GPIO_Pin_5
#define SCL_OUT_1(n) GPIO_SetBits( SCL_PORT, n ) //Êä³ö
#define SCL_OUT_0(n) GPIO_ResetBits( SCL_PORT, n ) //Êä³ö
#define SDA_OUT_1(n) GPIO_SetBits( SDA_PORT, n ) //Êä³ö
#define SDA_OUT_0(n) GPIO_ResetBits( SDA_PORT, n) //Êä³ö
#define SDA_IN(n) GPIO_ReadInputDataBit(SDA_PORT ,n) //ÊäÈë
//IO·½ÏòÉèÖÃ
//#define MPU_SDA_IN() {SetBit(((uint32_t)&M0P_GPIO->PADIR + SDA_PORT), SDA_PIN, (boolean_t)GpioDirIn);}
//#define MPU_SDA_OUT() {SetBit(((uint32_t)&M0P_GPIO->PADIR + SDA_PORT), SDA_PIN, (boolean_t)GpioDirOut);}
//IO²Ù×÷º¯Êý
#define MPU_IIC_SCL_0 SCL_OUT_0(SCL_PIN) //SCL 0
#define MPU_IIC_SDA_0 SDA_OUT_0(SDA_PIN) //SDA 0
#define MPU_READ_SDA SDA_IN(GPIO_Pin_5) //ÊäÈëSDA
//IO²Ù×÷º¯Êý
#define MPU_IIC_SCL_1 SCL_OUT_1(SCL_PIN) //SCL 1
#define MPU_IIC_SDA_1 SDA_OUT_1(SDA_PIN) //SDA 1
#define MPU_ADDR 0x12
//IICËùÓвÙ×÷º¯Êý
void MPU_IIC_Delay(void); //MPU IICÑÓʱº¯Êý
void hal_IIC_Init(void); //³õʼ»¯IICµÄIO¿Ú
void MPU_IIC_Start(void); //·¢ËÍIIC¿ªÊ¼ÐźÅ
void MPU_IIC_Stop(void); //·¢ËÍIICÍ£Ö¹ÐźÅ
uint8_t MPU_IIC_Send_Byte(uint8_t txd); //IIC·¢ËÍÒ»¸ö×Ö½Ú
uint8_t MPU_IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
uint8_t MPU_IIC_Wait_Ack(void); //IICµÈ´ýACKÐźÅ
void MPU_IIC_Ack(void); //IIC·¢ËÍACKÐźÅ
void MPU_IIC_NAck(void); //IIC²»·¢ËÍACKÐźÅ
extern uint8_t MPU_Write_Byte(uint8_t reg,uint8_t data); //IICдһ¸ö×Ö½Ú
extern uint8_t MPU_Read_Byte(uint8_t reg); //IIC¶ÁÒ»¸ö×Ö½Ú
void hal_IIC_Proc(void);
//ÅäÖÃÒý½ÅΪÊäÈë
void MPU_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //ÉèÖÃÒý½ÅģʽΪÊäÈë
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //ÎÞÆ«ÖÃ
///< ¶Ë¿Ú·½ÏòÅäÖÃ->ÊäÈë
GPIO_InitStructure.GPIO_Pin = SDA_PIN; //Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å
GPIO_Init(SDA_PORT, &GPIO_InitStructure); //µ÷Óÿ⺯Êý£¬³õʼ»¯GPIO
// SDA_PORT->OES =SDA_PIN;
// SDA_PORT->ODS = SDA_PIN;
}
//ÅäÖÃÒý½ÅΪÊä³ö
void MPU_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå
GPIO_InitStructure.GPIO_Mode = GPIO_OType_OD; //ÉèÖÃÒý½ÅģʽΪͨÓÃÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //ÎÞÆ«ÖÃ
///< ¶Ë¿Ú·½ÏòÅäÖÃ->ÊäÈë
GPIO_InitStructure.GPIO_Pin = SDA_PIN; //Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å
GPIO_Init(SDA_PORT, &GPIO_InitStructure); //µ÷Óÿ⺯Êý£¬³õʼ»¯GPIO
// SDA_PORT->OES = SDA_PIN;
// SDA_PORT->PDC = SDA_PIN;
// SDA_PORT->PUC = SDA_PIN;
}
//MPU IIC ÑÓʱº¯Êý
void MPU_IIC_Delay(void)
{
__nop();__nop();__nop();__nop();__nop();__nop();
}
//³õʼ»¯IIC
void hal_IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå
GPIO_InitStructure.GPIO_Mode = GPIO_OType_OD; //ÉèÖÃÒý½ÅģʽΪ¿ªÂ©
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //ÎÞÆ«ÖÃ
///< ¶Ë¿Ú·½ÏòÅäÖÃ->ÊäÈë
GPIO_InitStructure.GPIO_Pin = SDA_PIN; //Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å
GPIO_Init(SDA_PORT, &GPIO_InitStructure); //µ÷Óÿ⺯Êý£¬³õʼ»¯GPIO
GPIO_SetBits(SDA_PORT, SDA_PIN);
///< ¶Ë¿Ú·½ÏòÅäÖÃ->Êä³ö
GPIO_InitStructure.GPIO_Pin = SCL_PIN; //Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å
GPIO_Init(SCL_PORT, &GPIO_InitStructure); //µ÷Óÿ⺯Êý£¬³õʼ»¯GPIO
GPIO_SetBits(SCL_PORT, SCL_PIN);
MPU_IIC_SDA_1;
MPU_IIC_SCL_1;
MPU_IIC_Delay();
}
//²úÉúIICÆðʼÐźÅ
void MPU_IIC_Start(void)
{
MPU_SDA_OUT(); //sdaÏßÊä³ö
MPU_IIC_SDA_1;
MPU_IIC_SCL_1;
MPU_IIC_Delay();
MPU_IIC_SDA_0;//START:when CLK is high,DATA change form high to low
MPU_IIC_Delay();
MPU_IIC_SCL_0;//ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý
MPU_IIC_Delay();
}
//²úÉúIICÍ£Ö¹ÐźÅ
void MPU_IIC_Stop(void)
{
MPU_SDA_OUT();//sdaÏßÊä³ö
MPU_IIC_SCL_0;
MPU_IIC_SDA_0;//STOP:when CLK is high DATA change form low to high
MPU_IIC_Delay();
MPU_IIC_SCL_1;
MPU_IIC_SDA_1;//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
MPU_IIC_Delay();
}
uint8_t MPU_IIC_Wait_Ack(void)
{
uint16_t ucErrTime=0;
MPU_SDA_IN(); MPU_IIC_Delay();
MPU_IIC_SCL_1;MPU_IIC_Delay();
while(MPU_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
MPU_IIC_Stop();
return 1;
}
}
MPU_IIC_SCL_0;//????0
return 0;
}
//??ACK??
void MPU_IIC_Ack(void)
{
MPU_IIC_SCL_0;
MPU_SDA_OUT();
MPU_IIC_SDA_0;
MPU_IIC_Delay();
MPU_IIC_SCL_1;
MPU_IIC_Delay();
MPU_IIC_SCL_0;
}
//???ACK??
void MPU_IIC_NAck(void)
{
MPU_IIC_SCL_0;
MPU_SDA_OUT();
MPU_IIC_SDA_1;
MPU_IIC_Delay();
MPU_IIC_SCL_1;
MPU_IIC_Delay();
MPU_IIC_SCL_0;
}
uint8_t MPU_IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
MPU_SDA_OUT();
MPU_IIC_SCL_0;
for(t=0;t<8;t++)
{
if((txd<<t)&0x80)
MPU_IIC_SDA_1;
else
MPU_IIC_SDA_0;
MPU_IIC_Delay();
MPU_IIC_SCL_1;
MPU_IIC_Delay();
MPU_IIC_SCL_0;
MPU_IIC_Delay();
}
}
uint8_t MPU_IIC_Read_Byte(unsigned char ack)
{
uint8_t i,receive=0;
uint16_t ucErrTime=0;
MPU_SDA_IN();//SDA
for(i=0;i<8;i++ )
{
MPU_IIC_SCL_0;
MPU_IIC_Delay();
MPU_IIC_SCL_1;
receive<<=1;
if(MPU_READ_SDA)
receive++;
MPU_IIC_Delay();
}
return receive;
}
uint8_t MPU_Write_Str(uint8_t reg,uint8_t *s,uint8_t xn)
{
uint8_t i=0;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//
if(MPU_IIC_Wait_Ack()) return 0;
MPU_IIC_Send_Byte(reg); //
if(MPU_IIC_Wait_Ack()) return 0;
for(i=0;i<xn;i++)
{
MPU_IIC_Send_Byte(*s);
if(MPU_IIC_Wait_Ack()) return 0;
s++;
}
MPU_IIC_Stop();
return 1;
}
uint8_t MPU_Read_Byte(uint8_t reg)
{
uint8_t res;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//
if(MPU_IIC_Wait_Ack()) return 0;
MPU_IIC_Send_Byte(reg);
if(MPU_IIC_Wait_Ack()) return 0;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//
if(MPU_IIC_Wait_Ack()) return 0;
res=MPU_IIC_Read_Byte(0);//
MPU_IIC_NAck();
MPU_IIC_Stop(); //
return res;
}
uint8_t MPU_Read_Str(uint8_t reg,uint8_t *s,uint8_t xn)
{
uint8_t i=0;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//
if(MPU_IIC_Wait_Ack()) return 0;
MPU_IIC_Send_Byte(reg);
if(MPU_IIC_Wait_Ack()) return 0;
MPU_IIC_Start();
MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//
if(MPU_IIC_Wait_Ack()) return 0;
for(i=0;i<xn;i++)
{
*s=MPU_IIC_Read_Byte(0);//
MPU_IIC_Ack();
s++;
}
*s=MPU_IIC_Read_Byte(0);//
MPU_IIC_NAck();
MPU_IIC_Stop(); //
return 1;
}