pic16f877A软件模拟I2C通信读写24C02
扫描二维码
随时随地手机看文章
;该试验功能是单片机复位一次,自动从24C02中读取数据到数码管显示,然后对值加1再写入24C02,最终数码管中的数据就是开机的次数,具有一定的实用意义
;本电路所使用24C02为ATMEL的,或不是该厂的,则烧写时间可能会有差异
;必须调整本程序的DELAY时间
;本实战的目的是让大家进上步熟悉I2C通信的时序,熟悉24CXX的读写,会用软件模拟I2C通信
;硬件接法:
;1.24CXX的SDA接877A的RB5口,SCLK接877A的RB4口,WP接地,A0,A1,A2接地
LISTP=16F877A,R=DEC
include"P16F877A.inc"
;***********************************
__CONFIG_DEBUG_OFF&_CP_OFF&_WRT_HALF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC;
;************************************定义查表偏移量
#defineSDAPORTB,5
#defineSCLKPORTB,4
;*********************
COUNTEQU20H
ADDREQU21H
DATEQU23H
TEMPEQU24H
;**********************
ORG000H
NOP;放置一条ICD必需的空操作指令
GOTOMAIN
ORG004H
RETURN
ORG0008H
;******************************************************
TABLE
ADDWFPCL,1;地址偏移量加当前PC值
RETLW0C0H;0
RETLW0F9H;1
RETLW0A4H;2
RETLW0B0H;3
RETLW99H;4
RETLW92H;5
RETLW82H;6
RETLW0F8H;7
RETLW80H;8
RETLW98H;9
RETLW00H;A
RETLW00H;B
RETLW00H;C
RETLW00H;D
RETLW00H;E
RETLW00H;F
;*******************************************************
MAIN
MOV LW0FFH
MOV WFPORTC;数码管先全部熄灭
MOV LW0FFH
MOV WFPORTA
MOV LW0FFH
MOV WFPORTB;SDT,SCLK都为高
BSFSTATUS,RP0;定义RA口,RC,RB口全部为输出
MOV LW07H
MOV WFADCON1;设置RA口全部为普通数字IO口
CLRW
MOV WFTRISB;
MOV WFTRISA
MOV WFTRISC
MOV WFOPTION_REG;开启RB口内部弱上拉
BCFSTATUS,RP0
CLRW;地址00H
CALLRD24;读地址
MOV WFDAT;读出的值送F1
SUBLW.9;若读出的值大于9,则F1送为0,从0开始(因为1位数码管只能显示到0-9)
BCTT2;C=0就转TT2
TT1
CLRFDAT
TT2
MOV FWDAT
CALLTABLE;取显示段码
MOV WFPORTC;段码送C口
BCFPORTA,1;点亮第一位数码管
INCFDAT,1;每次上电,存入24CXX的00H地址的值加1
CLRW;地址00H
CALLWT24;写24CXX
GOTO$
;****************************
RD24
MOV WFADDR;地址暂存于F4中
CALLSTART24;启动I2C
MOV LW0A0H
CALLSUBS;写器件地址1010000+最后一位0写操作
MOV FWADDR;载入地址
CALLSUBS;写地址
CALLSTART24;再发开始信号
MOV LW0A1H;写器件地址1010000+最后一位1读操作
CALLSUBS
BSFSTATUS,RP0
BSFTRISB,5;设SDA脚为输入,准备读
BCFSTATUS,RP0
MOV LW08H;共读8位数据
MOV WFCOUNT
RD000
NOP
NOP
NOP
BSFSCLK;读数据
NOP
BSFSTATUS,C
BTFSSSDA
BCFSTATUS,C
RLFTEMP,1
BCFSCLK
DECFSZCOUNT,1;循环读完8位
GOTORD000
BSFSTATUS,RP0
BCFTRISB,5;恢复SDA脚为输出
BCFSTATUS,RP0
BSFSDA
CALLDELAY2
BSFSCLK
CALLDELAY2
BCFSCLK;应答毕,SDA置1
CALLSTOP;送停止信号
MOV FWTEMP;将读的数据送入W中
RETURN
;******************************写入24C02程序
WT24 MOV WFADDR;先将地址暂存于F4
CALLSTART24;开始条件
MOV LW0A0H
CALLSUBS;写器件地址1010000+最后一位0写操作
MOV FWADDR;载入地址
CALLSUBS;写地址
MOV FWDAT;载入数据
CALLSUBS;写数据
CALLSTOP;停止信号
RETURN
START24
;开始条件
BSFSDA
BSFSCLK
CALLDELAY2
BCFSDA
CALLDELAY2
BCFSCLK
RETURN
STOP
BCFSDA;停止条件
NOP
NOP
BSFSCLK
CALLDELAY2
BSFSDA
RETURN
SUBS;写数据
MOV WFTEMP;将要写的数据存于F2中
MOV LW08H
MOV WFCOUNT;写8位数据
SH01
RLFTEMP,1
BSFSDA
BTFSSSTATUS,C
BCFSDA
NOP
BSFSCLK
CALLDELAY2
BCFSCLK
DECFSZCOUNT,1;循环写完8位
GOTOSH01
BSFSDA
NOP
NOP
BSFSCLK
BSFSTATUS,RP0
BSFTRISB,5
BCFSTATUS,RP0
REP
BTFSCSDA;判应答到否,未到则等待
GOTOREP
BCFSCLK
BSFSTATUS,RP0
BCFTRISB,5
BCFSTATUS,RP0
RETURN
DELAY2
NOP
NOP
NOP
NOP
RETURN
;********************************************
end;源程序结束