当前位置:   article > 正文

物联网实战--驱动篇之(一)EEPROM存储器(AT24C64)

物联网实战--驱动篇之(一)EEPROM存储器(AT24C64)

目录

一、驱动概述

二、AT24C64简介

三、驱动编写

四、驱动应用


一、驱动概述

        这是驱动篇的第一篇,所以先说明下驱动篇的作用和书写计划。之前的净化器项目已有提及,向ESP8266、SHT30这些都属于驱动设备,主芯片STM32是核心,相当于大脑,这些外部模块相当于手眼耳鼻。那STM32要如何调用这些驱动设备呢,这就需要驱动程序了,像双面胶一样,粘合这两部分。

        其实驱动程序我们平时在使用个人电脑的时候也经常接触,比如我们在使用烧写器的时候直接插电脑USB首先是电脑无法识别的,需要你安装驱动程序后才能识别,这个驱动程序是烧写器厂家根据Windows的系统要求编写的,如果厂家没有写苹果系统的驱动程序,那么理论上你就不能在苹果电脑上使用烧写器了。所以,驱动程序要有比较好的移植能力,这样你在各个单片机平台之间就可以很好复用了,因为你毕竟无法预料老板想用哪款芯片做新项目。

        这样一说,大家也应该基本明白了,驱动程序之间没有关联,所以这个系列就是在不断扩充品类,上下文之间没有太大关联。根据计划,我把要写的清单先列一下:EEPROM存储器AT24C64、4G、NB-Iot、LoRa、实时时钟DS1302、电能芯片HLW8032、磁编码AS5600、modbus协议、加解密算法、hp303b气压传感器、MPU6050陀螺仪、SHA204A安全认证芯片、FLASH存储器 W25Q64、以太网W5500等等,反正想到什么写什么了,或者读者有什么需要的可以留言,有条件也安排上了。

        这里面LoRa是比较特殊的,因为它可以使用LoRaWAN也可以自组网,后面应该会单独开一篇LoRa自组网协议的文章。

二、AT24C64简介

        下面回归本篇主题,EEPROM存储器 AT24C64,AT24CXX是个系列,后面XX代表容量,这里具体可以看手册。AT24C64_(IDCHIP(英锐芯))AT24C64中文资料_价格_PDF手册-立创电子商城

        看手册不管中文版或者英文版,都要学会抓关键,像这类IIC器件的关键就是器件地址和数据地址,一般器件地址是厂家定义+引脚自定义决定的,数据地址对于这款芯片来说就是空间容量了,提炼出来就是下面这些截图了。

        如上图所示,AT24C64存储空间是8192字节,转换成16进制就是0x2000,所以读写范围不要超过这个,驱动程序内要有边界保护。

        如上图所示,一般来讲如果就一块AT24C64的话,地址A0A1A2都是直接接地的,根据地址脚数量可知,一条IIC总线可以挂载8个存储芯片。对于IIC,我这里都是使用模拟IIC,这样可移植性以较好。

        如上图所示,AT24C64的起始器件地址是0xA0,二进制(1010 0000),其它的根据硬件电路决定。

        如上图所示,读写都是差不多的,注意点是数据地址是2字节,因为存储空间是0x2000;还有一个是写的时候,如果地址重新换页了,那么要重启总线信号才能继续写数据进去,AT24C64一页是32个字节,所以代码里有部分是如下所示。

三、驱动编写

        接下去是代码部分,先看下头文件部分,并不复杂。

        接下来是代码部分,代码里都有注释了读写的数据地址范围,还有写数据换页时候要重启总线,然后稍微延时下,这里写代码时候稍微有点技巧,自己看代码琢磨了。

  1. #include "drv_at24c64.h"
  2. At24c64WorkStruct g_sAt24c64Work={0};
  3. /*
  4. ================================================================================
  5. 描述 :初始化
  6. 输入 :
  7. 输出 :
  8. ================================================================================
  9. */
  10. void at24c64_init(GPIO_TypeDef* port_sda, u16 pin_sda, GPIO_TypeDef* port_scl, u16 pin_scl)
  11. {
  12. I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
  13. pIIC->port_sda=port_sda;
  14. pIIC->pin_sda=pin_sda;
  15. pIIC->port_scl=port_scl;
  16. pIIC->pin_scl=pin_scl;
  17. g_sAt24c64Work.dev_addr=0xA0;//默认器件地址
  18. IIC_GPIOInit(pIIC);
  19. }
  20. /*
  21. ================================================================================
  22. 描述 : 设置器件地址
  23. 输入 :
  24. 输出 :
  25. ================================================================================
  26. */
  27. void at24c64_set_dev_addr(u8 dev_addr)
  28. {
  29. g_sAt24c64Work.dev_addr=dev_addr;
  30. }
  31. /*
  32. ================================================================================
  33. 描述 : 读数据
  34. 输入 :
  35. 输出 :
  36. ================================================================================
  37. */
  38. u16 at24c64_read(u32 data_addr, u8 *out_buff, u16 len)
  39. {
  40. u8 dev_addr=g_sAt24c64Work.dev_addr;//器件地址
  41. u16 i=0;
  42. if(len==0 || data_addr+len>AT24C64_MAX_ADDR)//数据范围检测
  43. return 0;
  44. I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
  45. IIC_Start(pIIC);
  46. IIC_WriteByte(pIIC, dev_addr );//写器件地址
  47. IIC_WaitAck(pIIC);
  48. IIC_WriteByte(pIIC, data_addr>>8 );
  49. IIC_WaitAck(pIIC);
  50. IIC_WriteByte(pIIC, data_addr ); //写数据地址
  51. IIC_WaitAck(pIIC);
  52. IIC_Start(pIIC);
  53. IIC_WriteByte(pIIC, dev_addr|0x01 );//准备读
  54. IIC_WaitAck(pIIC);
  55. for(i=0;i<len-1;i++)//循环读取,少一个字节
  56. {
  57. out_buff[i]=IIC_ReadByte(pIIC);
  58. IIC_Ack(pIIC);//ACK
  59. }
  60. out_buff[i]=IIC_ReadByte(pIIC);//读取最后一个字节
  61. IIC_NAck(pIIC);//NACK
  62. IIC_Stop(pIIC);
  63. return len;
  64. }
  65. /*
  66. ================================================================================
  67. 描述 :写数据
  68. 输入 :
  69. 输出 :
  70. ================================================================================
  71. */
  72. u16 at24c64_write(u32 data_addr, u8 *in_buff, u16 len)
  73. {
  74. u8 dev_addr=g_sAt24c64Work.dev_addr;//器件地址
  75. u8 *pData=in_buff;
  76. if(len==0 || data_addr+len>AT24C64_MAX_ADDR)//数据范围检测
  77. return 0;
  78. I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
  79. while(len>0)
  80. {
  81. IIC_Start(pIIC);
  82. IIC_WriteByte(pIIC, dev_addr);//写器件地址
  83. IIC_WaitAck(pIIC);
  84. IIC_WriteByte(pIIC, data_addr>>8 );
  85. IIC_WaitAck(pIIC);
  86. IIC_WriteByte(pIIC, data_addr );//写数据地址
  87. IIC_WaitAck(pIIC);
  88. //继续写
  89. while(len>0)
  90. {
  91. IIC_WriteByte(pIIC, *pData );
  92. IIC_WaitAck(pIIC);
  93. len--;
  94. pData++;
  95. data_addr++;
  96. if(data_addr%32==0)//写满一页,必须重新启动总线
  97. {
  98. break;
  99. }
  100. }
  101. IIC_Stop(pIIC);
  102. delay_ms(5);//适当延时
  103. }
  104. return len;
  105. }
四、驱动应用

        应用层就是初始化,然后读写了,没什么太复杂的东西。以后还会接触一个FLASH存储器,那个需要整页先擦除才能写入,容量比较大;而EEPROM不需要这个步骤,某个地址可以直接重复写入,但是它的容量比较小,适合存储一些参数信息。

驱动文件https://download.csdn.net/download/ypp240124016/89096777

本项目的交流QQ群:701889554

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/401668
推荐阅读
相关标签
  

闽ICP备14008679号