单片机为什么要接eeprom,单片机一般在什么时候写入eeprom

首页 > 实用技巧 > 作者:YD1662024-02-23 23:58:44

单片机为什么要接eeprom,单片机一般在什么时候写入eeprom(5)

3年嵌入式物联网学习资源整理分享:C语言、Linux开发、数据结构;软件开发,STM32单片机、ARM硬件开发、物联网通信开发、综合项目开发教程资料;笔试面试真题。点击下方插件免费领取↓↓↓https://s.pdb2.com/l/cnklSITCGo24eIn

因为24C02是一个2K Bit的串行EEPROM存储器(掉电不丢失),内部含有256个字节。也就是说有256个存储单元,一个字节就是一个存储单元,因为每个字节可以出存256个数,也就是说每个存储单元可以存0~255个数。我们可以这样理解,AT24C02是一栋教学楼,这个教学楼有256个房间(存储单元),没每个房间可以容纳256个学生(每个存储单元可以存储0 ~ 255个数)。而且这个芯片在断电的时候数据不会丢失,利用掉电不会丢失以及这款芯片容量不大的特性,可以大致判断它会在哪些地方可以用到。比如我们看电视得时候,正在看CCTV6电影频道,播放的声音比较大,那么这时候正好停电了。那么你下次来电时你打开电视机,电视机默认肯定是CCTV6电影频道,播放的声音也是很大。那么这些“频道”、“音量”这些数据就存在EEPROM里面,至于是不是ATC02就不一定了。

总结:

这三个特点对我们理解存储器的特性非常重要,因为接下来要说的FLASH芯片的特性就与它完全相反。

FLASH W25Q128存储器

单片机为什么要接eeprom,单片机一般在什么时候写入eeprom(6)

FLSAH字面意思就是闪现、一瞬间的意思,所以FLSAH存储器又称闪存,与 EEPROM都是掉电后数据不丢失的存储器,但FLASH存储器容量普遍大于 EPROM,现在基本取代了它的地位。生活中常用的 U 盘、SD卡、SSD 固态硬盘以及我们 STM32 芯片内部用于存储程序的设备,都是 FLASH 类型的存储器。在存储控制上,最主要的区别是 FLASH 芯片只能一大片一大片地擦写,而 EEPROM可以单个字节擦写。

FLASH 芯片的最小擦除单位为扇区(Sector),而一个块(Block)包含 16 个扇区,4Kbytes为一个Sector,16个扇区为1个Block。W25Q64 容量为8M字节(即 64M bit), 分为128块(Block),每一块的大小为64K字节,每块又分为16个扇区(Sector),那么每个扇区就是4K个字节。W25Q128 容量为16M字节(即 128M bit),分为256块(Block),每一块的大小为64K字节,每块又分为16个扇区(Sector),那么每个扇区就是4K个字节(4096个字节,也就是4096个存储单元)。

W25Qxx的最小擦除单位为一个扇区,也就是每一次必须擦除4K字节。所以必须给W25Qxx开辟至少4K的缓冲区,这样对单片机的RAM的要求比较高,要求芯片必须有4K以上的RAM才能很好的操作。所有的FLASH我们在写之前都要擦出对应的扇区,擦除后的数据是0XFF。我们可以这样理解。我们要改写FLASH芯片W25Q128的一个扇区中某一个数据,就必须在STM32芯片的内部RAM中开辟4K字节(4096字节)的缓冲区域。先把FLASH芯片W25Q128的一个扇区中数据全部读到STM32芯片的内部RAM中开辟4K字节(4096字节)的缓冲区域中去,把我们要改写的数据在缓冲区域改写好之后,再把FLASH芯片W25Q128的一个扇区中的数据全部擦除完毕,擦除完成之后再把数据写回去。这是写入数据的操作,在读数据的时候不需要以扇区为单位,想读哪个扇区就读哪个扇区的数据。

/************************************************************************* * Function Name : SPI_Flash_Write * Description : 在指定地址开始写入指定长度的数据,该函数带擦除操作! * Input : *pBuffer:要写入数据的指针 WriteAddr:开始写入的地址(24bit) NumByteToWrite:要写入的字节数(最大16 x 1024 x 1024) * Output : None * Return : None ****************************************************************************/ void SPI_Flash_Write(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; Addr = WriteAddr % 4096;//mod运算求余,若writeAddr是4096整数倍,运算结果Addr值为0 NumOfPage = NumByteToWrite / 4096;//计算出要写多少整数扇区 NumOfSingle = NumByteToWrite % 4096;//mod运算求余,计算出剩余不满一扇区的字节数 count = 4096 - Addr;//差count个数据值,刚好可以对齐到扇区地址 if (Addr == 0)//Addr=0,则WriteAddr刚好按扇区对齐或者说小于一个扇区 { //NumByteToWrite < 4096,写入的字符串大小长度小于一个扇区(4096个字节)的大小,如22 if (NumOfPage == 0) { SPI_Flash_Write_Page(pBuffer, WriteAddr, NumByteToWrite); } else //NumByteToWrite > 4096,写入的字符串大小长度大与一个扇区(4096个字节)的大小,如4098 { //先把整数扇区都写了 while (NumOfPage--) { SPI_Flash_Write_Page(pBuffer, WriteAddr, 4096); WriteAddr = 4096; pBuffer = 4096; } //若有多余的不满一扇区的数据,把它写完 SPI_Flash_Write_Page(pBuffer, WriteAddr, NumOfSingle); } } //若地址与 4096 不对齐 else //Addr不等于0,则要写入的WriteAddr地址与4096不对齐 { //NumByteToWrite < 4096 if (NumOfPage == 0)//大小不够一个扇区,如22 { //当前页剩余的count个位置比NumOfSingle小,一扇区写不完 if (NumOfSingle > count) { temp = NumOfSingle - count; //先写满当前扇区 SPI_Flash_Write_Page(pBuffer, WriteAddr, count); WriteAddr = count; pBuffer = count; //再写剩余的数据 SPI_Flash_Write_Page(pBuffer, WriteAddr, temp); } else //当前扇区剩余的count个位置能写完NumOfSingle个数据 { SPI_Flash_Write_Page(pBuffer, WriteAddr, NumByteToWrite); } } else //NumByteToWrite > 4096 //大小够一个扇区,而且还超出一点点,如4098 { //地址不对齐多出的count分开处理,不加入这个运算 NumByteToWrite -= count; NumOfPage = NumByteToWrite / 4096; NumOfSingle = NumByteToWrite % 4096; //先写完count个数据,为的是让下一次要写的地址对齐 SPI_Flash_Write_Page(pBuffer, WriteAddr, count); //接下来就重复地址对齐的情况 */ WriteAddr = count; pBuffer = count; //把整数扇区都写了*/ while (NumOfPage--) { SPI_Flash_Write_Page(pBuffer, WriteAddr, 4096); WriteAddr = 1096; pBuffer = 4096; } //若有多余的不满一扇区的数据,把它写完 if (NumOfSingle != 0) { SPI_Flash_Write_Page(pBuffer, WriteAddr, NumOfSingle); } } } }总结:

/********************************************************************** * Function Name : SPI_Flash_Read * Description : 在指定地址开始读取指定长度的数据 * Input : *pBuffer:存储读出数据的指针 ReadAddr:开始读取的地址(24bit) NumByteToRead:要读取的字节数(最大 16 x 1024 x 1024) * Output : None * Return : None ************************************************************************/ void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead) { u16 i; SPI_FLASH_CS=0; //使能器件 SPI1_ReadWriteByte(CMD_W25X_ReadData); //发送读取命令 SPI1_ReadWriteByte((ReadAddr& 0xFF0000)>>16); //发送扇区地址的高8bit SPI1_ReadWriteByte((ReadAddr& 0xFF00)>>8); //发送扇区地址的中间8bit SPI1_ReadWriteByte( ReadAddr& 0xFF); //发送扇区地址的低8bit for(i=0;i<NumByteToRead;i ) { pBuffer[i]=SPI1_ReadWriteByte(0XFF); //循环读数 } SPI_FLASH_CS=1; //取消片选 }

总结:

SD卡大容量存储器

SD 卡(Secure Digital Memory Card)在我们生活中已经非常普遍了,控制器对 SD卡进行读写通信操作一般有两种通信接口可选,一种是 SPI接口,另外一种是 SDIO 接口。SDIO全称是安全数字输入/输出接口,多媒体卡(MMC)、SD卡、SD I/O 卡(专指使用SDIO 接口的一些输入输出设备)都可使用 SDIO 接口通讯。STM32F10x 系列控制器有一 个 SDIO 主机接口,它支持与上述使用 SDIO 接口的设备进行数据传输。

单片机为什么要接eeprom,单片机一般在什么时候写入eeprom(7)

单片机为什么要接eeprom,单片机一般在什么时候写入eeprom(8)

上一页123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.