專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

單片機(jī)匯編實(shí)驗(yàn)六:I2C串行總線存儲(chǔ)器讀寫實(shí)驗(yàn)

作者:韓冰   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年11月30日   【字體:

實(shí)驗(yàn)要求:由AT89S52內(nèi)部定時(shí)器1,按方式1工作,每1秒鐘24C02的0001H單元內(nèi)容加2,以鍵盤作為外部中斷輸入信號(hào),有鍵按下時(shí),讀取0001H單元內(nèi)容并由LED顯示。

//This is the sixth program of the homework;
//Name :Wang Qi     Date:2013/3/11  北京化工大學(xué)   自實(shí)1001
     SDA EQU P2.0
    SCL EQU P2.1
    ORG 0000H     //主函數(shù)入口
    SJMP MAIN
   ORG 0013H     //外部中斷1入口
   LJMP WZD0
   ORG 001BH     //計(jì)時(shí)器1入口
   LJMP WT1
   ORG 0050H  
MAIN:        MOV SP,#60H
                   MOV TMOD,#10H  //設(shè)置T1工作方式
                  MOV TH1,#4CH   //設(shè)初值
   MOV TL1,#00H
   MOV R7,#10  //計(jì)數(shù)器
   SETB EA                 //全局中斷
   SETB ET1  //允許定時(shí)器1
   SETB TR1 //啟動(dòng)定時(shí)器1
                   SETB IT1 //外部中斷跳變觸發(fā)方式
   SETB EX1 //允許外部中斷1  
OK:            MOV C,P3.4            //掃描鍵盤
                   JNC OK1
   MOV C,P3.5
   JNC OK1
   MOV C,P3.6
   JNC OK1
   MOV C,P3.7
   JNC OK1
   SJMP OK
OK1:          CLR P3.3    //中斷信號(hào)
                  SETB P3.3
  SJMP OK
WZD0:
                 SETB P3.3 //中斷程序
                 PUSH TH1                //保護(hù)現(xiàn)場(chǎng)
 PUSH TL1    
 CLR  TR1                 //停止T1計(jì)數(shù)
  MOV  R2,#01H 
                 CALL DU
                 MOV P1,R3    
 POP TL1
 POP TH1
 SETB TR1 
 RETI
WT1:        MOV TH1,#4CH      //定時(shí)函數(shù)
                MOV TL1,#00H
                DJNZ R7,RET0
                MOV R7,#10 //1秒到來(lái)了
                INC 30H
                INC 30H  
                mov R2,#01H  
                MOV R3,30H
                CALL XIE
RET0: RETI
 
//////////////I2C協(xié)議摘自網(wǎng)絡(luò)  Thanks to the author
XIE: //寫數(shù)據(jù)子程序,R2是要寫入的24c02的字節(jié)位置地址,R3是要寫入的內(nèi)容
LCALL STAR;起始條件
MOV A,#10100000B //尋址24C02的總線硬件地址并使用寫入命令
LCALL SDATA        //傳輸數(shù)據(jù)A給24C02
MOV A,R2                //確定要寫入的字節(jié)位置地址
LCALL SDATA        //傳輸數(shù)據(jù)A給24C02
MOV A,R3               //把數(shù)據(jù)R3寫入剛指定的字節(jié)地址
LCALL SDATA       //傳輸數(shù)據(jù)A給24C02
LCALL STOP          //寫入結(jié)束
LCALL CHULI //提供2ms給24C02內(nèi)部處理剛寫入的數(shù)據(jù)
RET
DU:   ;讀數(shù)據(jù)子程序,R2是要讀的24c02的字節(jié)位置地址,讀完后A傳給R3
LCALL STAR;起始條件
MOV A,#10100000B//尋址24C02的總線硬件地址并使用寫入命令
LCALL SDATA      //傳輸數(shù)據(jù)A給24C02
MOV A,R2   //注意,這里是使24C02的字節(jié)地址指針變成R2的值,也就是確定要讀取的字節(jié)位置地址
LCALL SDATA     //傳輸數(shù)據(jù)A給24C02
LCALL STAR        //重復(fù)起始條件
MOV A,#10100001B//尋址24C02的總線硬件地址并使用讀出命令(這里正式發(fā)起讀命令)
LCALL SDATA//傳輸數(shù)據(jù)A給24C02
LCALL RDATA//從之前指定的字節(jié)地址中讀出字節(jié)內(nèi)容到A
LCALL STOP //讀取完畢(這里并沒有連續(xù)讀取,只能讀一個(gè)字節(jié),要多個(gè)字節(jié)連續(xù)讀取,請(qǐng)自己在R2上做變址讀取循環(huán))
MOV R3,A     //讀出的字節(jié)傳給R3
RET
STAR:SETB SDA //起始條件子程序
SETB SCL
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
RET
SDATA:MOV R0,#08H //向24C02傳輸數(shù)據(jù)子程序
LOOP0:CLR SCL
RLC A
MOV SDA,C
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
DJNZ R0,LOOP0
CLR SCL
NOP
SETB SDA
NOP
NOP
SETB SCL
REP:MOV C,SDA
JC REP
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
RDATA:MOV R0,#08H  //從24C02讀取數(shù)據(jù)子程序(讀取一個(gè)字節(jié)以后不做應(yīng)答)
LOOP1:SETB SCL
NOP
NOP
NOP
NOP
MOV C,SDA
RLC A
CLR SCL
NOP
NOP
NOP
NOP
DJNZ R0,LOOP1
SETB SCL
NOP
NOP
NOP
NOP
CLR SCL
RET
STOP:CLR SDA   ;結(jié)束條件
NOP
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
RET
CHULI:  //1999uS ;這里是用于寫完數(shù)據(jù)以后留給24C02的內(nèi)部數(shù)據(jù)處理時(shí)間,2ms是一個(gè)非常保險(xiǎn)的時(shí)間,最短需要1ms
    MOV R6,#04H
    WR0:
    MOV R5,#0F8H
    DJNZ R5,$
    DJNZ R6,WR0
    RET
END
 

關(guān)閉窗口

相關(guān)文章