#include "stm32f10x.h"
#include "GPIO.h"
#include "delay.h"
#include "IIC.h"
//------------------------------------
void IIC_Start(void); //起始信号
void IIC_Stop(void); //停止信号
void IIC_SendAck(u8 ack); //应答ACK
u8 IIC_WaitAck(void); //读ack
void IIC_SendByte(u8 dat); //IIC单个字节写
u8 IIC_ReceiveByte(void); //IIC单个字节读
uint16_t SDA_GPIO_Pin;
uint16_t SCL_GPIO_Pin;
GPIO_TypeDef *IIC_GPIOx;
void IIC_Init(GPIO_TypeDef *GPIOx, uint16_t SCL_GPIO_Pin_n, uint16_t SDA_GPIO_Pin_n)
{
SDA_GPIO_Pin = SDA_GPIO_Pin_n;
SCL_GPIO_Pin = SCL_GPIO_Pin_n;
IIC_GPIOx = GPIOx;
GPIOx_Output(GPIOx, SCL_GPIO_Pin_n | SDA_GPIO_Pin_n, GPIO_Speed_50MHz, GPIO_Mode_Out_PP);
}
//SDA 输出
void SDA_Out()
{
// GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitStructure.GPIO_Pin = SDA_GPIO_Pin;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);
GPIOx_Output(IIC_GPIOx, SCL_GPIO_Pin | SDA_GPIO_Pin, GPIO_Speed_50MHz, GPIO_Mode_Out_PP);
}
//SDA 输入
void SDA_In()
{
// GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitStructure.GPIO_Pin = SDA_GPIO_Pin;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
// GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);
GPIOx_Input(IIC_GPIOx, SDA_GPIO_Pin, GPIO_Mode_IPU);
}
/**************************************
起始信号
**************************************/
void IIC_Start(void)
{
SDA_Out();
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1); //拉高数据线
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线
Delay_Nus(5); //延时
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0); //数据线产生下降沿
Delay_Nus(5);
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线
}
/**************************************
结束信号
**************************************/
void IIC_Stop(void)
{
SDA_Out();
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0); //拉低数据线
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线
Delay_Nus(5);
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1); //数据线产生上升沿
Delay_Nus(5);
}
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void IIC_SendAck(u8 ack)
{
SDA_Out();
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, ack); //ack
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线
Delay_Nus(5);
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线
Delay_Nus(5);
}
u8 IIC_WaitAck(void) //返回值=1表示有ACK; //返回值=0表示无ACK.
{
u8 mcy;
SDA_In();
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线
Delay_Nus(5);
mcy = GPIOx_getValue(IIC_GPIOx, SDA_GPIO_Pin);
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线
Delay_Nus(5);
SDA_Out();
return mcy;
}
void IIC_SendByte(u8 SendByte) //数据从高位MSB到低位LSB发送
{
u8 i=8;
SDA_Out();
while(i--)
{
//GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线, SCL为低电平SDA才可以变动
// Delay_Nus(1);
if(SendByte&0x80)
{
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1); //SDA数据
}
else
{
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0); //SDA数据
}
SendByte<<=1;
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线,
Delay_Nus(5);
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线
Delay_Nus(5);
}
IIC_WaitAck();
}
u8 IIC_ReceiveByte(void) //数据从高位到低位
{
u8 i=8;
u8 ReceiveByte=0;
SDA_In();
GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1); //SDA上拉,准备接受数据;
while(i--)
{
ReceiveByte<<=1;
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1); //拉高时钟线,
Delay_Nus(5);
if(GPIOx_getValue(IIC_GPIOx, SDA_GPIO_Pin))
{
ReceiveByte|=0x01;
}
GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0); //拉低时钟线
Delay_Nus(5);
}
SDA_Out();
return ReceiveByte;
}
评论0