何為4線、5線、8線的24C02 ?
在市場上面我們常常會聽到4線、5線、8線的24C02,這里我跟大家解釋一下:
1、所謂的4線24C02:其實就是芯片內(nèi)部母體只打了4種功能線到塑封金屬引腳上。分別是VDD、GND、SDA、SCLK。對于這種芯片的打線方式,芯片的設備地址選擇腳A0A1A2和芯片寫保護腳WP腳在母體上面都固定接地了,當然還有一種情況就是原廠為了省成本在芯片設計的時候就把這部分的電路簡化掉了,所以母體上面根本就沒有這4個腳的PAD。這種打線的芯片是沒有器件地址選擇和寫保護功能的。
2、所謂的5線24C02:其實就是芯片內(nèi)部母體只打了5種功能線到塑封金屬引腳上。分別是GND、SDA、SCLK、WP、VDD、。對于這種芯片的打線方式,芯片的設備地址選擇腳A0A1A2腳在母體上面都固定接地了,當然還有一種情況就是原廠為了省成本在芯片設計的時候就把這部分的電路簡化掉了,所以母體上面根本就沒有這3個腳的PAD。這種打線的芯片是沒有器件地址選擇功能,但是有芯片寫保護功能。
3、所謂的8線24C02:其實就是芯片內(nèi)部母體打了8種功能線到塑封金屬引腳。分別是A0A1A2GNDSDASCLKWPVDD。對于這種芯片的打線方式,24C02的器件地址選擇跟寫保護功能都具備,是功能完全的24C02。
24C02都是以8字節(jié)為一頁劃分的么?
作為24C02的使用者,曾幾何時在我們上大學的時候,學習51單片機編程用的開發(fā)板上面的就有24C02,因此教程實驗里面就有用軟件模擬I2C總線對24C02進行讀寫操作,那時候的24C02數(shù)據(jù)手冊基本清一色都是一個存儲單元可以保存8位數(shù)據(jù),8個存儲單元為一頁的存儲結(jié)構(gòu)。直到后面參加工作以后,發(fā)現(xiàn)市場上面有的廠家的24C02別具特色,芯片內(nèi)部的結(jié)構(gòu)是以一個存儲單元可以保存8位數(shù)據(jù),16個存儲單元為一頁。其實這兩種存儲結(jié)構(gòu)的芯片總?cè)萘渴且粯拥模瑔蝹€存儲單元也是一樣的,唯一不同的地方就是頁的劃分不一樣,8個存儲單元為一頁的芯片內(nèi)部總共是32頁,而16個存儲單元為一頁的芯片內(nèi)部有16頁。因此這兩種芯片的24C02進行頁存取數(shù)據(jù)的時候會有點差異。
如何選擇適合自己的24C02?
1、首先要確定你的產(chǎn)品應用是不是需要多個I2C接口設備,因為這里牽涉到多個設備地址會不會沖突的問題。
2、另外就是確定芯片是否需要寫保護功能。
3、還有就是考慮一下在對24c02進行讀取數(shù)據(jù)時,是按8字節(jié)一頁來操作還是按16字節(jié)一頁來操作的。
另外就是不同廠家的24C02芯片替代也可以跟進上面的3條來確定。我就有遇到過客戶的板子上面用的是打4線的24C02,后面客戶缺貨拿我們的芯片替代上一家的芯片,并且把芯片全部貼到板子上面后,發(fā)現(xiàn)在生產(chǎn)測試的時候板子上面所有的24C02都不能正常讀寫數(shù)據(jù)。后來我拿到客戶的PCBA板看了一下,才知道客戶的應用電路是按打4線的24C02來設計的,他們的應用電路是將WP引腳懸空的。用打5線或者8線的24C02是沒有辦法使用的,因為5線或者8線的24c02的WP腳是有功能的,所以在寫保護功能不用的時候WP腳必須接地,不能懸空或者接VDD上面。因此作為硬件工程師在設計電路的時候,一定要考慮電路兼容性的問題。很多時候采購對不同廠家的芯片的不同細節(jié)不清楚,她們只知道型號一樣以為功能也一樣,所以容易導致出問題。
軟件模式I2C協(xié)議讀取24C02 C語言(STM32)和匯編語音(九齊MCU)
C語言
u8 eepromFlag[16]; void at24c02PortInit(void) { GPIOB_ModeCfg(EEP_SDA_PORT_NUM, GPIO_ModeOut_PP_5mA); GPIOB_ModeCfg(EEP_SCL_PORT_NUM, GPIO_ModeOut_PP_5mA); AT_SDA_H; AT_SCL_H; } void at24c02_Delay(void) { uint16_t i; for (i=0; i<40; i++); } void at24c02Start(void) { AT_SDA_H; at24c02_Delay(); AT_SCL_H ; at24c02_Delay(); AT_SDA_L; at24c02_Delay(); AT_SCL_L ; at24c02_Delay(); } /*---------------------*/ void at24c02Stop(void) { AT_SDA_L; at24c02_Delay(); AT_SCL_H ; at24c02_Delay(); at24c02_Delay(); AT_SDA_H; at24c02_Delay(); } u8 at24c02WriteByte(u8 dat) { u8 mask; for (mask=0x80; mask!=0; mask>>=1) { AT_SCL_L; if ((mask&dat) == 0){ AT_SDA_L; } else { AT_SDA_H; } at24c02_Delay(); AT_SCL_H; at24c02_Delay(); } AT_SCL_L; AT_SDA_H; at24c02_Delay(); AT_SCL_H; at24c02_Delay(); mask = AT_SDA_IN; AT_SCL_L; return mask; } u8 at24c02ReadByte(void) { u8 mask; u8 byte; byte = 0; for (mask=0x80; mask!=0; mask>>=1){ AT_SCL_L; AT_SDA_H; at24c02_Delay(); AT_SCL_H; at24c02_Delay(); if(AT_SDA_IN != 0){ byte |= mask; } } return byte; } static void at24c02ACK(void) { AT_SCL_L; AT_SDA_L; at24c02_Delay(); AT_SCL_H; at24c02_Delay(); AT_SCL_L; } static void at24c02NAK(void) { AT_SCL_L; AT_SDA_H; at24c02_Delay(); AT_SCL_H; at24c02_Delay(); AT_SCL_L; } u8 at24c02ReadACK(void) { u8 byte; byte = at24c02ReadByte(); at24c02ACK(); return byte; } u8 at24c02ReadNAK(void) { u8 byte; byte = at24c02ReadByte(); at24c02NAK(); return byte; } void at24c02WriteDat(u8 WriteAddr,u8 dat) { if (at24c02WaitThenStart(0xa0) != 0) { return; } if (at24c02WriteByte(WriteAddr) != 0) { at24c02Stop(); return; } if(at24c02WriteByte(dat) != 0) { at24c02Stop(); return; } at24c02Stop(); delay_ms(30); } u8 at24c02ReadDat(u8 WriteAddr) { u8 dat; if (at24c02WaitThenStart(0xa0) != 0) { return 0; } if (at24c02WriteByte(WriteAddr) != 0) { at24c02Stop(); return 0; } at24c02Start(); if (at24c02WriteByte(0xa1) != 0) { at24c02Stop(); return 0; } dat = at24c02ReadNAK(); at24c02Stop(); delay_ms(5); return dat; } void at24c02WriteBuf(u8 WriteAddr,u8 *buf,u8 num) { u8 cnt; cnt = num; if (at24c02WaitThenStart(0xa0) != 0) { return; } if (at24c02WriteByte(WriteAddr) != 0) { at24c02Stop(); return; } while (cnt>0) { if(at24c02WriteByte(*buf) != 0) { at24c02Stop(); return; } buf++; cnt--; } at24c02Stop(); delay_ms(30); } void at24c02ReadBuf(u8 WriteAddr,u8 *buf,u8 num) { u8 cnt; cnt = num; if (at24c02WaitThenStart(0xa0) != 0) { return; } if (at24c02WriteByte(WriteAddr) != 0) { at24c02Stop(); return; } at24c02Start(); if (at24c02WriteByte(0xa1) != 0) { at24c02Stop(); return; } while (cnt > 1) { *buf = at24c02ReadACK(); buf++; cnt--; } if (cnt == 1) { *buf = at24c02ReadNAK(); } at24c02Stop(); delay_ms(10); }
匯編語音:
; ============================ WWW.idchip.com ============================================= ; 該測試程序可以測試24C02芯片 ; I2C SDA 是PB4 ->芯片3腳 ; i2C CLK 是PB5 ->芯片2腳 ; PB1->LED_R 讀寫錯誤指示燈 ; PB0->LED_G 讀寫完成指示燈 ; PB2->LED_B 讀寫操作中指示燈 ;//讀或者寫存儲芯片過程中亮藍燈,如果中間發(fā)生錯誤或者讀出來的數(shù)據(jù)跟寫進去的數(shù)據(jù)不一樣報錯亮紅燈 ;//正常成功寫入24C16 完成后,藍燈跟綠燈同時亮 ;//正常成功讀24C16數(shù)據(jù)完成后,注意讀的過程中會跟寫入的數(shù)據(jù)進行比較,如果錯誤則亮紅燈并退出讀操作 ;//全部讀出數(shù)據(jù)并驗證跟寫入的數(shù)據(jù)一樣,藍燈會滅,直亮綠燈 ; File: main.asm ;-------------------------------------------------------------------------- #include AT8A513F.H ; The Header File for AT8A513F ;--------------- Variable Defination -------------------------------------- ;-------------------------------------------------------------------------- ;// temp0 EQU 10H;//H'0010' temp1 EQU 11H;H'0011' ACC_BUF EQU 12H;//H'0012' PFLAG_BUF EQU 13H;H'0013' wait_cnt equ 14H;// FLAG1 equ 15H KEY_CNT equ 16H KEY_LONG_CNT equ 17H delay_10ms_cnt EQU 18H;// I2C_QJ_BLOCK_TEMP EQU 19H block_adder_cnt EQU 1AH block_cnt_temp EQU 1BH page_cnt_temp EQU 1CH I2C_QJ_BLOCK_R_TEMP EQU 1DH page_st_adder EQU 20H ;//頁讀的首地址 ;block_adder_cnt equ 31H ;//塊地址 page_adder_cnt equ 21H ;unit_adder_cnt equ 22H ;//單元地址 write_data_cnt equ 23H ;//寫入的數(shù)據(jù) read_data_cnt equ 24H ;// I2C_WDT EQU 25H I2C_REV EQU 26H;H'0026' DELAY_3S EQU 27H;H'0027' POW_LED EQU 28H;H'0028' DELAY_COUNT EQU 29H;H'0029' ;//=================================== FLAG0 EQU 2AH;H'0029' EEPROM_DATA EQU 2BH;H'002A' TEST_REV EQU 2CH;H'002B' page_rw_byte EQU 2DH;//頁讀寫的字節(jié)數(shù)目 ;、、8字節(jié)還是16字節(jié) page_tab_cnt EQU 2EH;// block_adder_cnt_temp EQU 2FH;// ;//=========================================== ;//====================測試說明============================= #define CODE_3S_MATCH FLAG0,0 #define IR_DET_F FLAG0,1 #define Error_Flag FLAG0,2 #define DELAY_F FLAG0,3 #define LAMP_OFF_F FLAG0,4 #define LED_STATE_F FLAG0,5 #define key_ok_flag FLAG0,6;// #define KEY_UP_FLAG FLAG0,7 #define KEY_LONG_FLAG FLAG1,0;/// #define run_flag FLAG1,1;// #define pwm_up_flag FLAG1,2;// #define key_flag FLAG1,3;// #define start_write_flag FLAG1,4;// #define start_read_flag FLAG1,5;// ;//=================注意240248163264的區(qū)別========================================== ;#define C_02_FLAG FLAG1,0 ;//02每頁是8字節(jié) C02 C04 C08 C16 C32 C64 ;#define C_04_FLAG FLAG1,1 ;//04每頁是16字節(jié) A0 A0 NC NC NC A0 A0 ;#define C_08_FLAG FLAG1,2 ;//08每頁是16字節(jié) A1 A1 A1 NC NC A1 A1 ;#define C_16_FLAG FLAG1,3 ;//16每頁是16字節(jié) A2 A2 A2 A2 NC A2 A2 #define C32_64_FLAG FLAG1,4 ;//32每頁是32字節(jié) ;//#define C_64_FLAG FLAG1,5;//64每頁是32字節(jié) ;//================存儲結(jié)構(gòu)================================================================ ;// 器件 容量 總頁數(shù) 字節(jié)/頁 字地址長度 ;// 24C02 2K 32 8 8 ;;16字節(jié)一頁的芯片只是頁存取改一下即可 ;// 24C04 4K 32 16 9 ;;器件地址bit1 為字地址位高1位 ;// 24C08 8K 64 16 10;;器件地址bit1、bit2為字地址位高2位 ;// 24C16 16K 128 16 11;;器件地址bit1、bit2、bit3位為地址位高3位 ;// 24C32 32K 128 32 12;//需要寫入2個字節(jié)的地址 ;// 24C64 64K 256 32 13;//需要寫入2個字節(jié)的地址 ;//===========================綜合上述了解================================================================ ;//在0-255單元,如果隨機讀寫,24C024816 的讀寫程序是一樣的。 但是C32C64的話注意要讀寫地址都要2個字節(jié) ;//另外就是在0-255這個地址如果進行頁讀寫操作,注意他們每頁的字節(jié)數(shù)就可以了。 ;//======================================================================================================= #define I2C_WADR 0xa0 #define I2C_READ 0xa1 #define WR_ADD0 0x01 #define WR_ADD1 0x00;// #define R 1 #define A 0 ;//==================================== #define KEY_ADJ PORTB,3 ;// #define I2C_SDA PORTB,4 #define I2C_CLK PORTB,5 #define LED_G PORTB,0;//綠表示準確完成讀寫 #define LED_B PORTB,2;//紅色表示讀寫錯誤 #define LED_R PORTB,1;//藍色表示在讀寫過程中 ;//==================================== org 0x000 Lgoto main org 0x008 Lgoto int_time ;========================================= int_time: retie ;//======================================= main: LCALL ClearAllRAM;// LCALL system_init;// MOVIA 200 ;// LCALL delayxms ;// BCR LED_R bCr LED_B BSR LED_G MOVIA 200 ;// LCALL delayxms ;// BCR LED_G BSR LED_B MOVIA 200 ;// LCALL delayxms ;// bcr LED_B ;// ;//========================================== main_loop: BTRSS key_flag ;// LGOTO delay_10ms_fun;//delay_cnt_loop;// BCR key_flag ;// LCALL KEY_ADJ_FUN;// delay_cnt_loop: btrss key_ok_flag lgoto delay_10ms_fun;//main_loop bcr key_ok_flag;// btrsc start_write_flag;// lgoto write_c16_data_loop; btrsc start_read_flag;// lgoto read_c16_data_loop ;// delay_10ms_fun: movia 0x01 LCALL delayxms ;// INCR delay_10ms_cnt,r movia 10 subar delay_10ms_cnt,a btrss STATUS,2 LGOTO main_loop ;//loop clrr delay_10ms_cnt; bsr key_flag;// lgoto main_loop ;// write_c16_data_loop: BCR LED_G BCR LED_R BSR LED_B ;// LCALL page_write_data ;//寫數(shù)據(jù)的前亮藍燈,寫入過程中失敗亮紅的 BTRSC ERROR_flag lgoto delay_10ms_fun;//main_loop BSR LED_G ;//寫入完成藍燈跟綠燈同時亮 lgoto delay_10ms_fun;// main_loop ;// ;//=========================================;// read_c16_data_loop: BCR LED_G BCR LED_R BSR LED_B ;// 讀數(shù)據(jù)前亮藍燈 LCALL page_read_data btrsc ERROR_flag;//讀數(shù)據(jù)過程中失敗亮紅燈 lgoto delay_10ms_fun BCR LED_B;// bsr LED_G;//讀出校驗成功只量綠燈 lgoto main_loop ;//============================================;// KEY_ADJ_FUN: btrsc KEY_ADJ LGOTO KEY_UP_UP BTRSC KEY_UP_FLAG LGOTO KEY_EXIT;// INCR KEY_CNT,R movia 0x02 subar KEY_CNT,A BTRSS STATUS,2 LGOTO KEY_EXIT; CLRR KEY_CNT BSR KEY_UP_FLAG;// BCR KEY_LONG_FLAG;// LGOTO KEY_EXIT; KEY_UP_UP: BTRSS KEY_UP_FLAG;// LGOTO KEY_EXIT; BTRSC start_write_flag lgoto SET_READ_FLAG bsr key_ok_flag bcr LED_R BCR LED_B BCR LED_G bsr start_write_flag bcr start_read_flag bcr KEY_UP_FLAG CLRR KEY_CNT lgoto KEY_EXIT SET_READ_FLAG: bcr LED_R BCR LED_B BCR LED_G bsr key_ok_flag bcr start_write_flag bsr start_read_flag bcr KEY_UP_FLAG CLRR KEY_CNT KEY_EXIT: RET ;===============================================// ClearAllRAM: MOVIA 0x2f ;; Clear Bank0 RAM 0x11-0x3f RAM數(shù)量 MOVAR 10H;clrr_ram_cnt MOVIA 0x11 ;//RAM 地址 MOVAR FSR L_Clear_Next_Byte: CLRR INDF INCR FSR, R DECRSZ 10H,R ;//clrr_ram_cnt, R LGOTO L_Clear_Next_Byte CLRR FSR clrr 10H ret ;//============================================// system_init: movia 0x01 ;// movar PORTB ;// MOVIA 0x08 ;//0000 8 1為輸入 0為輸出 P11輸入上拉 P13輸入下拉 IOST IOSTB ;//配置PB4輸入,PB2為PWM PB1 PB0 PB3 PB5輸出 MOVIA 0x37 ;//1100 0111 MOVAR BPHCON ;//上拉寄存器 0使能 1禁止 PB0-PB5 P14使能上拉 MOVIA 0xff ;// 下拉電阻是bit7-bit4 MOVAR BPLCON ;//下拉寄存器 0使能 1禁止 PB0-PB3 P13使能下拉 MOVIA 0x00 ;// IOST BODCON ;//開漏配置 0禁止 1使能 clrr BWUCON ;// movia 0x00 ;// IOST PCON1 ;//關(guān)閉定時器0 bit0:T0EN bit6:LVDOUT bit7:GIE MOVIA 0x08 ;//bit3:低電壓復位 bit5:低電壓檢測使能 bit7:看門狗使能 movar PCON ;// BSR LED_R bcr LED_B BCR LED_G ret ;//================================================= TIME1_init: movia 0x02 ;// SFUN T1CR1;// movia 0x08 ;//bit3 ->1 關(guān)閉預分頻器 0->打開預分頻器 SFUN T1CR2;//bit0-bit2 預分頻器 000->2 分頻 001->4分頻 movia 100 ;// 37*0.25 SFUN TMR1 ;// movia 0 ;// SFUN PWM1DUTY;// movia 0x83 ;// SFUN T1CR1;// RET delayxms: MOVAR DELAY_COUNT DY_LOOP0: MOVIA 240 MOVAR temp0 DY_LOOP1: NOP DECRSZ temp0,R Lgoto DY_LOOP1 DECRSZ DELAY_COUNT,R Lgoto DY_LOOP0 ret ;//====================================== delayus: NOP NOP NOP NOP NOP NOP ret; ;========================================= i2c_stat: BCR I2C_CLK BCR I2C_SDA LCALL delayus BSR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BCR I2C_SDA LCALL delayus BCR I2C_CLK LCALL delayus ret ;========================================= i2c_stop: BCR I2C_CLK BCR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BSR I2C_SDA LCALL delayus BCR I2C_CLK ret ;================應答回復一個低電平========================= i2c_ack: IOSTR IOSTB ANDIA 0x2f;//P14 設置為輸出 IOST IOSTB;// lCALL delayus BCR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BCR I2C_CLK LCALL delayus ;BSR I2C_SDA ;LCALL delayus ret ;=================非應答給一個高電平======================== i2c_noack: IOSTR IOSTB ANDIA 0x2f;//P14 設置為輸出 IOST IOSTB;// LCALL delayus BSR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BCR I2C_CLK LCALL delayus ret ;=========================================== i2c_write_byte: MOVAR temp1 MOVIA 0x08 MOVAR temp0 W_LOOP: RLR temp1,R ;// BTRSC STATUS,0;// Lgoto w_h w_l: BCR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BCR I2C_CLK LCALL delayus DECRSZ temp0,R Lgoto W_LOOP Lgoto w_ack w_h: BSR I2C_SDA LCALL delayus BSR I2C_CLK LCALL delayus BCR I2C_CLK LCALL delayus DECRSZ temp0,R Lgoto W_LOOP w_ack: BCR Error_Flag;//錯為標志===== IOSTR IOSTB ;// IORIA 0x10 ;// IOST IOSTB ;//P14設置為輸入 NOP NOP BSR I2C_CLK movia 200 ;// movar wait_cnt; wait_ack_l: BTRSS I2C_SDA LGOTO WRITE_OK ;/// LCALL delayus ;/// DECRSZ wait_cnt,r;// LGOTO wait_ack_l;// BSR Error_Flag;// BSR LED_R ;// 接收不到應答信號;// bcr LED_B ;// WRITE_OK: NOP ;//新增加 BCR I2C_CLK ;//新增加 ;//================================ NOP NOP IOSTR IOSTB ;// ANDIA 0x2F ;//P15設置為輸出 0010 1111 1是輸入 0是輸出 IOST IOSTB ;// BCR I2C_SDA NOP NOP ret ;=============================================== i2c_read_byte: CLRR I2C_REV MOVIA 0x08 MOVAR temp0 IOSTR IOSTB ;// IORIA 0x10 ;// IOST IOSTB ;//P15設置為輸入 LCALL delayus R_LOOP: LCALL delayus BSR I2C_CLK LCALL delayus BTRSC I2C_SDA LGOTO R_H NOP NOP BCR I2C_CLK BCR STATUS,0;//C RLR I2C_REV,R DECRSZ temp0,R Lgoto R_LOOP Lgoto R_RETURN R_H: NOP NOP BCR I2C_CLK BSR STATUS,0;//C RLR I2C_REV,R DECRSZ temp0,R lgoto R_LOOP NOP ;// ;/LCALL i2c_ack ;//回復一個應答信號;、、 R_RETURN: LCALL i2c_ack ret ;====================寫任意一個單元地址數(shù)據(jù)======================== i2c_write_data: LCALL i2c_stat;// MOVIA I2C_WADR;// 器件地址 LCALL i2c_write_byte LCALL delayus ;//MOVR ADR_BUF,A movia WR_ADD0 LCALL i2c_write_byte;//單元地址 LCALL delayus BTRSS C32_64_FLAG;//注意C32/C64要寫2個字節(jié)地址 LGOTO W_DATA_LOOP movia WR_ADD1;// LCALL i2c_write_byte;//單元地址 LCALL delayus W_DATA_LOOP: MOVR I2C_WDT,A LCALL i2c_write_byte LCALL delayus LCALL delayus ;//=============寫周期=========== LCALL i2c_stop MOVIA 30 LCALL delayxms ret ;=====================讀任意一個單元地址數(shù)據(jù)========================== i2c_read_data: LCALL i2c_stat;// MOVIA I2C_WADR;//器件地址 LCALL i2c_write_byte; btrsc Error_Flag LGOTO eixt_read_data LCALL delayus LCALL delayus MOVIA WR_ADD0 ;// LCALL i2c_write_byte;// LCALL delayus ;// BTRSS C32_64_FLAG ;//============C32 C64 LGOTO R_DATA_LOOP ;// MOVIA WR_ADD1 LCALL i2c_write_byte LCAll delayus ;//============================= R_DATA_LOOP: LCALL i2c_stat MOVIA I2C_READ LCALL i2c_write_byte;//寫 LCALL delayus ;//============================== LCALL i2c_read_byte LCALL delayus eixt_read_data: LCALL i2c_stop ;//隨機讀的話,讀一個單元發(fā)停止信號,如果是頁讀的話,不用發(fā). ret ;//================頁寫====================================== ;//=================傳遞3個參數(shù) 塊地址 在器件地址的 bit1-bit3 ;//=================頁地址16字節(jié)為一頁 page_write_data: clrr write_data_cnt ;//寫入的數(shù)據(jù)從0-255 clrr page_adder_cnt ;//頁首地址 clrr block_adder_cnt;//塊首地址 movia 32;//16 ;//16頁 movar page_cnt_temp ;// movia 0x01 movar block_cnt_temp ;//8個數(shù)據(jù)塊 movia 0xa0 ;// movar I2C_QJ_BLOCK_TEMP;// write_page_loop: LCALL i2c_stat;// MOVR I2C_QJ_BLOCK_TEMP,A;//I2C_WADR;//0xa0 器件地址 LCALL i2c_write_byte LCALL delayus ;//======================================= movr page_adder_cnt,a;// 從00地址開始 LCALL i2c_write_byte ;//單元地址 LCALL delayus ;// ;//====================================== movia 8;//16 ;//16個字節(jié)為一頁 movar page_rw_byte ;//頁寫數(shù)據(jù)的數(shù)量為16字節(jié) WPAGE_DATA_LOOP: movr write_data_cnt,a;// 要寫入的數(shù)據(jù) LCALL i2c_write_byte ;// LCALL delayus LCALL delayus incr write_data_cnt,r;// decrsz page_rw_byte,r ;//字節(jié)計數(shù)器減一 lgoto WPAGE_DATA_LOOP ;// CLRR page_rw_byte ;// LCALL delayus ;// LCALL delayus ;//完成16字節(jié)的數(shù)據(jù)寫入 ;//=======寫周期======== ;// LCALL i2c_stop ;// MOVIA 10 ;// LCALL delayxms ;// ;//======================================================= decrsz page_cnt_temp,r ;// lgoto page_adder_incr_loop;/// 寫完16頁 movia 32;//16 ;//16頁 movar page_cnt_temp ;// clrr write_data_cnt ;// decrsz block_cnt_temp,r ;// lgoto block_adder_incr_loop;// ret ;// page_adder_incr_loop: movr page_adder_cnt,a ;// addia 0x08 movar page_adder_cnt ;// lgoto write_page_loop block_adder_incr_loop: incr block_adder_cnt,r;// bcr STATUS,0 RLR block_adder_cnt,a ; movar block_adder_cnt_temp addia 0xa0;//I2C_WADR MOVAR I2C_QJ_BLOCK_TEMP ;;//這里面的bit3-bit1 是芯片的塊地址 lgoto write_page_loop ;//寫下一個塊 ;//================頁讀=============================================================================== page_read_data: clrr write_data_cnt ;//寫入的數(shù)據(jù)從0-255 clrr page_adder_cnt ;//頁首地址 clrr block_adder_cnt;//塊首地址 movia 32;//16 ;//16頁 movar page_cnt_temp ;// movia 0x01 movar block_cnt_temp ;//8個數(shù)據(jù)塊 movia 0xa0 ;// movar I2C_QJ_BLOCK_TEMP;// movia 0xa1 movar I2C_QJ_BLOCK_R_TEMP ; movia 0x40 ;//對一頁的首地址單頁測試 ; movar page_adder_cnt ;// ;//========================================================= read_page_loop: LCALL i2c_stat;// MOVR I2C_QJ_BLOCK_TEMP,A;//0xa0;//I2C_WADR;//寫入器件地址 LCALL i2c_write_byte; btrsc Error_Flag LGOTO eixt_read_data LCALL delayus LCALL delayus MOVR page_adder_cnt,A;//0x20;//WR_ADD0;//寫入單元地址或者頁首地址 LCALL i2c_write_byte;// LCALL delayus ;// ;//============================= RPAGE_LOOP: LCALL i2c_stat ;// MOVR I2C_QJ_BLOCK_R_TEMP,A;//0xa1 ;I2C_READ ;// LCALL i2c_write_byte;//寫入對器件讀操作指令 LCALL delayus ;// movia 8;//16;//;//16 寫8個字節(jié)或者16個字節(jié) movar page_rw_byte ;//頁寫數(shù)據(jù)的數(shù)量為16字節(jié) ; movia 0x30 ;//緩存數(shù)據(jù)的單元首地址 0x30-0x3f 為緩存單元塊 ; movar FSR ;// ; CLRR INDF ;// RPAGE_DATE_LOOP: LCALL i2c_read_byte ;// movr I2C_REV,a ;// subar write_data_cnt,a;//比較讀出來的數(shù)據(jù)跟寫入的數(shù)據(jù)是否一樣,注意首地址讀寫要對的上 btrss STATUS,2 LGOTO exit_read_loop ; movar INDF ; INCR FSR,R INCR write_data_cnt,r;// DECRSZ page_rw_byte,R ;// lgoto RPAGE_DATE_LOOP;//比較完一頁數(shù)據(jù) LCALL delayus LCALL delayus LCALL i2c_stop ;//隨機讀的話,讀一個單元發(fā)停止信號,如果是頁讀的話,不用發(fā). decrsz page_cnt_temp,r ;// lgoto R_page_adder_incr_loop;/// 讀完16頁 也就是一塊數(shù)據(jù) movia 32;//16 ;//1塊有16頁 movar page_cnt_temp ;// clrr write_data_cnt ;// decrsz block_cnt_temp,r ;// lgoto W_block_adder_incr_loop;// ret ;// R_page_adder_incr_loop: movr page_adder_cnt,a ;// addia 0x08;//0x10 movar page_adder_cnt ;//讀下一頁,頁地址要加16 16字節(jié)為一頁 lgoto read_page_loop ;// W_block_adder_incr_loop: incr block_adder_cnt,r;// bcr STATUS,0 RLR block_adder_cnt,A movar block_adder_cnt_temp addia 0xa0;//I2C_WADR bit0 = 0表示對器件寫入數(shù)據(jù) MOVAR I2C_QJ_BLOCK_TEMP ;;//這里面的bit3-bit1 是芯片的塊地址 movr block_adder_cnt_temp,a addia 0xa1 ;//bit0 = 1表示對器件讀數(shù)據(jù) movar I2C_QJ_BLOCK_R_TEMP;// lgoto read_page_loop ;//寫下一個塊 ;//================================================================== exit_read_loop: bcr LED_R BCR LED_B BCR LED_G ret ;//============================================ end 審核編輯 黃昊宇
-
芯片
+關(guān)注
關(guān)注
452文章
50224瀏覽量
420983 -
24c02
+關(guān)注
關(guān)注
0文章
67瀏覽量
30677
發(fā)布評論請先 登錄
相關(guān)推薦
評論