0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32 IO口模拟I2C(附源代码)

如意 来源:CSDN、博客园 作者:CSDN、博客园 2021-07-23 10:55 次阅读

STM32 IO口模拟I2C(附源代码)

I2C英文名为inter-Integrated Circuit,是用于多设备通讯的两线式串行总线,分为主机Master和从机Slave,通常有一个主机和多个从机,从机之间可通过地址进行区分,不同种类的设备地址不同。I2C分别是时钟线SCL和数据线SDA,其中SCL和SDA由主机控制,可设置成开漏输出模式。

STM32 IO口模拟I2C实例代码1:

#define IIC_SCL_1 GPIO_SetBits(GPIOB, GPIO_Pin_6) /* SCL = 1 */

#define IIC_SCL_0 GPIO_ResetBits(GPIOB, GPIO_Pin_6) /* SCL = 0 */

#define IIC_SDA_1 GPIO_SetBits(GPIOB, GPIO_Pin_7) /* SDA = 1 */

#define IIC_SDA_0 GPIO_ResetBits(GPIOB, GPIO_Pin_7) /* SDA = 0 */

#define IIC_READ_SDA() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) /* 读SDA口线状态 */

//初始化IIC

void IIC_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

IIC_Stop();

}

//产生IIC起始信号

//SCL为高电平时SDA由高变低

void IIC_Start(void)

{

IIC_SDA_1;

IIC_SCL_1;

delay_us(4);

IIC_SDA_0;

delay_us(4);

IIC_SCL_0;

}

//产生IIC停止信号

//SCL为高电平时SDA由低变高

//IIC空闲时SCL和SDA均输出高电平,这样不会干扰其他设备的收发

void IIC_Stop(void)

{

IIC_SDA_0;

IIC_SCL_1;

delay_us(4);

IIC_SDA_1;

}

//等待应答信号到来

//返回值:1,接收应答失败

// 0,接收应答成功

uint8_t IIC_WaitAck(void)

{

uint8_t errCount = 0;

uint8_t ack = 0;

IIC_SDA_1;

delay_us(4);

IIC_SCL_1;

delay_us(4);

while(IIC_READ_SDA())

{

errCount++;

if(errCount 》 250){

ack = 1;

break;

}

}

IIC_SCL_0;

return ack;

}

//产生应答ACK

//SCL为高电平时SDA为低电平表示应答

void IIC_Ack(void)

{

IIC_SDA_0;

delay_us(4);

IIC_SCL_1;

delay_us(4);

IIC_SCL_0;

delay_us(4);

IIC_SDA_1; //释放SDA

}

//产生非应答NACK

//SCL为高电平时SDA为高电平表示非应答

void IIC_NAck(void)

{

IIC_SDA_1;

delay_us(4);

IIC_SCL_1;

delay_us(4);

IIC_SCL_0;

delay_us(4);

}

//IIC发送一个字节

void IIC_WriteByte(uint8_t txd)

{

uint8_t i;

IIC_SCL_0;

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

{

(txd & 0x80) ? IIC_SDA_1 : IIC_SDA_0;

txd 《《= 1;

delay_us(4);

IIC_SCL_1;

delay_us(4);

IIC_SCL_0;

delay_us(4);

}

IIC_SDA_1;

}

//读1个字节,ack=1时,发送ACK,ack=0,发送NACK

uint8_t IIC_ReadByte(uint8_t ack)

{

uint8_t i, rcv = 0;

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

{

rcv 《《= 1;

IIC_SCL_1;

delay_us(4);

if(IIC_READ_SDA()){

rcv++;

}

IIC_SCL_0;

delay_us(4);

}

ack ? IIC_Ack() : IIC_NAck();

return rcv;

}

STM32 IO口模拟I2C实例代码2:

#define I2C_Speed 100000#define I2C_EE I2C1#define uStatus 0x80#define dTime 5#define I2C_EE_GPIO GPIOB#define I2C_EE_SCL GPIO_Pin_5#define I2C_EE_SDA GPIO_Pin_4#define I2C_EE_CLK RCC_APB1Periph_I2C1#define SCL_H GPIOB-》BSRR = GPIO_Pin_5#define SCL_L GPIOB-》BRR = GPIO_Pin_5#define SDA_H GPIOB-》BSRR = GPIO_Pin_4#define SDA_L GPIOB-》BRR = GPIO_Pin_4#define SCL_read GPIOB-》IDR & GPIO_Pin_5#define SDA_read GPIOB-》IDR & GPIO_Pin_4static unsigned int cntForInitial = 0;static unsigned char fSigStatus = 0;//static bool LedStatus = true;void I2C_Init(){GPIO_InitTypeDef GPIO_InitStructure;//* Configure I2C_EE pins: SCL and SDAGPIO_InitStructure.GPIO_Pin = I2C_EE_SCL | I2C_EE_SDA;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_Init(I2C_EE_GPIO, &GPIO_InitStructure);}static void i2c_start(){SDA_H;SCL_H;DelayUs(dTime);SDA_L;DelayUs(dTime);SCL_L;DelayUs(dTime);// LedStatus = !LedStatus;//f_LCT1(LedStatus);}/*******************************************************************Fuction:Stop i2c*******************************************************************/static void i2c_stop(){SDA_L;SCL_H;DelayUs(dTime);SDA_H;DelayUs(dTime);SCL_H;DelayUs(dTime);}/*******************************************************************Fuction:i2c Master wait for ackOnly ack*******************************************************************/static unsigned char i2c_rd_ack(){unsigned char flag = 0;SDA_H;SCL_H;DelayUs(dTime/2);flag = SDA_read;DelayUs(dTime/2);SCL_L;DelayUs(dTime/2);if(flag == 1)return 0;return 1;}/*******************************************************************Fuction:i2c Byte transmissionOnly Send,no ack,no stop*******************************************************************/static unsigned char i2c_sb(unsigned char Byte){unsigned char cnt;SCL_L;for(cnt=0;cnt《8;cnt++){if(Byte&0x80)SDA_H;elseSDA_L;DelayUs(dTime);SCL_H;DelayUs(dTime);SCL_L;Byte 《《= 1;DelayUs(dTime);}return i2c_rd_ack();}/*******************************************************************Fuction:i2c Byte receiveReturn Byte*******************************************************************/static unsigned char i2c_rb(){unsigned char cnt;unsigned char Byte=0;SDA_H;for(cnt=0;cnt《8;++cnt){Byte 《《= 1;DelayUs(dTime);SCL_H;DelayUs(dTime);if(SDA_read)Byte |= 0x01;SCL_L;DelayUs(dTime);}return Byte;}/*******************************************************************Fuction:i2c ACK Master send*******************************************************************/static void i2c_wr_ack(unsigned char ACK){if(ACK)SDA_H;elseSDA_L;SCL_H;DelayUs(dTime);SCL_L;DelayUs(dTime);}/*******************************************************************Fuction:i2c Byte receiveReturn Byte*******************************************************************/uint8_t ReadReg(unsigned int addr){uint8_t temp;i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((uint8_t)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((uint8_t)(addr & 0xFF))){i2c_stop();return 0;}i2c_start();if(!i2c_sb(BRG_DEV_ADDR |0x01)){i2c_stop();return 0;}temp = i2c_rb();i2c_wr_ack(1);i2c_stop();return temp;}unsigned char WriteReg8(unsigned int addr,unsigned char wData){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData))){i2c_stop();return 0;}i2c_stop();//DelayUs(1);return 1; }unsigned char WriteReg16(unsigned int addr,unsigned char wData1,unsigned char wData2){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData2))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData1))){i2c_stop();return 0;}i2c_stop();DelayUs(1);return 1; }unsigned char WriteReg32(unsigned int addr,unsigned char wData1,unsigned char wData2,unsigned char wData3,unsigned char wData4){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData4))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData3))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData2))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData1))){i2c_stop();return 0;}i2c_stop();DelayUs(1);return 1;}

以上是STM32 IO口模拟I2C的源代码,希望对用户有所帮助。

本文整合自CSDN、博客园

责编AJX

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2265

    文章

    10870

    浏览量

    354716
  • 源代码
    +关注

    关注

    96

    文章

    2944

    浏览量

    66659
收藏 人收藏

    评论

    相关推荐

    RISC V的I2C操作

    _scl_write(system_i2c_0_io_scl_write),.system_i2c_0_io_scl_read(system_i2c_0_io_scl_read),WriteEnable信号的处理
    的头像 发表于 11-01 11:06 121次阅读

    I2C协议的基础知识

    本文从I2C协议的概述开始,描述协议的历史、不同速度模式、物理层和数据帧结构,最后介绍I2C混合电压系统中电平兼容性以及上拉电阻大小计算。
    的头像 发表于 10-22 15:51 282次阅读
    <b class='flag-5'>I2C</b>协议的基础知识

    了解I2C总线

    电子发烧友网站提供《了解I2C总线.pdf》资料免费下载
    发表于 10-08 11:13 1次下载
    了解<b class='flag-5'>I2C</b>总线

    I2C基本指南

    电子发烧友网站提供《I2C基本指南.pdf》资料免费下载
    发表于 09-10 09:40 0次下载
    <b class='flag-5'>I2C</b>基本指南

    如何通过I2C加载TPS2388x SRAM和奇偶校验代码

    电子发烧友网站提供《如何通过I2C加载TPS2388x SRAM和奇偶校验代码.pdf》资料免费下载
    发表于 09-06 11:16 0次下载
    如何通过<b class='flag-5'>I2C</b>加载TPS2388x SRAM和奇偶校验<b class='flag-5'>代码</b>

    在用STM32的SPI和I2C时,是用I/O模拟还是片内外设?

    大家一起来聊一聊在用STM32的SPI和I2C时,用I/O模拟多些还是片内外设,用查询方式还是中断方式。
    发表于 05-16 08:29

    请问数字(硬件)I2C模拟I2C的优缺点?

    请教哈各位同仁: 1. 数字(硬件)I2C模拟I2C的优缺点? 2.他们在正常模式下的功耗对比,哪个较好?
    发表于 05-13 06:10

    如何根据时序图编写高效IO模拟I2C程序

    I2C的读写字节是这么定义的:当时钟线为低电平的时候,允许修改数据线的电平状态,在时钟线为高电平的时候读取数据线的状态。
    的头像 发表于 04-06 03:05 3595次阅读
    如何根据时序图编写高效<b class='flag-5'>IO</b><b class='flag-5'>模拟</b><b class='flag-5'>I2C</b>程序

    STM32F103普通IO模拟通信协议如I2C,SPI,串口,怎么精准的控制通讯的速率?

    STM32F103普通IO模拟通信协议如I2C,SPI,串口等。 怎么精准的控制通讯的速率,我看到STLINK也是用的STM32的芯片,为
    发表于 03-28 08:24

    stm32f4软件模拟I2C读写EEPROM无器件响应是什么原因造成的?

    利用STM32F4软件模拟I2C读写EEPROM时,在检测I2C总线设备时,在等待应答阶段,CPU读取SDA线状态值为1(GPIO_Rea
    发表于 03-19 06:36

    什么是I2C协议 I2C总线的控制逻辑

    在实际使用过程中,I2C比较容易出现的一个问题就是死锁 ,死锁在I2C中主要表现为:I2C死锁时表现为SCL为高,SDA一直为低。
    发表于 03-12 09:17 946次阅读
    什么是<b class='flag-5'>I2C</b>协议 <b class='flag-5'>I2C</b>总线的控制逻辑

    GD32 MCU硬件I2C不可靠不如软件I2C?来看看红枫派开发版的硬件I2C驱动如何做到稳得一批

    在一个评论中,看到网友对硬件I2C的讨论,硬件I2C Busy找不到原因、软件I2C稳得一批。
    的头像 发表于 02-23 09:37 2691次阅读
    GD32 MCU硬件<b class='flag-5'>I2C</b>不可靠不如软件<b class='flag-5'>I2C</b>?来看看红枫派开发版的硬件<b class='flag-5'>I2C</b>驱动如何做到稳得一批

    请问NUC970的I2C的Software Mode怎么使用?

    Cn_SWR)寄存器中的SDW,SCW是否和使用IO模拟I2C一样, 通过操作这两个位产生START, STOP, READ等指令? 2.
    发表于 01-17 06:28

    stm32 I2c硬件驱动程序不稳定该怎么解决?

    stm32 I2c硬件驱动程序不稳定该怎么解决? stm32I2C 硬件驱动程序不稳定可能是由多种因素引起的。在本文中,我们将讨论可能导致 I
    的头像 发表于 01-16 17:11 2814次阅读

    使用两片ADU360进行I2C通信,当与从机进行通信时,从机无法进入I2C中断是为什么?

    问题说明:使用两片ADU360进行I2C通信,主机使用IO模拟方式,从机使用内部外设 主机IO
    发表于 01-15 06:47