这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 适合STM32芯片的模拟IIC总线的源代码

共5条 1/1 1 跳转至

适合STM32芯片的模拟IIC总线的源代码

工程师
2020-09-04 15:15:09     打赏



/*****************************IIC通信协议***************************/

#define _IIC11

#define _IIC20


#define IIC1_SCLPB6

#define IIC1_SDAPB7


#define IIC2_SCL PB10

#define IIC2_SDAPB11


#if _IIC1

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

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

#endif


#if _IIC2

#define SDA_IN(){GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= (u32)8<<12;}

#define SDA_OUT(){GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= (u32)3<<12;}

#endif


#define IIC1_SCL_HighwriteGpioHigh(IIC1_SCL)

#define IIC1_SCL_LowwriteGpioLow(IIC1_SCL)

#define IIC1_SDA_HighwriteGpioHigh(IIC1_SDA)

#define IIC1_SDA_LowwriteGpioLow(IIC1_SDA)


#define IIC2_SCL_HighwriteGpioHigh(IIC2_SCL)

#define IIC2_SCL_LowwriteGpioLow(IIC2_SCL)

#define IIC2_SDA_HighwriteGpioHigh(IIC2_SDA)

#define IIC2_SDA_LowwriteGpioLow(IIC2_SDA)


void iicStart(void)

{

SDA_OUT();    //sda线输出

IIC1_SCL_High;

IIC1_SDA_High;

delayNop(2);

IIC1_SDA_Low;

delayNop(2);

IIC1_SCL_Low;   //钳住I2C总线,准备发送或接收数据 

}


void iicStop(void)

{

SDA_OUT();     //sda线输出

IIC1_SDA_Low;

IIC1_SCL_Low;

delayNop(2);

IIC1_SCL_High;

IIC1_SDA_High;

delayNop(2);

}


u8 iicWaitAck(void)

{

u8 errorAck = 0;

SDA_IN();

IIC1_SCL_High;

delayNop(2);

IIC1_SDA_High;

delayNop(2);

while( GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == Bit_SET )

{

errorAck++;

if(errorAck > 250)

{

iicStop();

return 0;

}

}

IIC1_SCL_Low;

return 1;

}


//产生应答

void iicACK(void)

{

IIC1_SCL_Low;

SDA_OUT();

IIC1_SDA_Low;

delayNop(2);

IIC1_SCL_High;

delayNop(2);

IIC1_SCL_Low;

}


void iicNOack(void)

{

IIC1_SCL_Low;

SDA_OUT();

IIC1_SDA_High;

delayNop(2);

IIC1_SCL_High;

delayNop(2);

IIC1_SCL_Low;

}



void iicWrite_Byte(u8 byte)

{

u8 i;

SDA_OUT();

IIC1_SCL_Low;

for(i = 0; i < 8; i++)

{

if( (byte&0x80) == 0x80 )

{

IIC1_SDA_High;

}

else

{

IIC1_SDA_Low;

}

byte <<= 1;

delayNop(2);

IIC1_SCL_High;

delayNop(2);

IIC1_SCL_Low;

delayNop(2);

}

}


//读1个字节(高位开始读),ack=1时,发送ACK,ack=0,发送nACK  

//在C语言中x<<=1等于x=x<<1,是把x左移1位以后值保存回x里,x发生变化了

u8 iicRead_Byte(unsigned char ack)

{

u8 i;

u8 recvByte = 0;

SDA_IN();

for(i = 0; i < 8; i++)

{

IIC1_SCL_Low;

delayNop(2);

recvByte <<= 1;//高位开始读,所以左移

if( GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == Bit_SET )

{

recvByte |= 0x01; 

}

delayNop(2);

}


if(ack)

{

iicACK();

}

else

{

iicNOack();

}

return recvByte;

}


//------- 延时子程序

//系统时钟为24M时

//count = 200时,时间约等于100us

void delayNop(u32 count)

{

while(count -- > 0)

{

__NOP();

}

}





关键词: 源码     I2C     IIC    

工程师
2020-09-04 15:40:01     打赏
2楼

GOOD! stm32可以直接用了!


工程师
2020-09-04 15:42:52     打赏
3楼

楼主实测过?


工程师
2020-09-04 15:46:16     打赏
4楼

stm32 一般不是自带I2C 硬件总线吗? 干嘛要软件的方式来模拟时序啊


工程师
2020-09-04 15:49:46     打赏
5楼

我用过STM32的硬件,确实还是模拟的方式简单和靠谱


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]