EEPROM (Electrically Erasable Programmable read only memory)是指帶電可擦可編程只讀存儲(chǔ)器。是一種掉電后數(shù)據(jù)不丟失的存儲(chǔ)芯片。EEPROM 可以在電腦上或?qū)S迷O(shè)備上擦除已有信息,重新編程。一般用在即插即用。AT24C02是一個(gè)2K位串行CMOS E2PROM, 內(nèi)部含有256個(gè)8位字節(jié),CATALYST公司的先進(jìn)CMOS技術(shù)實(shí)質(zhì)上減少了器件的功耗。AT24C02有一個(gè)16字節(jié)頁寫緩沖器。該器件通過IIC總線接口進(jìn)行操作,有一個(gè)專門的寫保護(hù)功能。
一、模塊來源
模塊實(shí)物展示:
二、規(guī)格參數(shù)
工作電壓:1.8V-5.5V
工作電流:最大3mA
通信接口:IIC
內(nèi)存:2048位
時(shí)鐘速度:5V時(shí)最大1000Khz,其余為400Khz
以上信息見廠家資料文件
三、移植過程
我們的目標(biāo)是將例程移植至CW32F030C8T6開發(fā)板上【能夠播報(bào)語音的功能】。首先要獲取資料,查看數(shù)據(jù)手冊(cè)應(yīng)如何實(shí)現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。
3.1查看資料
上圖是AT24CXX的設(shè)備地址(第一行的為AT24C02,它的容量為2K),我們發(fā)現(xiàn)AT24CXX整個(gè)系列芯片的地址高四位都相同,都是1010,這四位是由生產(chǎn)商固化在芯片內(nèi)部,無法改變。
AT24C02地址的低三位(不包括讀寫位)對(duì)應(yīng)芯片的三個(gè)引腳,也就是說這三位是可以人為設(shè)定的,23=8,所以一條I2C總線上可以掛載8個(gè)AT24C02。
AT24C02的地址為7位二進(jìn)制數(shù),下圖中最后一位是讀寫位(數(shù)據(jù)方向位),1 表示讀數(shù)據(jù),0 表示寫數(shù)據(jù)。
這樣,7位設(shè)備地址加1位讀寫位,構(gòu)成I2C的尋址數(shù)據(jù)。I2C 總線的尋址過程中,通常在起始條件后的第一個(gè)字節(jié)決定了主機(jī)選擇哪一個(gè)從機(jī),該字節(jié)的最后一位決定數(shù)據(jù)傳輸方向。
AT24C02讀寫:AT24C02的存儲(chǔ)空間為2K位(256字節(jié)),在對(duì)其進(jìn)行寫數(shù)據(jù)時(shí),最小寫入單位為字節(jié)(Byte),最大寫入單位為頁(Page),AT24C02頁大小為 16 Byte。
字節(jié)寫
在字節(jié)寫模式下,主器件發(fā)送起始信號(hào)和從器件地址信息(R/W 位置零)給從器件,在從器件送回應(yīng)答信號(hào)后,主器件發(fā)送 AT24WC01/02/04/08/16 的字節(jié)地址,主器件在收到從器件的應(yīng)答信號(hào)后,再發(fā)送數(shù)據(jù)到被尋址的存儲(chǔ)單元。AT24WC01/02/04/08/16 再次應(yīng)答,并在主器件產(chǎn)生停止信號(hào)后開始內(nèi)部數(shù)據(jù)的擦寫,在內(nèi)部擦寫過程中,AT24WC01/02/04/08/16 不再應(yīng)答主器件的任何請(qǐng)求。
頁寫
用頁寫,AT24WC01 可一次寫入 8 個(gè)字節(jié)數(shù)據(jù),AT24WC02/04/08/16 可以一次寫入 16 個(gè)字節(jié)的數(shù)據(jù),頁寫操作的啟動(dòng)和字節(jié)寫一樣,不同在于傳送了一字節(jié)數(shù)據(jù)后并不產(chǎn)生停止信號(hào),主器件被允許發(fā)送 P(AT24WC01 P=7;AT24WC02/04/08/16 P=15)個(gè)額外的字節(jié)。每發(fā)送一個(gè)字節(jié)數(shù)據(jù)后 AT24WC01/02/04/08/16 產(chǎn)生一個(gè)應(yīng)答位并將字節(jié)地址低位加 1,高位保持不變。
如果在發(fā)送停止信號(hào)之前主器件發(fā)送超過P+1個(gè)字節(jié),地址計(jì)數(shù)器將自動(dòng)翻轉(zhuǎn),先前寫入的數(shù)據(jù)被覆蓋。
接收到P+1字節(jié)數(shù)據(jù)和主器件發(fā)送的停止信號(hào)后,AT24CXXX啟動(dòng)內(nèi)部寫周期將數(shù)據(jù)寫到數(shù)據(jù)區(qū),所有接收的數(shù)據(jù)在一個(gè)寫周期內(nèi)寫入AT24WC01/02/04/08/16。
當(dāng)前地址讀
AT24WC01/02/04/08/16 的地址計(jì)數(shù)器內(nèi)容為最后操作字節(jié)的地址加 1。也就是說 如果上次讀/寫的操作地址為 N,則立即讀的地址從地址 N+1 開始。如果 N=E(這里對(duì) 24WC01 E=127;對(duì) 24WC02 E=255;對(duì) 24WC04 E=511;對(duì) 24WC08 E=1023;對(duì) 24WC16 E=2047)則計(jì)數(shù)器將翻轉(zhuǎn)到 0 且繼續(xù)輸出數(shù)據(jù)。AT24WC01/02/04/08/16 接收到從器件地址信號(hào)后(R/W 位置 1),它首先發(fā)送一個(gè)應(yīng)答信號(hào),然后發(fā)送一個(gè) 8 位字節(jié)數(shù)據(jù)。主器件不需發(fā)送一個(gè)應(yīng)答信號(hào),但要產(chǎn)生一個(gè)停止信號(hào)。
選擇讀(隨機(jī)讀)
選擇性讀操作允許主器件對(duì)寄存器的任意字節(jié)進(jìn)行讀操作,主器件首先通過發(fā)送起始信號(hào)、從器件地址和它想讀取的字節(jié)數(shù)據(jù)的地址執(zhí)行一個(gè)偽寫操作。在 AT24WC01/02/04/08/16 應(yīng)答之后,主器件重新發(fā)送起始信號(hào)和從器件地址,此時(shí) R/W 位置 1,AT24WC01/02/04/08/16 響應(yīng)并發(fā)送應(yīng)答信號(hào),然后輸出所要求的一個(gè) 8 位字節(jié)數(shù)據(jù),主器件不發(fā)送應(yīng)答信號(hào)但產(chǎn)生一個(gè)停止信號(hào)。
連續(xù)讀
連續(xù)讀操作可通過立即讀或選擇性讀操作啟動(dòng)。在 AT24WC01/02/04/08/16 發(fā)送完一個(gè) 8 位字節(jié)數(shù)據(jù)后,主器件產(chǎn)生一個(gè)應(yīng)答信號(hào)來響應(yīng),告知 AT24WC01/02/04/08/16 主器件要求更多的數(shù)據(jù),對(duì)應(yīng)每個(gè)主機(jī)產(chǎn)生的應(yīng)答信號(hào) AT24WC01/02/04/08/16 將發(fā)送一個(gè) 8 位數(shù)據(jù)字節(jié)。當(dāng)主器件不發(fā)送應(yīng)答信號(hào)而發(fā)送停止位時(shí)結(jié)束此操作。
從 AT24WC01/02/04/08/16 輸出的數(shù)據(jù)按順序由 N 到 N+1 輸出。讀操作時(shí)地址計(jì)數(shù)器在 AT24WC01/02/04/08/16 整個(gè)地址內(nèi)增加,這樣整個(gè)寄存器區(qū)域在可在一個(gè)讀操作內(nèi)全部讀出。當(dāng)讀取的字節(jié)超過 E(對(duì)于 24WC01 E=127;對(duì) 24WC02 E=255; 對(duì) 24WC04 E=511;對(duì) 24WC08 E=1023;對(duì) 24WC16 E=2047)計(jì)數(shù)器將翻轉(zhuǎn)到零并繼續(xù)輸出數(shù)據(jù)字節(jié)。
3.2引腳選擇
模塊接線圖
3.3移植至工程
移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_at24c02.c與bsp_at24c02.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。
在文件bsp_at24c02.c中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-25 LCKFB-LP first version */ #include "bsp_at24c02.h" #include "stdio.h" // SLAVE ADDRESS+W為0xA0,SLAVE ADDRESS+R為0xA1 #define AT24C02_ADDRESS_READ 0xA0 #define AT24C02_ADDRESS_WRITE 0xA1 /****************************************************************** * 函 數(shù) 名 稱:AT24C02_GPIO_Init * 函 數(shù) 說 明:AT24C02的引腳初始化 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void AT24C02_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結(jié)構(gòu)體 RCC_AT24C02_GPIO_ENABLE(); // 使能GPIO時(shí)鐘 GPIO_InitStruct.Pins = GPIO_SDA|GPIO_SCL; // GPIO引腳 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 開漏輸出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(PORT_AT24C02, &GPIO_InitStruct); // 初始化 } /****************************************************************** * 函 數(shù) 名 稱:IIC_Start * 函 數(shù) 說 明:IIC起始時(shí)序 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Start(void) { SDA_OUT(); SDA(1); delay_us(5); SCL(1); delay_us(5); SDA(0); delay_us(5); SCL(0); delay_us(5); } /****************************************************************** * 函 數(shù) 名 稱:IIC_Stop * 函 數(shù) 說 明:IIC停止信號(hào) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Stop(void) { SDA_OUT(); SCL(0); SDA(0); SCL(1); delay_us(5); SDA(1); delay_us(5); } /****************************************************************** * 函 數(shù) 名 稱:IIC_Send_Ack * 函 數(shù) 說 明:主機(jī)發(fā)送應(yīng)答或者非應(yīng)答信號(hào) * 函 數(shù) 形 參:0發(fā)送應(yīng)答 1發(fā)送非應(yīng)答 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Send_Ack(unsigned char ack) { SDA_OUT(); SCL(0); SDA(0); delay_us(5); if(!ack) SDA(0); else SDA(1); SCL(1); delay_us(5); SCL(0); SDA(1); } /****************************************************************** * 函 數(shù) 名 稱:I2C_WaitAck * 函 數(shù) 說 明:等待從機(jī)應(yīng)答 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:0有應(yīng)答 1超時(shí)無應(yīng)答 * 作 者:LC * 備 注:無 ******************************************************************/ unsigned char I2C_WaitAck(void) { char ack = 0; unsigned char ack_flag = 10; SCL(0); SDA(1); SDA_IN(); delay_us(5); SCL(1); delay_us(5); while( (SDA_GET()==1) && ( ack_flag ) ) { ack_flag--; delay_us(5); } if( ack_flag <= 0 ) { IIC_Stop(); return 1; } else { SCL(0); SDA_OUT(); } return ack; } /****************************************************************** * 函 數(shù) 名 稱:Send_Byte * 函 數(shù) 說 明:寫入一個(gè)字節(jié) * 函 數(shù) 形 參:dat要寫入的數(shù)據(jù) * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void Send_Byte(uint8_t dat) { int i = 0; SDA_OUT(); SCL(0);//拉低時(shí)鐘開始數(shù)據(jù)傳輸 for( i = 0; i < 8; i++ ) { SDA( (dat & 0x80) >> 7 ); delay_us(1); SCL(1); delay_us(5); SCL(0); delay_us(5); dat<=1; } } /****************************************************************** * 函 數(shù) 名 稱:Read_Byte * 函 數(shù) 說 明:IIC讀時(shí)序 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:讀到的數(shù)據(jù) * 作 者:LC * 備 注:無 ******************************************************************/ unsigned char Read_Byte(void) { unsigned char i,receive=0; SDA_IN();//SDA設(shè)置為輸入 for(i=0;i8;i++ ) { SCL(0); delay_us(5); SCL(1); delay_us(5); receive<=1; if( SDA_GET() ) { receive|=1; } delay_us(5); } SCL(0); return receive; } /****************************************************************** * 函 數(shù) 名 稱:AT24C02_WriteByte * 函 數(shù) 說 明:AT24C02寫入一個(gè)字節(jié) * 函 數(shù) 形 參:WordAddress 要寫入字節(jié)的地址 Data 要寫入的數(shù)據(jù) * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void AT24C02_WriteByte(unsigned char WordAddress,unsigned char Data) { IIC_Start(); Send_Byte(AT24C02_ADDRESS_READ); I2C_WaitAck(); Send_Byte(WordAddress); I2C_WaitAck(); Send_Byte(Data); I2C_WaitAck(); IIC_Stop(); } /****************************************************************** * 函 數(shù) 名 稱:AT24C02_ReadByte * 函 數(shù) 說 明:AT24C02讀取一個(gè)字節(jié) * 函 數(shù) 形 參:WordAddress 要讀出字節(jié)的地址 * 函 數(shù) 返 回:讀出的數(shù)據(jù) * 作 者:LC * 備 注:無 ******************************************************************/ unsigned char AT24C02_ReadByte(unsigned char WordAddress) { unsigned char Data; IIC_Start(); Send_Byte(AT24C02_ADDRESS_READ); I2C_WaitAck(); Send_Byte(WordAddress); I2C_WaitAck(); IIC_Start(); Send_Byte(AT24C02_ADDRESS_WRITE); I2C_WaitAck(); Data=Read_Byte(); IIC_Send_Ack(1); IIC_Stop(); return Data; }
在文件bsp_at24c02.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-25 LCKFB-LP first version */ #ifndef _BSP_AT24C02_H_ #define _BSP_AT24C02_H_ #include "board.h" //端口移植 #define RCC_AT24C02_GPIO_ENABLE() __RCC_GPIOB_CLK_ENABLE() #define PORT_AT24C02 CW_GPIOB #define GPIO_SDA GPIO_PIN_8 #define GPIO_SCL GPIO_PIN_9 //設(shè)置SDA輸出模式 #define SDA_OUT() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_SDA; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_AT24C02, &GPIO_InitStruct); } //設(shè)置SDA輸入模式 #define SDA_IN() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_SDA; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_AT24C02, &GPIO_InitStruct); } //獲取SDA引腳的電平變化 #define SDA_GET() GPIO_ReadPin(PORT_AT24C02, GPIO_SDA) //SDA與SCL輸出 #define SDA(x) GPIO_WritePin(PORT_AT24C02, GPIO_SDA, (x?GPIO_Pin_SET:GPIO_Pin_RESET) ) #define SCL(x) GPIO_WritePin(PORT_AT24C02, GPIO_SCL, (x?GPIO_Pin_SET:GPIO_Pin_RESET) ) void AT24C02_GPIO_Init(void); void AT24C02_WriteByte(unsigned char WordAddress,unsigned char Data); unsigned char AT24C02_ReadByte(unsigned char WordAddress); #endif
四、移植驗(yàn)證
在自己工程中的main主函數(shù)中,編寫如下。
/* * Change Logs: * Date Author Notes * 2024-06-25 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "bsp_at24c02.h" int32_t main(void) { unsigned char dat1 = 0; unsigned char dat2 = 0; board_init(); uart1_init(115200U); AT24C02_GPIO_Init(); printf("startrn"); //向0地址寫入數(shù)據(jù)48 AT24C02_WriteByte(0,48); delay_ms(5); //向8地址寫入數(shù)據(jù)48 AT24C02_WriteByte(8,66); delay_ms(5); //從0地址讀取數(shù)據(jù)到dat1 dat1 = AT24C02_ReadByte(0); delay_ms(5); //從8地址讀取數(shù)據(jù)到dat2 dat2 = AT24C02_ReadByte(8); delay_ms(5); delay_ms(50); //輸出dat查看數(shù)據(jù)是否正確 printf("dat1 = %drn",dat1); delay_ms(1); printf("dat2 = %drn",dat2); delay_ms(1); while(1) { } }
移植現(xiàn)象:
向0地址寫入數(shù)據(jù)48,再讀出查看是否是48。
向8地址寫入數(shù)據(jù)66,再讀出查看是否是66。
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/1vMkhtubSlSjCLW960FccxQ?pwd=LCKF
提取碼:LCKF
-
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7613瀏覽量
165913 -
EEPROM
+關(guān)注
關(guān)注
9文章
1061瀏覽量
83007 -
存儲(chǔ)芯片
+關(guān)注
關(guān)注
11文章
920瀏覽量
43819 -
CW32
+關(guān)注
關(guān)注
1文章
232瀏覽量
1037
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
STM32基礎(chǔ)知識(shí):IIC總線操作EEPROM存儲(chǔ)模塊AT24C02

TCL 2101C-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2108-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2128B-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2129C-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2136A-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2136C-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2169A-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
TCL 2169C-24C04(TCLM5C02)存儲(chǔ)器數(shù)據(jù)
使用51單片機(jī)和EEPROM存儲(chǔ)器24C02保持保存實(shí)現(xiàn)流水燈的程序

使用51單片機(jī)進(jìn)行EEPROM存儲(chǔ)器24C02讀取存儲(chǔ)多字節(jié)的程序免費(fèi)下載

使用EEPROM存儲(chǔ)器24C02記憶開機(jī)次數(shù)的代碼免費(fèi)下載

24C02 EEPROM存儲(chǔ)器的應(yīng)用程序詳細(xì)說明
EEPROM存儲(chǔ)芯片AT24C02芯片手冊(cè)

評(píng)論