iic.h
#ifndef _IIC_H
#define _IIC_H
#include "stm32f10x_conf.h"
/*
PB6 SCL
PB7 SDA
*/
extern void IIC_Init(void);
extern void IIC_Start(void);
extern void IIC_Stop(void);
extern void IIC_ACK(void);
extern void IIC_NACK(void);
extern u8 IIC_Wait_ACK(void);
extern void IIC_Send_Byte(u8 data);//发送数据
extern u8 IIC_Recv_Byte(u8 ack);//接受数据
#endif
iic.c
#include"iic.h"
#include"bitband.h"
#include"delay.h"
#define IIC_SCL PBOut(6)
#define IIC_SDA PBOut(7)
#define IIC_SDA_In PBIn(7)
GPIO_InitTypeDef IIC_SCL_Init;//时钟线初始化
GPIO_InitTypeDef IIC_SDA_Out_Init;//数据线初始化
GPIO_InitTypeDef IIC_SDAI_in_Init;//数据线初始化
void IIC_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
IIC_SCL_Init.GPIO_Mode=GPIO_Mode_Out_PP;
IIC_SCL_Init.GPIO_Pin=GPIO_Pin_6;
IIC_SCL_Init.GPIO_Speed=GPIO_Speed_50MHz;//设置接口速度
GPIO_Init(GPIOB ,&IIC_SCL_Init);
IIC_SDA_Out_Init.GPIO_Mode=GPIO_Mode_Out_PP;
IIC_SDA_Out_Init.GPIO_Pin=GPIO_Pin_7;
IIC_SDA_Out_Init.GPIO_Speed=GPIO_Speed_50MHz;//设置接口速度
GPIO_Init(GPIOB ,&IIC_SDA_Out_Init);
IIC_SDAI_in_Init.GPIO_Mode=GPIO_Mode_IPU;
IIC_SDAI_in_Init.GPIO_Pin=GPIO_Pin_7;
IIC_SDAI_in_Init.GPIO_Speed=GPIO_Speed_50MHz;//设置接口速度
IIC_SCL=1;
IIC_SDA=1;
}
void IIC_Sda_Out(void)
{
GPIO_Init(GPIOB,&IIC_SDA_Out_Init);
}
void IIC_Sda_In(void)
{
GPIO_Init(GPIOB,&IIC_SDAI_in_Init);
}
void IIC_Start(void)//开始
{
IIC_Sda_Out();//输出
IIC_SCL=1;//拉高时钟线
IIC_SDA=1;//拉高数据线
delay_us(2);//延时2微秒
IIC_SDA=0;//拉低数据线
delay_us(2);
IIC_SCL=1;//拉高时钟线
}
void IIC_Stop(void)//结束
{
IIC_Sda_Out();
IIC_SCL=0;//拉低
IIC_SDA=0;//拉低
delay_us(2);
IIC_SCL=1;//拉高
delay_us(2);
IIC_SDA=1;//拉高
}
void IIC_ACK(void)
{
IIC_SCL=0;//拉低
IIC_Sda_Out();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;//拉高
delay_us(2);
IIC_SCL=0;//拉低
}
void IIC_NACK(void)
{
IIC_SCL=0;//拉低
IIC_Sda_Out();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;//拉高
delay_us(2);
IIC_SCL=0;//拉低
}
u8 IIC_Wait_ACK(void)//等待ACK
{
u8 TimeErr=0;
IIC_Sda_In();
IIC_SCL=0;//拉低
delay_us(1);
IIC_SCL=1;//拉高
delay_us(1);
while(IIC_SDA_In)//超时处理
{
TimeErr++;
if(TimeErr>250)
{
IIC_Stop();
return 1;//没有等到ACK
}
}
IIC_SCL=0;//拉低
return 0;//等到ACK
}
void IIC_Send_Byte(u8 data)//发送数据
{
u8 i=0;
IIC_Sda_Out();//输出
for(i=0;i<8;i++)
{
IIC_SCL=0;//拉低
delay_us(1);
IIC_SDA=(data&0x80)>>7;
data<<=1;
delay_us(1);
IIC_SCL=1;//拉高
delay_us(2);
}
IIC_SCL=0;//拉低
}
u8 IIC_Recv_Byte(u8 ack)//接收数据
{
u8 i=0,tmp=0;
IIC_Sda_In();//输入模式
for(i=0;i<8;i++)
{
IIC_SCL=0;//拉低
delay_us(2);
IIC_SCL=1;//拉高
delay_us(2);
tmp<<=1;
if(IIC_SDA_In)
tmp|=1;
}
IIC_SCL=0;
if(ack)//形参是1产生ACK
IIC_ACK();
else
IIC_NACK();
return tmp;
}