stm32f103实现常用模拟IIC


#define SDA_IN() {GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=(u32)3<<28;}

#define IIC_SCK PAout(4)
#define IIC_SDA PAout(7)
#define READ_SDA PAin(7)

 

void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTA,PORTE时钟
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
IIC_SCK = 1;
IIC_SDA = 1;
}

void SDA_OUT_1(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SDA_IN_1(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void IIC_Start(void)
{
SDA_OUT();
//SDA_OUT_1();
IIC_SDA = 1;
IIC_SCK = 1;
delay_us(4);
IIC_SDA = 0;
delay_us(4);
IIC_SCK=0;
}

void IIC_Stop(void)
{
SDA_OUT();
//SDA_OUT_1();
IIC_SCK = 0;
IIC_SDA = 0;
delay_us(4);
IIC_SCK = 1;
IIC_SDA = 1;
delay_us(4);
}

unsigned char IIC_ReadAck(void)
{
unsigned char i=0,uctemp=0;

SDA_IN();
//SDA_IN_1();
IIC_SDA = 1;
delay_us(1);
IIC_SCK = 1;
delay_us(1);
while(READ_SDA)
{
i++;
if(i > 250)
{
IIC_Stop();
return 0;
}
}
IIC_SCK = 0;

return 1;
}

void IIC_WriteByte(unsigned char ucByte)
{
unsigned char ucloop;

SDA_OUT();
//SDA_OUT_1();
IIC_SCK = 0;
for(ucloop=0;ucloop<8;ucloop++)
{
if((ucByte&0x80)>>7)
IIC_SDA = 1;
else
IIC_SDA = 0;
ucByte <<=1;
delay_us(2);
IIC_SCK = 1;
delay_us(2);
IIC_SCK = 0;
delay_us(2);
}
}

unsigned char IIC_ReadByte(void)
{
unsigned char uctemp=0;
unsigned char ucloop;

SDA_IN();
//SDA_IN_1();
IIC_SCK = 0;
for(ucloop=0;ucloop<8;ucloop++)
{
IIC_SCK = 0;
delay_us(2);
IIC_SCK = 1;
uctemp <<= 1;
if(READ_SDA)
uctemp++;
delay_us(1);
}

return (uctemp);
}

unsigned char CommandDataWrite(unsigned char ucCommand,unsigned char ucData)
{
unsigned char uctemp1,uctemp2;

IIC_Start();

IIC_WriteByte(ucCommand);
uctemp1 = IIC_ReadAck();
IIC_WriteByte(ucData);
uctemp2=IIC_ReadAck();
IIC_Stop();

if((uctemp1+uctemp2)>0)
return 1;
else
return 0;
}

unsigned char CommandDataRead(unsigned char ucCommand,unsigned char * pucData)
{
unsigned char uctemp1,uctemp2;

IIC_Start();
IIC_WriteByte(ucCommand);
uctemp1 = IIC_ReadAck();
*pucData = IIC_ReadByte(); //IIC_WriteByte(ucData);
uctemp2 = IIC_ReadAck();
IIC_Stop();

if((uctemp1+uctemp2)>0)
return 1;
else
return 0;
}

 

注意: 在SDA进行输入输出口切换时,使用寄存器操作!!!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM