STM32 使用IO口模拟I2C时序

上一篇《I2C协议详解

我们了解了I2C的操作流程,这一篇,我们就使用I2C,来对EEPROM进行操作吧。

我们做两种选择:

1.时序由IO口模拟高低电平,需要了解协议并按照协议操作相应的IO口。

2.时序由硬件自行产生,不需要人工干预;

由硬件产生的I2C时序,我们借助Stm32Cube配置实现便可,我们这一篇,抛开Stm32Cube,手撕代码,根据I2C的时序,一步步地实现I2C对EEPROM的读写吧。

 

我们分为几个步骤来对EEPROM进行操作:

1. 发动"看硬件原理图"技能,确定I2C连线;

2. 发动"乾坤大拷贝"技能,配置对应的IO口;

3. 发动"手撕代码"技能,写出相应时序;

 

1. 发动"看硬件原理图"技能,确定I2C连线;

第9页,找到EEPROM那一块,EEPROM用的是AT24C02,只有2K Bits,不是很大。AT24C02由ATMEL公司生产,其命名规则为 AT24Cxx,xx可以=02,04,32,64,128,256,512,1M 等等,xx也表示容量,单位是 Bits,注意,是位,不是字节,要换成字节要除以8,所以,AT24C02只有 256 个字节。别问我怎么知道的,AT24C02的规格书告诉我的,要记得看原理图,看规格书喔~~~

 

再找呀找呀找朋友,找到 SCL连到PB6,SDA连到PB9。咋找?搜索呗,搜引脚 I2C1_SCL就行了。

确定了I2C连线,SCL=PB6,SDA=PB9,接下来,我们就

 

2. 发动"乾坤大拷贝"技能,配置对应的IO口;

先新建两个文件,io_i2c.c/io_i2c.h,我们就在这里面写i2c时序。

并且把文件添加进工程项目里参与编译。

配置IO口,详见《STM32CubeMx 创建第一个工程》,把那段代码拷贝过来,改一下配置就行了。

void IOI2C_GpioInit(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;


    __HAL_RCC_GPIOB_CLK_ENABLE();

    /*Configure GPIO pin Output Level */

    // PB6 = SCL/PB9 = SDA

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6|GPIO_PIN_9, GPIO_PIN_SET);


    /*Configure GPIO pin : PC7 */

    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_9;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;            // 记不记得i2c要上拉?

    GPIO_InitStruct.Pull = GPIO_PULLUP;                                    // 

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

记得在初始化时调用一下它喔:
  

MX_GPIO_Init();

  MX_DMA_Init();

  MX_UART4_Init();

  MX_TIM1_Init();

  MX_TIM2_Init();

  /* USER CODE BEGIN 2 */

    USR_UartInit();

      IOI2C_GpioInit();            // 我在这,快看这里~

  /* USER CODE END 2 */


  printf("Start System: Io I2C.\r\n");

 

3. 发动"手撕代码"技能,写出相应时序,I2C时序,请参照《I2C协议详解》。

看图,会有高电平持续一段时间,低电平持续一段时间的操作,这个持续一段时间,就是延时,关于延时,详细参照《STM32精准延时》。

这个持续多长时间怎么算呢?

根据I2C时钟频率,可以算出周期,再根据周期,算出持续多长时间。

For Example:

100kHz的频率,也就是1秒钟内,有100,000个时钟周期。

那1个时钟周期,也就是 1/100,000秒 = 1,000/100,000毫秒 = 1,000,000/100,000微秒,根据小学数学,算出,100kHz频率的时钟周期是 10微秒,一高一低一周期,那么,延时 = 5us。

在《STM32精准延时》篇中,我们做了个us级的精准延时,用上:

#define I2C_Delay                USER_Delay1us(5)

如果要其它延时呢?

delay = 1,000,000 / freq / 2 = 500,000 / freq

算出来delay与时钟频率的关系:

1us = 500kHz,2us = 250kHz,3us = 166.67kHz,4us = 125kHz,5us = 100kHz,

6us = 83.33kHz,7us = 71.4kHz,8us = 62.5kHz,9us = 55.56kHz,10us = 50kHz。

选一个,但要符合芯片的最高支持速率喔。图:400k

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值