21.1實(shí)驗(yàn)內(nèi)容
通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
AT24C16 EEPROM的工作原理;
IIC模塊原理以及IIC驅(qū)動(dòng)原理。
21.2實(shí)驗(yàn)原理
21.2.1AT24C16 EEPROM的工作原理
下圖為AT24CXX系列EEPROM相關(guān)參數(shù),由該圖可知,AT24C16的存儲(chǔ)容量為16Kbit,共2048字節(jié),共128頁(yè),每頁(yè)為16字節(jié)。
由下圖可知,AT24C16由8塊組成,每塊256字節(jié)。
I2C開始信號(hào)后,第一個(gè)字節(jié)為器件地址,由1010+3位塊地址+1位讀寫標(biāo)志組成,3位塊地址剛好可以表示8個(gè)塊, 所以一次寫完256字節(jié),換到下一下塊的時(shí)候,要重新更改器件地址。
AT24C16支持頁(yè)寫入模式,一次最多可支持寫入16字節(jié)。主機(jī)每發(fā)送一個(gè)字節(jié),24c16收到確認(rèn),內(nèi)部地址遞增(僅限低4bit,所以1次可寫16字節(jié))。
21.2.2IIC接口原理
GD32F30X系列MCU的I2C接口模塊實(shí)現(xiàn)了I2C協(xié)議的標(biāo)速模式,快速模式以及快速+模式,具備CRC計(jì)算和校驗(yàn)功能、支持SMBus(系統(tǒng)管理總線)和PMBus(電源管理總線),此外還支持多主機(jī)I2C總線架構(gòu),其主要特性如下:
?并行總線至I2C總線協(xié)議的轉(zhuǎn)換及接口;
?同一接口既可實(shí)現(xiàn)主機(jī)功能又可實(shí)現(xiàn)從機(jī)功能;
?主從機(jī)之間的雙向數(shù)據(jù)傳輸;
?支持7位和10位的地址模式和廣播尋址;
?支持I2C多主機(jī)模式;
?支持標(biāo)速(最高100 KHz),快速(最高400 KHz)和快速+模式(最高1MHz);
?從機(jī)模式下可配置的SCL主動(dòng)拉低;
?支持DMA模式;
?兼容SMBus 2.0和PMBus;
?兩個(gè)中斷:字節(jié)成功發(fā)送中斷和錯(cuò)誤事件中斷;
?可選擇的PEC(報(bào)文錯(cuò)誤校驗(yàn))生成和校驗(yàn)。
IIC模塊結(jié)構(gòu)框圖如下所示。
21.3硬件設(shè)計(jì)
EEPROM硬件電路圖如下所示,IIC引腳使用PB10和PB11引腳,SDA和SCL總線通過(guò)4.7K電阻上拉,且對(duì)地接30pf電容以及100歐姆串阻濾波。
21.4代碼解析
21.4.1EEPROM初始化配置函數(shù)
EEPROM初始化配置函數(shù)如下,主要實(shí)現(xiàn)對(duì)IIC總線引腳配置以及IIC模塊配置。
C void bsp_eeprom_init_AT24C16(void) { driver_i2c_init(&EEPROM_I2C); } void driver_i2c_init(typdef_i2c_struct *i2cx) { rcu_periph_clock_enable(i2cx->rcu_i2c_x); i2c_deinit(i2cx->i2c_x); driver_gpio_general_init(i2cx->i2c_scl_gpio); driver_gpio_general_init(i2cx->i2c_sda_gpio); /* I2C clock configure */ i2c_clock_config(i2cx->i2c_x, i2cx->frequency, I2C_DTCY_2); /* I2C address configure */ i2c_mode_addr_config(i2cx->i2c_x, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, i2cx->slave_addr); /* enable I2C0 */ i2c_enable(i2cx->i2c_x); /* enable acknowledge */ i2c_ack_config(i2cx->i2c_x, I2C_ACK_ENABLE); } |
21.4.2EEPROM buf寫入接口函數(shù)
EEPROM buf寫入接口函數(shù)實(shí)現(xiàn)如下,通過(guò)該函數(shù)可實(shí)現(xiàn)對(duì)AT24C16任意地址的多字節(jié)寫入。內(nèi)部已根據(jù)地址和寫入長(zhǎng)度自動(dòng)識(shí)別從機(jī)地址以及對(duì)應(yīng)的塊,然后寫入正確的地址空間。
C EEPROM_STATE eeprom_buffer_write_AT24C16(uint8_t* p_buffer, uint16_t write_address, uint16_t number_of_byte) { uint8_t number_of_page = 0, number_of_single = 0, address = 0, count = 0; uint8_t deviceId; address = write_address % I2C_PAGE_SIZE; count = I2C_PAGE_SIZE - address; number_of_page = number_of_byte / I2C_PAGE_SIZE; number_of_single = number_of_byte % I2C_PAGE_SIZE; if(write_address+write_address>EEPROM_SIZE) { return EEPROM_ERROR; } /* if write_address is I2C_PAGE_SIZE aligned */ if(0 == address){ while(number_of_page--){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer,I2C_PAGE_SIZE) == DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C) == EEPROM_ERROR) { return EEPROM_ERROR; } write_address += I2C_PAGE_SIZE; p_buffer += I2C_PAGE_SIZE; } if(0 != number_of_single){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer, number_of_single)==DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C) == EEPROM_ERROR) { return EEPROM_ERROR; } } return EEPROM_SUCCESS; }else{ /* if write_address is not I2C_PAGE_SIZE aligned */ if(number_of_byte < count){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer, number_of_byte)==DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C)==EEPROM_ERROR) { return EEPROM_ERROR; } }else{ number_of_byte -= count; number_of_page = number_of_byte / I2C_PAGE_SIZE; number_of_single = number_of_byte % I2C_PAGE_SIZE; if(0 != count){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer, count)==DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C)==EEPROM_ERROR) { return EEPROM_ERROR; } write_address += count; p_buffer += count; } /* write page */ while(number_of_page--){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer, I2C_PAGE_SIZE)==DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C)==EEPROM_ERROR) { return EEPROM_ERROR; } write_address += I2C_PAGE_SIZE; p_buffer += I2C_PAGE_SIZE; } /* write single */ if(0 != number_of_single){ deviceId=(write_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((write_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_write(&EEPROM_I2C,deviceId,write_address,MEM_ADDRESS_8BIT,p_buffer, number_of_single)==DRV_ERROR) { return EEPROM_ERROR; } if(eeprom_wait_standby_state(&EEPROM_I2C)==EEPROM_ERROR) { return EEPROM_ERROR; } } } return EEPROM_SUCCESS; } } |
21.4.3EEPROM buf讀取接口函數(shù)
EEPROM buf讀取接口函數(shù)實(shí)現(xiàn)如下,通過(guò)該函數(shù)可實(shí)現(xiàn)對(duì)EEPROM任意地址的多字節(jié)數(shù)據(jù)讀取,內(nèi)部也對(duì)讀取的地址進(jìn)行自動(dòng)識(shí)別從機(jī)地址。
C EEPROM_STATE eeprom_buffer_read_AT24C16(uint8_t* p_buffer, uint16_t read_address, uint16_t number_of_byte) { uint8_t rNum=0; //讀取的數(shù)據(jù)長(zhǎng)度 uint16_t lenLeft=number_of_byte;//剩余的數(shù)據(jù)長(zhǎng)度 uint8_t deviceId;//讀取的器件地址 if(read_address+number_of_byte>EEPROM_SIZE)//如果讀取的長(zhǎng)度加上讀取地址超過(guò)了EEPROM的空間大小,則報(bào)錯(cuò)誤 { return EEPROM_ERROR; } /*calculate the current read position to know how many word can read continully*/ rNum=16-read_address & 0x0F; if(rNum == 0) rNum=16; rNum = lenLeft>=rNum ? rNum : lenLeft;//剩余未讀字節(jié)數(shù)如果大于rNum, 則讀rNum個(gè),如果小于rNum,則一次讀完了 /*read the data from e2prom*/ while(lenLeft) { //這里計(jì)算頁(yè)地址,當(dāng)?shù)刂沸∮?56時(shí),右移8位會(huì)小于0,所以器件地址為基地址A1 //如果讀取的地址大于256時(shí),右移8位則不會(huì)小于0,所以器件地址為 基地址A1 | 3位頁(yè)地址 deviceId=(read_address>>8)>0 ? (EEPROM_ADDR | (uint8_t)((read_address>>7)&0x0E)):EEPROM_ADDR ; if(driver_i2c_mem_poll_read(&EEPROM_I2C,deviceId,read_address,MEM_ADDRESS_8BIT,p_buffer,rNum)==DRV_ERROR) { // printf('i2c read errorrn'); return EEPROM_ERROR; } read_address+=rNum;//已經(jīng)讀了rNum個(gè)了,所以地址后移rNum個(gè) lenLeft-=rNum;//剩余未讀數(shù)據(jù)減少rNum個(gè) p_buffer+=rNum; rNum=lenLeft>16? 16 : lenLeft;//如果剩余大于16個(gè),則下次再讀16個(gè),如果小于,則一次讀完 } return EEPROM_SUCCESS; } |
21.4.4EEPROM讀寫實(shí)驗(yàn)主函數(shù)
EEPROM讀寫實(shí)驗(yàn)主函數(shù)如下所示。通過(guò)該實(shí)驗(yàn)實(shí)現(xiàn)對(duì)AT24C16任意地址256字節(jié)的寫入、讀取以及校驗(yàn)測(cè)試。
C int main(void) { uint16_t i; uint8_t i2c_buffer_write[BUFFER_SIZE]; uint8_t i2c_buffer_read[BUFFER_SIZE]; bsp_eeprom_init_AT24C16(); /* initialize i2c_buffer_write */ for(i = 0;i < BUFFER_SIZE;i++){ i2c_buffer_write[i]=i; // printf('0x%02X ',i2c_buffer_write[i]); // if(15 == i%16){ // printf('rn'); // } } if(eeprom_buffer_write_AT24C16(i2c_buffer_write,0x0153,BUFFER_SIZE)==EEPROM_SUCCESS) { __nop(); } if(eeprom_buffer_read_AT24C16(i2c_buffer_read,0x0153,BUFFER_SIZE)==EEPROM_SUCCESS) { __nop(); } /* compare the read buffer and write buffer */ for(i = 0;i < BUFFER_SIZE;i++){ if(i2c_buffer_read[i] != i2c_buffer_write[i]){ __nop(); // printf('0x%02X ', i2c_buffer_read[i]); // printf('Err:data read and write aren't matching.nr'); // return I2C_FAIL; } //printf('0x%02X ', i2c_buffer_read[i]); // if(15 == i%16){ // printf('rn'); // } } __nop(); // printf('I2C-AT24C02 test passed!nr'); while (1) { } } |
21.5實(shí)驗(yàn)結(jié)果
將本實(shí)驗(yàn)歷程燒錄到紅楓派開發(fā)板中,運(yùn)行后,可通過(guò)串口打印測(cè)試結(jié)果,可實(shí)現(xiàn)對(duì)于AT24C16任意地址寫入、讀取以及校驗(yàn)。
上一篇:【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二十講八 USB-虛擬串口實(shí)驗(yàn)
下一篇:【GD32F303紅楓派開發(fā)板使用手冊(cè)】第十一講 ADC-電源電壓?jiǎn)瓮ǖ繟DC檢測(cè)實(shí)驗(yàn)
推薦閱讀最新更新時(shí)間:2025-06-22 10:51





設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級(jí)數(shù)字信號(hào)控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無(wú)線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲(chǔ)html,css,js文件,以及網(wǎng)頁(yè)和arduino的通訊
- ESP32 freeRTOS使用測(cè)試
- 在隔離應(yīng)用中使用 AD7740
- DC2373A,使用 LT8641 65V、3.5A 微功率同步降壓靜音開關(guān)的演示板
- Tda7385 4 X 30W 四橋車載收音機(jī)放大器的典型應(yīng)用
- 時(shí)間控制板 帶均衡
- 手持無(wú)線電通訊器
- 使用 Analog Devices 的 AD8033AKS 的參考設(shè)計(jì)
- #第五屆立創(chuàng)電子設(shè)計(jì)大賽#QCC5124藍(lán)牙高保真播放器
- 使用 ROHM Semiconductor 的 BD5244 的參考設(shè)計(jì)
- AM2G-0518SH30Z 18V 2 瓦 DC/DC 轉(zhuǎn)換器的典型應(yīng)用
- 基于STUSB4500的即用型USB PD控制器評(píng)估板
- 雷達(dá)液位計(jì)在大型化工儲(chǔ)罐中的應(yīng)用
- 為什么有時(shí)按下【Run/Stop】鍵響應(yīng)慢?
- Mobileye自動(dòng)駕駛汽車在巴黎街頭開跑
- 聞泰科技:安世開發(fā)了100v以上MOSFET新產(chǎn)品
- STM32 SPI和TM1628通信
- 土壤pH測(cè)試儀的簡(jiǎn)單介紹
- 改善客戶體驗(yàn):當(dāng)今企業(yè)的業(yè)務(wù)關(guān)鍵和潛在商機(jī)
- 新意網(wǎng)超大規(guī)模數(shù)據(jù)中心 MEGA Gateway 正式開幕
- 電動(dòng)機(jī)保護(hù)用斷路器的選擇原則
- ARXML 規(guī)則下 ECU 總線通訊與 ADTF 測(cè)試方案
- 日產(chǎn)在歐洲推出第三代e-POWER技術(shù)
- 福特CEO更看好Waymo激光雷達(dá)方案:比特斯拉純視覺自動(dòng)駕駛路線可靠
- 智元機(jī)器人兩大核心產(chǎn)品啟動(dòng)規(guī)?;a(chǎn)
- 固態(tài)電池2026量產(chǎn)豪賭,真相還是泡沫?
- 100億元!湖北“下注”人形機(jī)器人產(chǎn)業(yè)
- 海外磷酸鐵鋰電池產(chǎn)能從0到1
- 基于多傳感器數(shù)據(jù)的自動(dòng)駕駛仿真確定性驗(yàn)證
- 國(guó)芯科技發(fā)布全球首款48V安全氣囊芯片,引領(lǐng)智能汽車新紀(jì)元
- 亞馬遜全球部署100萬(wàn)臺(tái)機(jī)器人
- 能源互聯(lián)網(wǎng):“去中心化控制”勢(shì)在必行
- 泛在電力物聯(lián)網(wǎng)與能源革命
- 提升上海城市能級(jí)需要"加速器",泛在電力物聯(lián)網(wǎng)已在路上
- 泛在電力物聯(lián)網(wǎng)衍生“智能業(yè)務(wù)”的展望
- 武漢借力泛在電力物聯(lián)網(wǎng),AI智能機(jī)器人為軍運(yùn)會(huì)保電
- 為激勵(lì)員工下血本,TCL有多拼?
- 三條高世代線陸續(xù)量產(chǎn),液晶面板價(jià)格進(jìn)入新一輪下行周期?
- 背光市場(chǎng)大陸品牌擠壓,臺(tái)系廠商轉(zhuǎn)攻mini LED、CSP等高端應(yīng)用
- 京東方大秀MWC2018,“8K+5G”成重頭戲
- 關(guān)于無(wú)人機(jī),從何處來(lái)往何處去?
- M16配套的USBASP下載線調(diào)試報(bào)告。
- DM9000硬件問(wèn)題怎么檢測(cè)
- 如何正確使用示波器
- 中興通訊內(nèi)部推薦
- 急!請(qǐng)高手回答stm32關(guān)于can通信的問(wèn)題
- msp430F5438A 的ADC 研究
- 準(zhǔn)備學(xué)習(xí)嵌入式,大家提點(diǎn)建議,謝謝
- 電源設(shè)計(jì)小貼士 39:同步整流帶來(lái)的不僅僅是高效率
- 有沒(méi)有大神猜得出這個(gè)芯片是什么?問(wèn)了5個(gè)網(wǎng)站都無(wú)人能解
- 春天,真的是萬(wàn)物復(fù)蘇的季節(jié)~~~