#include "iic.h"
#include "delay.h"
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructer;
//使能IIC端口的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//初始化IO端口
GPIO_InitStructer.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //时钟线SCL为PB10,数据线SDA为PB11
GPIO_InitStructer.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructer.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOB,&GPIO_InitStructer);
GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11); //输出高电平
}
/******************************************************************
** 函数名称 : IIC_Start
** 函数功能 : 发送启动信号
** 入口参数 : 无
** 出口参数 : 无
** 函数说明 : 首先SCL和SDA都为高电平,然后在SCL为高电平的期间拉低SDA
******************************************************************/
void IIC_Start(void)
{
SDA_OUT();
IIC_SCL = 1;
IIC_SDA = 1;
delay_us(4);
IIC_SDA = 0;
delay_us(4);
}
/*******************************************************************
** 函数名称 : IIC_Stop
** 函数功能 : 发送停止信号
** 入口参数 : None
** 出口参数 : None
** 函数说明 : 刚开始的时候SDA为低电平,然后拉高SCL,在SCL为高电平的
情况下拉高SDA
*******************************************************************/
void IIC_Stop(void)
{
SDA_OUT();
IIC_SDA = 0;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SDA = 1;
delay_us(4);
}
/********************************************************************
** 函数名称 : IIC_Wait_Ack
** 函数功能 : 等待应答
** 入口参数 : None
** 出口参数 : 1:表示产生应答 0:表示没有产生应答
** 函数说明 : 刚开始的时候SCL和SDA都为高电平,然后判断在第九个周期的时候
SDA线是否被拉低,如果被拉低则成功写入
********************************************************************/
u8 IIC_Wait_Ack(void)
{
u8 temp = 0;
SDA_IN();
IIC_SCL = 1;
IIC_SDA = 1;
while(READ_SDA)
{
temp++;
if(temp > 250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL = 0;
return 0;
}
/***************************************************************
** 函数名称 : IIC_Response
** 函数功能 : 产生应答信号
** 入口参数 : None
** 出口参数 : None
** 函数说明 : 刚开始的时候SCL为低电平,SDA为高电平,然后拉低SDA
然后拉高SCL,最后再拉低SCL
***************************************************************/
void IIC_Response(void)
{
SDA_OUT();
IIC_SCL = 0;
IIC_SDA = 1;
delay_us(2);
IIC_SDA = 0;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
}
/***************************************************************
** 函数名称 : IIC_No_Response
** 函数功能 : 产生非应答信号
** 入口参数 : None
** 出口参数 : None
** 函数说明 : 刚开始的时候SCL为低电平,然后拉高SDA,然后再拉高SCL
最后再拉低SCL
***************************************************************/
void IIC_No_Response(void)
{
SDA_OUT();
IIC_SCL = 0;
delay_us(2);
IIC_SDA = 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
}
/***************************************************************
** 函数名称 : IIC_SendByte
** 函数功能 : 发送一字节的数据
** 入口参数 : None
** 出口参数 : None
** 函数说明 : 刚开始的时候SCL为低电平,然后拉高SDA最后再拉高SCL
***************************************************************/
void IIC_SendByte(u8 Dat)
{
u8 i;
SDA_OUT();
IIC_SCL = 0; //SCL为低电平
for(i = 0;i < 8;i++)
{
if((Dat << i) & 0x80) //如果数据左移一位然后与上0x80为真
IIC_SDA = 1;
else IIC_SDA = 0;
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
delay_us(2);
}
}
/***************************************************************
** 函数名称 : IIC_Read_Byte
** 函数功能 : 接收一字节的数据
** 入口参数 : Ack:1:发送应答
** 出口参数 : None
** 函数说明 : 读数据在数据稳定的时候读取即SCL为高电平的时候
***************************************************************/
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();
for(i = 0;i < 8;i++)
{
IIC_SCL = 0;
delay_us(2);
IIC_SCL = 1;
receive <<= 1;
if(READ_SDA) receive++;
delay_us(1);
}
if (!ack)
IIC_No_Response();//发送nACK
else
IIC_Response(); //发送ACK
return receive;
}
一步一步学32..........
|