AT24C02 Driver
/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __AT24_H #define __AT24_H #include <string.h> #include "hw_twi.h" #include "hw_def.h" /* AT24C02, 2K Bits SERIAL EEPROM: Internally organized with 32 pages of 8 bytes each, the 2K Bits requires an 8-bit data word address for random word addressing. // Serial EEPROM type ////////////////////////////////////////////////////////// #define IIC_EEPROM_AT24C01 1 // AT24C01 - 1K ( 128 x 8) ( 8 byte page write) #define IIC_EEPROM_AT24C02 2 // AT24C02 - 2K ( 256 x 8) ( 8 byte page write) #define IIC_EEPROM_AT24C04 4 // AT24C04 - 4K ( 512 x 8) (16 byte page write) #define IIC_EEPROM_AT24C08 8 // AT24C08 - 8K (1024 x 8) (16 byte page write) #define IIC_EEPROM_AT24C16 16 // AT24C16 -16K (2048 x 8) (16 byte page write) +---+---+---+---+---+---+---+---+ 1k/2K | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C01A/AT24C02 +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ 4k | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C04 +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ 8k | 1 | 0 | 1 | 0 | A2| P1| P0|R/W| AT24C08 +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ 16k | 1 | 0 | 1 | 0 | P2| P1| P0|R/W| AT24C16 +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ 512k | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C512 +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ 1M | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C1024 +---+---+---+---+---+---+---+---+ P0,P1,P2 - Page Address */ #define AT24_CMD_READ ( 0xA1 ) #define AT24_CMD_WRITE ( 0xA0 ) #define AT24_CHIP_SIZE ( 0x100 ) #define AT24_PAGE_SIZE ( 0x08 ) #define AT24_WRITE_TIMEOUT ( 50 ) #define AT24_PAGE_MASK ( AT24_PAGE_SIZE-1 ) #define AT24_PAGE_COUNT ( AT24_CHIP_SIZE/AT24_PAGE_SIZE ) unsigned int AT24_Init(void); void AT24_ReadMemory(unsigned int dwAddr, unsigned int dwSize, unsigned char * Memory); void AT24_WriteMemory(unsigned int dwAddr, unsigned int dwSize, unsigned char * Memory); #endif /*__AT24_H*/
#include "AT24.h" #include "hw_eeprom_addr.h" unsigned int AT24_Init(void) { #if ( 1 ) unsigned int TestValue; unsigned int i = 0; do { TestValue = 0xAA; AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned char *)&TestValue); if ( ( i > 0 ) || ( TestValue == 0x55 ) ) break; AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned char *)&TestValue); i++; } while (1); return ( TestValue == 0x55 ); #else unsigned int TestValue; TestValue = 0xAA; AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue); if ( TestValue != 0x55 ) { TestValue = 0x55; AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue); TestValue = 0xAA; AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue); } return ( TestValue == 0x55 ); #endif } // only for UserZone 0..2 void AT24_ReadMemory(unsigned int dwAddr, unsigned int dwSize, unsigned char * Memory) { //memset( Memory, 0xFF, dwSize ); if ( dwAddr + dwSize > AT24_CHIP_SIZE ) return; #if ( AT24_CHIP_SIZE > 0x0800 ) // AT24C32 > 2048 Bytes #else // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR // Write Address HW_TWI_Start( HW_TWI_AT24 ); HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ) ); if ( HW_TWI_ReadACK( HW_TWI_AT24 ) == HW_TWI_NACK ) { HW_TWI_Stop( HW_TWI_AT24 ); return; } HW_TWI_SendByte(HW_TWI_AT24, dwAddr ); HW_TWI_ReadACK( HW_TWI_AT24 ); // READ Data HW_TWI_Start( HW_TWI_AT24 ); HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_READ | ( (dwAddr>>8) << 1 ) ); HW_TWI_ReadACK( HW_TWI_AT24 ); while ( dwSize ) { *Memory = HW_TWI_ReceiveByte ( HW_TWI_AT24 ); if ( dwSize == 1 ) HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_NACK ); else HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_ACK ); Memory++; dwSize--; } HW_TWI_Stop( HW_TWI_AT24 ); #endif } void AT24_WritePage(unsigned int dwAddr, unsigned int dwSize, unsigned char * Memory) { #if ( AT24_CHIP_SIZE > 0x0800 ) // AT24C32 > 2048 Bytes #else // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR HW_TWI_Start( HW_TWI_AT24 ); HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ) ); if ( HW_TWI_ReadACK( HW_TWI_AT24 ) == HW_TWI_NACK ) { HW_TWI_Stop( HW_TWI_AT24 ); return; } HW_TWI_SendByte(HW_TWI_AT24, dwAddr ); HW_TWI_ReadACK( HW_TWI_AT24 ); while ( dwSize ) { HW_TWI_SendByte(HW_TWI_AT24, *Memory ); HW_TWI_ReadACK( HW_TWI_AT24 ); Memory++; dwSize--; } HW_TWI_Stop( HW_TWI_AT24 ); // Poll Ack from eeprom HW_TWI_WaitComplete(HW_TWI_AT24, AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ), AT24_WRITE_TIMEOUT); #endif } /* When the word address, internally generated, reaches the page boundary, the following byte is placed at the beginning of the same page. If more than eight (1K/2K) or sixteen (4K, 8K, 16K) data words are transmitted to the EEPROM, the data word address will roll over and previous data will be overwritten. */ void AT24_WriteMemory(unsigned int dwAddr, unsigned int dwSize, unsigned char * Memory) { unsigned int dwSizeInPage; if ( dwAddr + dwSize > AT24_CHIP_SIZE ) return; while ( dwSize > 0 ) { dwSizeInPage = AT24_PAGE_SIZE - ( dwAddr & (AT24_PAGE_SIZE-1) ); if ( dwSizeInPage > dwSize ) dwSizeInPage = dwSize; AT24_WritePage(dwAddr, dwSizeInPage, Memory); dwSize -= dwSizeInPage; Memory += dwSizeInPage; dwAddr += dwSizeInPage; // now it must be page alignment } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本