物联网实战--驱动篇之(一)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个字节,所以代码里有部分是如下所示。

三、驱动编写

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

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


#include "drv_at24c64.h"


At24c64WorkStruct g_sAt24c64Work={0};
/*		 
================================================================================
描述 :初始化
输入 : 
输出 :  
================================================================================
*/
void at24c64_init(GPIO_TypeDef* port_sda, u16 pin_sda, GPIO_TypeDef* port_scl, u16 pin_scl)
{ 
  I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
	pIIC->port_sda=port_sda; 
	pIIC->pin_sda=pin_sda;
	pIIC->port_scl=port_scl;
	pIIC->pin_scl=pin_scl;	
	
  g_sAt24c64Work.dev_addr=0xA0;//默认器件地址
	IIC_GPIOInit(pIIC);

}

/*		
================================================================================
描述 : 设置器件地址
输入 : 
输出 : 
================================================================================
*/
void at24c64_set_dev_addr(u8 dev_addr)
{
  g_sAt24c64Work.dev_addr=dev_addr;
}

/*		
================================================================================
描述 : 读数据
输入 : 
输出 : 
================================================================================
*/
u16 at24c64_read(u32 data_addr, u8 *out_buff, u16 len)
{
	u8 dev_addr=g_sAt24c64Work.dev_addr;//器件地址
	u16 i=0;
	
	if(len==0 || data_addr+len>AT24C64_MAX_ADDR)//数据范围检测
		return 0;
  
	I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
  
	IIC_Start(pIIC);
	IIC_WriteByte(pIIC, dev_addr );//写器件地址
	IIC_WaitAck(pIIC);
	IIC_WriteByte(pIIC, data_addr>>8 );
	IIC_WaitAck(pIIC);	
	IIC_WriteByte(pIIC, data_addr ); //写数据地址
	IIC_WaitAck(pIIC);
	
	IIC_Start(pIIC);
	IIC_WriteByte(pIIC, dev_addr|0x01 );//准备读
	IIC_WaitAck(pIIC);
	for(i=0;i<len-1;i++)//循环读取,少一个字节
	{
		out_buff[i]=IIC_ReadByte(pIIC);
		IIC_Ack(pIIC);//ACK
	}		
	out_buff[i]=IIC_ReadByte(pIIC);//读取最后一个字节
	IIC_NAck(pIIC);//NACK
	IIC_Stop(pIIC);
	
	return len;
}

/*		
================================================================================
描述 :写数据
输入 : 
输出 : 
================================================================================
*/
u16 at24c64_write(u32 data_addr, u8 *in_buff, u16 len)
{
	u8 dev_addr=g_sAt24c64Work.dev_addr;//器件地址
	u8 *pData=in_buff;

	if(len==0 || data_addr+len>AT24C64_MAX_ADDR)//数据范围检测
		return 0;
	
  I2cDriverStruct *pIIC=&g_sAt24c64Work.tag_iic;
  
	while(len>0)
	{
		IIC_Start(pIIC);
		IIC_WriteByte(pIIC, dev_addr);//写器件地址
		IIC_WaitAck(pIIC);
		IIC_WriteByte(pIIC, data_addr>>8 );
		IIC_WaitAck(pIIC);	
		IIC_WriteByte(pIIC, data_addr );//写数据地址
		IIC_WaitAck(pIIC);
		
    //继续写
		while(len>0)
		{
			IIC_WriteByte(pIIC, *pData );
			IIC_WaitAck(pIIC);
			len--;			
			pData++;
			data_addr++;
			if(data_addr%32==0)//写满一页,必须重新启动总线
			{
				break;
			}
		}
		IIC_Stop(pIIC);		
		delay_ms(5);//适当延时
	}
	return len;
}
四、驱动应用

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518540.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++入门4.引用

目录 1.引用概念&#xff1a; 2.引用特性&#xff1a; 3.常引用&#xff1a; 4.使用场景&#xff1a; 引用和指针的区别&#xff1a; 1.引用概念&#xff1a; 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空…

BLE协议—HID

BLE协议—HID HID设备HOGP&#xff08;HID Over GATT Profile&#xff09;HID服务HID infoHID ModeHID ReportHID MAP HID设备 HID&#xff08;Human Interface Device&#xff0c;人机接口设备&#xff09;是USB设备中常用的设备类型&#xff0c;是直接与人交互的USB设备&…

谷歌AI搜寻背后的资本战:收费传言引爆行业震荡|TodayAI

考虑对其AI驱动的搜索工具收费&#xff0c;这一消息在某种程度上让人感到惊讶。毕竟&#xff0c;谷歌超过一半的总收入来自搜索业务&#xff0c;几乎是其次大收入来源的五倍。YouTube订阅、Pixel手机、Play商店佣金以及Gmail存储空间的收入加起来&#xff0c;与搜索业务的价值相…

机台数据传输共享存在哪些问题?机台数据管控怎么做?

一些金融机构、大型制造业以及晶圆制造厂里面&#xff0c;都会存在大量的机台设备&#xff0c;这些机台会产⽣庞⼤⽽属性不同的数据&#xff0c;这些数据需要定期的进行采集和利用。机台数据在传输分享过程中&#xff0c;会面临各种问题和调整&#xff0c;所以需要做好机台数据…

Java 线程池的基本用法

线程池 池化思想&#xff1a;线程池、数据连接池等&#xff0c;比如我们 Spark 的 Executor 就是典型的线程池&#xff0c;用户在启动 Spark 作业的同时启动线程池&#xff0c;这样 Spark 的 Task 就可以直接获取资源&#xff0c;而不用像 MR 程序那样等待容器上的进程开启了。…

一、持续集成介绍

持续集成介绍 一、什么是持续集成二、持续集成的流程三、持续集成的组成要素四、持续集成的好处 一、什么是持续集成 持续集成&#xff08;CI&#xff09;指的是&#xff0c;频繁地&#xff08;一天多次&#xff09;将代码集成到主干。持续集成的目的&#xff0c;就是让产品可…

JavaScript前端学习大全

一、概念 JavaScript简称为JS&#xff0c;这门语言诞生主要用于完成页面的数据验证&#xff0c;因此运行在客户端&#xff0c;需要浏览器来解析JavaScript的代码。是世界上最流行的脚本语言。JavaScript 是一种让网页变得有趣和动态的编程语言。比如&#xff0c;当你在网页上点…

学习【RabbitMQ入门】这一篇就够了

目录 1. RabbitMQ入门1-1. 同步调用1-2. 异步调用1-3. MQ技术选型1-4. RabbitMQ介绍消息模式 1-5. SpringAMQPBasic QueueWork QueueFanout ExchangeDirect ExchangeTopic Exchange消息转换器 1. RabbitMQ入门 1-1. 同步调用 优势&#xff1a; 时效性强&#xff0c;等待到结…

当前2024阿里云服务器哪个地域价格比较优惠,哪个地域便宜?

目前2024年阿里云服务器地域对比哪个价格更优惠&#xff1f;华北6&#xff08;乌兰察布&#xff09;、华北3&#xff08;张家口&#xff09;、华北1&#xff08;青岛&#xff09;和华南2&#xff08;河源&#xff09;地域更便宜&#xff0c;云服务器吧yunfuwuqiba.com整理阿里云…

【量子计算机为什么能吊打通用计算机】浅谈

Quntum Computer 一、量子计算机导入 这是一双手&#xff0c;这是大自然送给你最神奇的礼物&#xff0c;你用它来写字、吃饭、打游戏&#xff0c;除此之外&#xff0c;它还有一个妙不可言的功能&#xff0c;计算。是的&#xff0c;手是你人生中的第一个计算器&#xff0c;到小…

Azure service tag 导致的Exchange online 无法发送邮件的问题

最近碰到一个比较有趣的客户问题。 这个客户一直在使用Exchange online 与自己在Azure Vnet 里面的exchange server交换邮件。 客户的网络架构如下图所示。 客户说之前从exchange online往外发邮件一直是好的,但是最近两周开始只有百分之3左右的邮件可以发出去,其他的都pen…

java中大型医院HIS系统源码 Angular+Nginx+SpringBoot云HIS运维平台源码

java中大型医院HIS系统源码 AngularNginxSpringBoot云HIS运维平台源码 云HIS系统是一款满足基层医院各类业务需要的健康云产品。该产品能帮助基层医院完成日常各类业务&#xff0c;提供病患预约挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生工作站和护士工…

不连续页分配器

不连续页分配器 在设备长时间运行后&#xff0c;内存碎片话&#xff0c;连续的物理页比较稀缺&#xff1b;伙伴分配器和slab块分配器&#xff0c;分配的内存物理上是连续的&#xff1b;在这种情况下&#xff0c;如果需要分配长度超过一页的内存块&#xff0c;可以使用不连续页…

LeetCode-17. 电话号码的字母组合【哈希表 字符串 回溯】

LeetCode-17. 电话号码的字母组合【哈希表 字符串 回溯】 题目描述&#xff1a;解题思路一&#xff1a;回溯三部曲&#xff1a;解题思路二&#xff1a;回溯解题思路三&#xff1a; 题目描述&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组…

【JavaSE】反射

Java代码的生命周期 Java代码在计算机中经历的阶段&#xff1a;Source源代码阶段、Class类对象阶段、RunTime运行时阶段。 Source源代码阶段: 这个阶段是由程序员编写生成源代码,再由Javac编译器生成class文件。 Class类对象阶段&#xff1a;由类加载器将class文件加载到JVM内…

【保姆级教程】如何订阅OnlyFans?如何在OnlyFans上面支付?OnlyFans虚拟卡订阅教程

1. 引言 什么是OnlyFans&#xff1a;OnlyFans是一种内容订阅服务&#xff0c;成立于2016年&#xff0c;允许内容创作者从用户那里获得资金&#xff0c;用户需要支付订阅费用才能查看他们的内容。它在多个领域受到欢迎&#xff0c;包括音乐、健身、摄影&#xff0c;以及成人内容…

C语言之指针(4)使用并模拟实现qsort

冒泡排序有局限性&#xff0c;实现时间长而且只能进行整型数据的排序&#xff0c;接下来介绍模拟实现qsort来方便实现各种数据的排序。 函数基本形式&#xff1a; 可以看到该函数有四个参数&#xff0c;第四个参数是一个函数指针&#xff0c;这个指针指向的函数第一个参数和第…

数据分析——数据规范化

数据规范化是数据分析中的一个重要步骤&#xff0c;其目的在于确保数据的一致性和可比性&#xff0c;提高数据质量和分析结果的准确性。以下是一些数据规范化的常见方法和技术&#xff1a; 数据清洗&#xff1a;此步骤主要清除数据中的重复项、空格、格式错误等&#xff0c;确…

【Oracle】oracle、mysql、sql server三者区别

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Oracle》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识…

Waifu2x:使用深度卷积神经网络的动漫风格艺术的图像超分辨率

Github网址&#xff1a;nagadomi/waifu2x&#xff1a;动漫风格艺术的图像超分辨率 (github.com) 该项目主要讲述的是如何利用预训练的深度学习模型来达到无损扩大收缩和去噪&#xff0c;对于一般训练图像的小伙伴应该很清晰图像经常要通过resize操作固定大小&#xff0c;然后c…