搜索
bottom↓
回复: 45

STM32平台编写很规范的铁电存储器FM24CL64驱动IIC I2C

  [复制链接]

出0入0汤圆

发表于 2013-9-6 16:58:44 | 显示全部楼层 |阅读模式
bsp_eeprom.h
  1. #ifndef _BSP_EEPROM_H_
  2. #define _BSP_EEPROM_H_

  3. #include "stm32f10x.h"
  4. #include "macroconst.h"

  5. #define                EEPROM_PAGE_SIZE        256

  6. #define                EEPROM_WRITE_ADDR                0XA0
  7. #define                EEPROM_READ_ADDR                0XA1

  8. #define                EEPROM_SCL_SET                GPIO_SetBits(GPIOB, GPIO_Pin_10)
  9. #define         EEPROM_SCL_CLR                GPIO_ResetBits(GPIOB, GPIO_Pin_10)

  10. #define                EEPROM_SDA_SET                GPIO_SetBits(GPIOB, GPIO_Pin_11)
  11. #define         EEPROM_SDA_CLR                GPIO_ResetBits(GPIOB, GPIO_Pin_11)

  12. #define         EEPROM_SDA_READ                GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)

  13. #define                EEPROM_TRUE                        1
  14. #define                EEPROM_FALSE                0

  15. extern void EEPROM_Init(void);
  16. extern u8_t EEPROM_Write(u8_t *_pbyte, u16_t _addr, u16_t _byte_count);
  17. extern u8_t EEPROM_Read(u8_t *_pbyte, u16_t _addr, u16_t _byte_count);

  18. #endif
复制代码
bsp_eeprom.c
  1. #include "bsp_eeprom.h"

  2. void EEPROM_Init(void)
  3. {       
  4.         GPIO_InitTypeDef  GPIO_InitStructure;

  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  6.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
  7.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  8.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  9.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  10. }

  11. static u8_t IIC_Start(void)
  12. {
  13.         EEPROM_SDA_SET;
  14.         EEPROM_SCL_SET;
  15.        
  16.         if(!EEPROM_SDA_READ)
  17.                 return EEPROM_FALSE;
  18.         EEPROM_SDA_CLR;
  19.         if(EEPROM_SDA_READ)
  20.                 return EEPROM_FALSE;
  21.         EEPROM_SCL_CLR;
  22.         return EEPROM_TRUE;
  23. }

  24. static void IIC_Stop(void)
  25. {
  26.         EEPROM_SCL_CLR;
  27.         EEPROM_SDA_CLR;
  28.         EEPROM_SCL_SET;
  29.         EEPROM_SDA_SET;
  30. }

  31. static void IIC_ACK(void)
  32. {
  33.         EEPROM_SCL_CLR;
  34.         EEPROM_SDA_CLR;
  35.         EEPROM_SCL_SET;
  36.         EEPROM_SCL_CLR;
  37. }

  38. static void IIC_NoACK(void)
  39. {
  40.         EEPROM_SCL_CLR;
  41.         EEPROM_SDA_SET;
  42.         EEPROM_SCL_SET;
  43.         EEPROM_SCL_CLR;       
  44. }

  45. // 1 ÓÐACK   0 ÎÞACK
  46. static u8_t IIC_WaitACK(void)
  47. {
  48.         EEPROM_SCL_CLR;
  49.         EEPROM_SDA_SET;
  50.         EEPROM_SCL_SET;
  51.        
  52.         if(EEPROM_SDA_READ)
  53.         {
  54.                 EEPROM_SCL_CLR;
  55.                 return EEPROM_FALSE;
  56.         }
  57.         EEPROM_SCL_CLR;
  58.         return EEPROM_TRUE;
  59. }

  60. //Êý¾Ý´Ó¸ßλµ½µØλ
  61. static void IIC_SendByte(u8_t _byte)
  62. {
  63.         u8_t i = 0;
  64.         for (i=0; i<8; i++)
  65.         {
  66.                 EEPROM_SCL_CLR;
  67.                 if (_byte&0x80)
  68.                         EEPROM_SDA_SET;
  69.                 else
  70.                         EEPROM_SDA_CLR;
  71.                
  72.                 _byte <<= 1;
  73.                 EEPROM_SCL_SET;
  74.         }
  75.         EEPROM_SCL_CLR;
  76. }

  77. static u8_t IIC_RecByte(void)
  78. {
  79.         u8_t i = 0;
  80.         u8_t rec_byte;
  81.        
  82.         EEPROM_SDA_SET;
  83.         for (i=0; i<8; i++)
  84.         {
  85.                 rec_byte <<= 1;
  86.                 EEPROM_SCL_CLR;
  87.                 EEPROM_SCL_SET;
  88.                 if (EEPROM_SDA_READ)
  89.                         rec_byte |= 0x01;
  90.         }
  91.         EEPROM_SCL_CLR;
  92.        
  93.         return rec_byte;
  94. }
  95. u8_t EEPROM_Write(u8_t *_pbyte, u16_t _addr, u16_t _byte_count)
  96. {
  97.         u8_t addr_h = 0, addr_l = 0;
  98.         u8_t i;
  99.        
  100.         addr_h = _addr/EEPROM_PAGE_SIZE;
  101.         addr_l = _addr%EEPROM_PAGE_SIZE;
  102.        
  103.         if (!IIC_Start())        return EEPROM_FALSE;
  104.         IIC_SendByte(EEPROM_WRITE_ADDR);
  105.         if(!IIC_WaitACK())
  106.         {
  107.                 IIC_Stop();
  108.                 return EEPROM_FALSE;
  109.         }
  110.         IIC_SendByte(addr_h);
  111.         IIC_WaitACK();
  112.         IIC_SendByte(addr_l);
  113.         IIC_WaitACK();
  114.        
  115.         for (i=0; i<_byte_count; i++)
  116.         {
  117.                 IIC_SendByte(*(_pbyte+i));
  118.                 IIC_WaitACK();
  119.         }
  120.         IIC_Stop();
  121.        
  122.         return EEPROM_TRUE;
  123. }

  124. u8_t EEPROM_Read(u8_t *_pbyte, u16_t _addr, u16_t _byte_count)
  125. {
  126.         u8_t addr_h = 0, addr_l = 0;
  127.         u8_t i;
  128.        
  129.         addr_h = _addr/EEPROM_PAGE_SIZE;
  130.         addr_l = _addr%EEPROM_PAGE_SIZE;
  131.        
  132.         if (!IIC_Start())        return EEPROM_FALSE;
  133.         IIC_SendByte(EEPROM_WRITE_ADDR);
  134.         if(!IIC_WaitACK())
  135.         {
  136.                 IIC_Stop();
  137.                 return EEPROM_FALSE;
  138.         }
  139.         IIC_SendByte(addr_h);
  140.         IIC_WaitACK();
  141.         IIC_SendByte(addr_l);
  142.         IIC_WaitACK();
  143.        
  144.         IIC_Start();
  145.         IIC_SendByte(EEPROM_READ_ADDR);
  146.         IIC_WaitACK();
  147.        
  148.         for (i=0; i<_byte_count-1; i++)
  149.         {
  150.                 *(_pbyte+i) = IIC_RecByte();
  151.                 IIC_ACK();
  152.         }
  153.         *(_pbyte+_byte_count-1) = IIC_RecByte();
  154.         IIC_NoACK();
  155.         IIC_Stop();
  156.        
  157.         return EEPROM_TRUE;
  158. }

复制代码
测试的主函数

  1. #include "stm32f10x.h"
  2. #include "bsp_delay.h"
  3. #include "bsp_led.h"
  4. #include "bsp_oled.h"
  5. #include "bsp_beep.h"
  6. #include "bsp_gprs.h"
  7. #include "bsp_timer.h"
  8. #include "bsp_menu.h"
  9. #include "bsp_key.h"
  10. #include "bsp_eeprom.h"

  11. extern u16_t tim3_2ms_count;                //From bsp_timer
  12. extern u8_t tim3_10ms_key_flag;                //From bsp_timer
  13. extern u8_t tim3_20ms_lcd_flag;                //From bsp_timer

  14. u8_t key_val;
  15. u8_t eeprom_test_w[16] = {0x01,0x02,0x03,0x05,0x04,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16};
  16. u8_t eeprom_test_r[16];

  17. int main(void)
  18. {
  19.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  20.         DelayFunc_Init(72);
  21.         LEDPort_Init();
  22.         OLED_Init();
  23.         Beep_Init();
  24.         GPRS_COM_Init();
  25.         Menu_Init();
  26.         KeyPort_Init();
  27.         EEPROM_Init();
  28.         Timer3_Init(199,719);                //        2ms

  29.         Menu_Display();
  30.         OLED_Update();
  31.        
  32.        
  33.         BEEP_CLR;
  34.         EEPROM_Write(eeprom_test_w, 0x0001, 16);

  35.         while (1)
  36.         {       
  37.                 if (tim3_10ms_key_flag)
  38.                 {
  39.                         tim3_10ms_key_flag = 0;                //10msµ½
  40.                         key_val = Get_Key_Value();
  41.                         EEPROM_Read(eeprom_test_r, 0x00001,16);
  42.                         UART2_SendData(eeprom_test_r, 16);
  43.                 }
  44.                 KeyPress_To_MenuUpdate(key_val);
  45.         }
  46. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-9-6 17:04:14 | 显示全部楼层
iic的速率是怎么控制的呢?

出0入0汤圆

 楼主| 发表于 2013-9-6 22:31:28 | 显示全部楼层
wswh2o 发表于 2013-9-6 17:04
iic的速率是怎么控制的呢?

铁电的东西就是速度快 不需要控制速率 1M

出0入0汤圆

发表于 2013-9-7 00:27:29 来自手机 | 显示全部楼层
做个记号

出0入0汤圆

发表于 2013-9-7 09:02:51 | 显示全部楼层
本帖最后由 sky5566 于 2013-9-7 09:04 编辑

用 25 的 SPI 吧,clk高達10MHZ以上,如果要使用 24 就無需使用鐵電 eeprom.

出0入0汤圆

发表于 2013-9-7 10:03:47 | 显示全部楼层
谢谢楼主分享,铁电的优势是读写速度快,操作次数高,25的SPI行吗?

出0入0汤圆

发表于 2013-9-7 10:05:03 | 显示全部楼层
solojimes 发表于 2013-9-6 22:31
铁电的东西就是速度快 不需要控制速率 1M

你那个DTU怎么样了

出0入0汤圆

发表于 2013-9-7 10:20:36 | 显示全部楼层
mark,mark!

出0入12汤圆

发表于 2013-9-7 10:54:27 | 显示全部楼层
STM32, I2C看来注定是模拟的天下哈哈哈哈
那些用硬的,都碰的头破血流

出0入0汤圆

 楼主| 发表于 2013-9-7 16:24:17 | 显示全部楼层
gzhmcu 发表于 2013-9-7 10:05
你那个DTU怎么样了

快好了 这个也是dtu中的一部分 换成了STM32 主控

出0入0汤圆

发表于 2013-9-7 16:26:16 | 显示全部楼层
solojimes 发表于 2013-9-7 16:24
快好了 这个也是dtu中的一部分 换成了STM32 主控

恭喜呀,等完成的时候,帮你测试,现在偶公司上了好多装备,呵呵

出0入0汤圆

发表于 2013-11-25 12:19:14 | 显示全部楼层
马上也要用到铁电,定期

出0入0汤圆

发表于 2013-11-25 14:03:58 | 显示全部楼层
mark 一下!

出0入0汤圆

发表于 2013-11-25 15:52:15 | 显示全部楼层
IIC读写比较慢,要是要求高就用SPI的

出0入0汤圆

发表于 2013-11-25 16:22:18 | 显示全部楼层
这个好,写得很规范,用起来或者要改点什么也很方便
楼主能不能传个压缩包呢,因为直接贴上来的代码,好多注释都乱码了。
谢谢楼主啦·~~

出0入0汤圆

发表于 2013-12-3 16:27:46 | 显示全部楼层
收藏!!!STM32 I2C

出0入0汤圆

发表于 2013-12-13 18:17:26 | 显示全部楼层
果断收了!

出0入0汤圆

发表于 2013-12-13 21:37:41 | 显示全部楼层
排版挺规范,编程就不能算规范了。

出0入0汤圆

发表于 2013-12-27 14:16:06 | 显示全部楼层
收藏收藏

出0入0汤圆

发表于 2014-1-7 09:03:03 | 显示全部楼层
果断收藏,谢谢楼主发帖!

出0入0汤圆

发表于 2014-3-20 10:57:09 | 显示全部楼层
楼主是在什么单片机上 是在STM32F407上吗???

出0入57汤圆

发表于 2014-3-21 11:21:14 | 显示全部楼层
正准备搞F103外接24C02,试试!

出0入0汤圆

发表于 2014-8-31 10:55:57 | 显示全部楼层
我也准备搞F103外接24C02

出0入0汤圆

发表于 2014-9-16 09:50:54 | 显示全部楼层
fm24c64和256的读写时序有没有区别?

出0入0汤圆

发表于 2014-9-18 09:30:32 | 显示全部楼层
楼主这样的代码不能够实现,实时的处理数据啊。比如有中断频繁的场合。你如果实时的读写数据,肯定死在ack里面。楼主是否考虑更改?

出0入0汤圆

发表于 2014-9-18 09:36:32 | 显示全部楼层
谢谢楼主,收藏备用。。。。

出0入0汤圆

发表于 2014-9-18 11:47:55 | 显示全部楼层
代码确实很清晰

出0入16汤圆

发表于 2014-9-18 11:58:13 | 显示全部楼层
GOOD JOB!!!!

出0入0汤圆

发表于 2015-4-3 08:43:34 | 显示全部楼层
项目中正在使用铁电,谢谢分享!

出0入0汤圆

发表于 2015-4-3 09:23:45 | 显示全部楼层
铁电就是贵了点,正在找速度快的存储器,SRAM也太贵,还没找到合适的东西

出0入0汤圆

发表于 2015-5-4 13:41:23 | 显示全部楼层
写的很清楚 标记下

出0入30汤圆

发表于 2015-5-4 13:47:48 | 显示全部楼层
wtliu 发表于 2013-11-25 15:52
IIC读写比较慢,要是要求高就用SPI的

请教,SPI写没有应答,写完再读一遍校验吗?

出0入0汤圆

发表于 2015-5-4 14:37:57 | 显示全部楼层
谢谢楼主分享,有尝试过硬件IIC去驱动吗、

出0入0汤圆

发表于 2015-5-14 15:02:14 | 显示全部楼层
MARK   现在在用硬件IIC方式驱动铁链存储器,很多人反应STM32自带的IIC模块经常出问题!

我调试的时候就卡在:while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); 上了,一直无法通过

出0入0汤圆

发表于 2015-5-15 22:21:29 | 显示全部楼层
谢谢楼主分享,           

出0入0汤圆

发表于 2015-5-18 16:58:10 | 显示全部楼层
FM25CL64和FM24CL64其实价格一样,可以改用FM25CL64, SPI 20MHz最高,目前由于测试的MPU关系最高只能到12MHz,和原来IIC比,在协议端就有差距了(IIC需要 9BIT存取一笔资料,相同速度就差了12%左右)那差距不是一般的大,读写很快

出0入0汤圆

发表于 2015-8-17 14:01:58 | 显示全部楼层
第一次用STM32模拟I2C,看到GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;此行代码,才调通了。

出0入0汤圆

发表于 2015-11-17 19:26:12 | 显示全部楼层
果断收藏,谢谢楼主发帖!

出0入0汤圆

发表于 2016-9-9 23:21:36 | 显示全部楼层
楼主强悍,果断收藏!

出0入0汤圆

发表于 2016-9-10 08:03:22 | 显示全部楼层
收藏一个

出0入8汤圆

发表于 2018-4-3 11:02:11 | 显示全部楼层
好像没有搞延时   ,EE估计就不行了

出0入0汤圆

发表于 2018-4-3 11:31:16 | 显示全部楼层
hyper320 发表于 2015-5-18 16:58
FM25CL64和FM24CL64其实价格一样,可以改用FM25CL64, SPI 20MHz最高,目前由于测试的MPU关系最高只能到12MHz, ...

铁电好贵啊

出0入8汤圆

发表于 2018-6-19 15:37:17 | 显示全部楼层
用你这个程序驱动我的FM24C64无应答,什么鬼

出0入0汤圆

发表于 2020-12-5 09:00:46 | 显示全部楼层
正好想驱动MB85RC16PNF, 不知道是不是一样的,试试看!

出0入0汤圆

发表于 2020-12-5 10:12:29 | 显示全部楼层
我也想用铁电

出5入10汤圆

发表于 2022-4-7 10:18:51 | 显示全部楼层
amxx 发表于 2020-12-5 09:00
正好想驱动MB85RC16PNF, 不知道是不是一样的,试试看!
(引用自44楼)

能正常驱动MB85RC16PNF吗
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-9 03:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表