STM32——EEPROM使用——(转载)

一、I2C接口读写EEPROMAT24C02

       ——主模式,分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。

1I 2C接口初始化

        与其他对GPIO 复用的外设一样,它先调用了用户函数I2C_GPIO_Confi g() 配置好 I 2 C 所用的 I/O端口,然后再调用用户函数 I2C_Mode_Confi gu() 设置 I 2 C 的工作模式,并使能相关外设的时钟。

  1. void I2C_EE_Init(void)
  2. {
  3. I2C_GPIO_Config();
  4. I2C_Mode_Config();
  5.  
  6. /* 根据头文件 i2c_ee. 14 h 中的定义来选择 EEPROM 要写入的地址 */
  7. #ifdef EEPROM_Block0_ADDRESS /* 选择 EEPROM Block0 来写入 */
  8. EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
  9. #endif
  10. #ifdef EEPROM_Block1_ADDRESS /* 选择 EEPROM Block1 来写入 */
  11. EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
  12. #endif
  13. #ifdef EEPROM_Block2_ADDRESS /* 选择 EEPROM Block2 来写入 */
  14. EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
  15. #endif
  16. #ifdef EEPROM_Block3_ADDRESS /* 选择 EEPROM Block3 来写入 */
  17. EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
  18. #endif
  19. }

1)EEPROM地址

        AT24C02:256字节,高四位硬性规定,最低位是R/W(传输方向选择位),在制作硬件时,我们可以根据需要改变的是地址位中的 A2、A1、A0 位。原理图上面全接地,所以它的地址为 :0xA0 或 0xA1。

2GPIO端口初始化

  1. static void I2C_GPIO_Config(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4.  
  5. /* 使能与 I2C1 有关的时钟 */
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  7. RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  8.  
  9. /* 配置SCL SDA引脚速率输出方式 */
  10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
  13. GPIO_Init(GPIOB, &GPIO_InitStructure);
  14. }


3I2C模式初始化

 

  1. typedef struct
  2. {
  3. uint32_t I2C_ClockSpeed;
  4. uint16_t I2C_Mode;
  5. uint16_t I2C_DutyCycle;
  6. uint16_t I2C_OwnAddress1;
  7. uint16_t I2C_Ack;
  8. uint16_t I2C_AcknowledgedAddress;
  9. } I2C_InitTypeDef;

1I2C_Mode本成员是选择 I 2 C 的使用方式,有 I 2 C 模式(I2C_Mode_I2C)和SMBus 模式。(I2C_Mode_SMBusDevice、I2C_Mode_SMBusHost)

2I2C_DutyCycle设置的是 I 2 C 的 SCL 线时钟的占空比。在 STM32 的 I 2 C 占空比配置中有两个选择,分别为高电平时间和低电平时间之比为16 :9 (I2C_DutyCycle_16_9)和 2 :1( I2C_DutyCycle_2)。

3I2C_OwnAddress1本 成 员 配 置 的 是 STM32 的 I 2 C 设 备 自 己 的 地 址, 每个 连 接 到 I 2 C 总线上的设备都要有一个自己的地址,作为主机也不例外。这个地址可以被配置为 7 位和 10 位地址。我们把这个地址设置为 0x0A (自定义宏I2C1_OWN_ADDRESS7 的值)。

4I2C_Ack_Enable本成员关于 I 2 C 应答设置,设置为使能则每接收到一个字节就返回一个应答信号。配置为允许应答(I2C_Ack_Enable),这是绝大多数遵循 I 2 C标准的设备通信的要求,改为禁止应答 (I2C_Ack_Disable)往往会导致通信错误。

5I2C_AcknowledgeAddress本成员选择 I 2 C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I 2C 总线上设备的地址进行选择。与 EEPROM 进行通信,使用的为 7 位寻址模式(I2C_AcknowledgedAddress_7bit)。

6I2C_ClockSpeed本成员设置的是 I 2 C 的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把分频值写入到 I 2 C 的时钟控制寄存器。而我们写入的这个参数值不得高于 400 kHz。——400000

对结构体成员赋值完成后,我们调用库函数 I2C_Init() 根据我们的配置对 I 2 C 进行初始化, 并调用库函数 I2C_Cmd() 使能I 2 C 外设。 

  1. static void I2C_Mode_Configu(void)
  2. {
  3. I2C_InitTypeDef I2C_InitStructure;
  4.  
  5. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; /* I2C 配置 */
  6.  
  7. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
  8. I2C_InitStructure.I2C_OwnAddress1 = I2C1_OWN_ADDRESS7;
  9. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
  10. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* I2C 的寻址模式 */
  11. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* 通信速率 */
  12.  
  13. I2C_Init(I2C1, &I2C_InitStructure); /* I2C1 初始化 */
  14. I2C_Cmd(I2C1, ENABLE); /* 使能 I2C1 */
  15. }

 

二、对EEPROM的读写操作

  1. void I2C_Test(void)
  2. {
  3. u16 i;
  4.  
  5. printf("写入的数据\n\r");
  6.  
  7. for ( i = 0; i <= 255; i++ ) //填充缓冲
  8. {
  9. I2c_Buf_Write[i] = i;
  10. printf("0x%02X ", I2c_Buf_Write[i]);
  11. if (i % 16 == 15)
  12. {
  13. printf("\n\r");
  14. }
  15. }
  16.  
  17. I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256); //将 I2c_Buf_Write 中顺序递增的数据写入 EERPOM 中
  18.  
  19. printf("\n\r 写成功\n\r");
  20. printf("\n\r 读出的数据\n\r");
  21.  
  22. I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256); //将 EEPROM 读出数据顺序保持到 I2c_Buf_Read 中
  23.  
  24. //将 I2c_Buf_Read 中的数据通过串口打印
  25. for (i = 0; i < 256; i++)
  26. {
  27. if (I2c_Buf_Read[i] != I2c_Buf_Write[i])
  28. {
  29. printf("0x%02X ", I2c_Buf_Read[i]);
  30. printf("错误:I2C EEPROM 写入与读出的数据不一致\n\r");
  31. return;
  32. }
  33. printf("0x%02X ", I2c_Buf_Read[i]);
  34. if (i % 16 == 15)
  35. {
  36. printf("\n\r");
  37. }
  38. }
  39. printf(
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值