上一篇《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