| | ;****************************************** ;** 24CXX 接口I2C總線讀/寫(xiě)的程序 ;** (所有時(shí)序均基于4MHZ晶體震蕩器頻率) ;****************************************** /* ;**************************** ;隨機(jī)讀寫(xiě)測(cè)試程序(示范程序) ;**************************** TEST: MOV A,@0XAE ;A2=A1=A0=1 MOV SLAVE_24,A ;設(shè)置器件碼 MOV A,@2 ;R/W LOC. = 2 MOV ADDR_24,A ;設(shè)置地址碼 MOV A,@55 ; MOV DATA_24,A ;寫(xiě)55到E2PROM CALL WRBYTE ;寫(xiě)一個(gè)字節(jié) CALL DL10MS ;延時(shí)10MS,等待寫(xiě)操作完成(注意,此語(yǔ)句非常重要) CALL RDBYTE ;讀回原數(shù)據(jù) MOV A,@55 ; XOR A,DATA_24 ; JBS R3,Z ;讀出數(shù)據(jù)=寫(xiě)入數(shù)據(jù)跳 WRONG: JMP WRONG ;校驗(yàn)失敗 CORRECT: JMP CORRECT ;校驗(yàn)通過(guò) DL10MS: RET ;**************************** ;存儲(chǔ)器定義 ;**************************** PROT_I2C EQU 0X05 ;I2C操作口 SDA EQU 3 ;數(shù)據(jù)腳 SCL EQU 2 ;時(shí)鐘腳
ADDR_24 EQU 0X1B ;地址寄存器 DATA_24 EQU 0X1C ;寫(xiě)入/讀自I2C的數(shù)據(jù)寄存器 SLAVE_24 EQU 0X1D ;從器件地址寄存器(1010XXX0) DBUF_24 EQU 0X1E ;發(fā)送/接受自SDA口的數(shù)據(jù)緩沖器 COUNT_24 EQU 0X1F ;位計(jì)數(shù)器 TT_24 EQU 0X20 ;標(biāo)志寄存器 REND_24 EQU 1 ;讀完畢標(biāo)志(0=未完畢,1=完畢) NUM_24 EQU 0X21 ;頁(yè)寫(xiě)/頁(yè)讀字節(jié)數(shù)
*/ ;**************************** ;宏定義 ;**************************** ;================= ;設(shè)置SCL,SDA為輸出口 ;================= SDA_OUT MACRO MOV A,@0B00000001 IOW PROT_I2C ENDM ;================= ;設(shè)置SCL為輸出口,SDA為輸入口 ;================= SDA_IN MACRO MOV A,@0B00001001 IOW PROT_I2C ENDM ;**************************** ;字節(jié)寫(xiě)程序 ;功能: 寫(xiě)一個(gè)字節(jié)到EEPROM器件 ;入口: DATA_24 =要寫(xiě)的數(shù)據(jù) ; ADDR_24 =數(shù)據(jù)地址 ; SLAVE_24=從器件地址1010XXX0) ;**************************** WRBYTE: MOV A,SLAVE_24 MOV DBUF_24,A CALL BSTART ;送起始位 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) MOV A,ADDR_24 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)地址并檢測(cè)應(yīng)答信號(hào) MOV A,DATA_24 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)并檢測(cè)應(yīng)答信號(hào) CALL BSTOP ;送停止位 RET ;**************************** ;字節(jié)讀程序 ;功能: 從EEPROM器件讀一個(gè)字節(jié) ;入口: ADDR_24 =數(shù)據(jù)地址 ; SLAVE_24=從器件地址(1010XXX0) ;出口: DATA_24 =讀到的數(shù)據(jù) ;**************************** RDBYTE: MOV A,SLAVE_24 MOV DBUF_24,A CALL BSTART ;送起始位 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) MOV A,ADDR_24 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)地址并檢測(cè)應(yīng)答信號(hào) ;轉(zhuǎn)入讀狀態(tài) CALL BSTART ;送起始位 MOV A,SLAVE_24 MOV DBUF_24,A BS DBUF_24,0 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) BS TT_24,REND_24 CALL RX ;讀數(shù)據(jù)并發(fā)送應(yīng)答信號(hào) CALL BSTOP ;送停止位 MOV A,DBUF_24 MOV DATA_24,A ;保存數(shù)據(jù)到DATA_24 RET ;**************************** ;頁(yè)寫(xiě)程序 ;功能: 寫(xiě)一個(gè)字節(jié)到EEPROM器件 ;入口: R4 =要寫(xiě)的數(shù)據(jù)在RAM中存放首地址 ; NUM_24 =字節(jié)數(shù) ; ADDR_24 =數(shù)據(jù)地址 ; SLAVE_24=從器件地址1010XXX0) ;**************************** WRPAGE: MOV A,SLAVE_24 MOV DBUF_24,A CALL BSTART ;送起始位 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) MOV A,ADDR_24 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)地址并檢測(cè)應(yīng)答信號(hào) WRPAGE1: MOV A,R0 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)并檢測(cè)應(yīng)答信號(hào) INC R4 DJZ NUM_24 JMP WRPAGE1 ;未寫(xiě)完繼續(xù) CALL BSTOP ;送停止位 RET ;**************************** ;頁(yè)讀程序 ;功能: 從EEPROM器件讀一個(gè)字節(jié) ;入口: ADDR_24 =數(shù)據(jù)地址 ; SLAVE_24=從器件地址(1010XXX0) ; NUM_24 =字節(jié)數(shù) ;出口: R4 =讀到的數(shù)據(jù)在RAM中存放首地址 ;**************************** RDPAGE: MOV A,SLAVE_24 MOV DBUF_24,A CALL BSTART ;送起始位 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) MOV A,ADDR_24 MOV DBUF_24,A CALL TX ;送數(shù)據(jù)地址并檢測(cè)應(yīng)答信號(hào) ;轉(zhuǎn)入讀狀態(tài) CALL BSTART ;送起始位 MOV A,SLAVE_24 MOV DBUF_24,A BS DBUF_24,0 CALL TX ;送從器件地址并檢測(cè)應(yīng)答信號(hào) RDPAGE1: MOV A,@1 XOR A,NUM_24 BS TT_24,REND_24 JBS R3,Z ;NUM_24=1跳;判斷是否最后一個(gè)字節(jié),決定應(yīng)答信號(hào) BC TT_24,REND_24 CALL RX ;讀數(shù)據(jù)并發(fā)送應(yīng)答信號(hào) MOV A,DBUF_24 MOV R0,A ;保存數(shù)據(jù)到R0 INC R4 DJZ NUM_24 JMP RDPAGE1 ;未讀完繼續(xù) CALL BSTOP ;送停止位 RET ;**************************** ;I2C操作子程序(時(shí)序)集合 ;**************************** ;================= ;發(fā)送起始位程序 ;說(shuō)明: 當(dāng)SCL=1時(shí),向SDA發(fā)一個(gè)下降沿 ;================= BSTART: SDA_OUT ;設(shè)置SDA為輸出口 BS PROT_I2C,SDA ;SDA=1 NOP ;延時(shí)0.6US BS PROT_I2C,SCL ;SCL=1 NOP ;延時(shí)0.6US BC PROT_I2C,SDA ;SDA=0 NOP ;延時(shí)0.6US BC PROT_I2C,SCL ;SCL=0 NOP ;延時(shí)0.6US RET ;================= ;發(fā)送結(jié)束位程序 ;說(shuō)明: 當(dāng)SCL=1時(shí),向SDA發(fā)一個(gè)上升沿 ;================= BSTOP: SDA_OUT ;設(shè)置SDA為輸出口 BC PROT_I2C,SDA ;SDA=0 NOP ;延時(shí)0.6US BS PROT_I2C,SCL ;SCL=1 NOP ;延時(shí)0.6US BS PROT_I2C,SDA ;SDA=1 NOP ;延時(shí)0.6US RET ;================= ;位輸入子程序 ;說(shuō)明: 當(dāng)SCL=1時(shí),從SDA上讀電平 ;出口: C=從SDA上讀入的位值 ;================= BITIN: SDA_IN ;設(shè)置SDA為輸入口 BS PROT_I2C,SDA ;SDA=1 NOP ;延時(shí)0.6US BS PROT_I2C,SCL ;SCL=1 NOP ;延時(shí)0.6US BC R3,C JBC PROT_I2C,SDA BS R3,C ;C=SDA NOP ;延時(shí)0.6US BC PROT_I2C,SCL ;SCL=0 NOP ;延時(shí)0.6US RET ;================= ;位輸出子程序 ;說(shuō)明: 每當(dāng)SCL=0時(shí),改寫(xiě)SDA上的電平 ;入口: C=要寫(xiě)到SDA上的位值 ;================= BITOUT: SDA_OUT ;設(shè)置SDA為輸出口 JBS R3,C JMP BIT0 BS PROT_I2C,SDA ;SDA=C=1 JMP CLK1 BIT0: BC PROT_I2C,SDA ;SDA=C=0 CLK1: NOP ;延時(shí)0.6US BS PROT_I2C,SCL ;SCL=1 BIT2: NOP NOP BC PROT_I2C,SCL ;SCL=0 RET ;============================ ;接收數(shù)據(jù)子程序 ;入口: TT_24.REND_24 =讀完畢標(biāo)志 ;出口: DBUF_24 =接受到的數(shù)據(jù)(8_BIT) ;============================ RX: MOV A,@8 ;循環(huán)次數(shù)=8 MOV COUNT_24,A CLR DBUF_24 RXLP: CALL BITIN ;輸入1_BIT RLC DBUF_24 ;左移(帶C) DJZ COUNT_24 ;循環(huán)結(jié)束? JMP RXLP ;設(shè)置應(yīng)答信號(hào)位,如果讀完畢則送1(NO_ACK)停止接受,否則送0(ACK)繼續(xù)接受 BS R3,C JBS TT_24,REND_24 ;讀完畢信號(hào)->C BC R3,C CALL BITOUT ;應(yīng)答 RET ;============================ ;發(fā)送數(shù)據(jù)子程序 ;入口: DBUF_24 =要發(fā)送的數(shù)據(jù)(8_BIT) ;============================ TX: MOV A,@8 ;循環(huán)次數(shù)=8 MOV COUNT_24,A TXLP: RLC DBUF_24 ;左移(帶C) CALL BITOUT ;輸出1_BIT DJZ COUNT_24 ;循環(huán)結(jié)束? JMP TXLP CALL BITIN ;讀應(yīng)答信號(hào) RET
;**************************** ;I2C總線讀/寫(xiě)的程序全部結(jié)束 ! ;**************************** |
|
|