pIC16f877A软件模拟I2C通信读写24C02
;该试验功能是 单片机 复位一次,自动从24C02中读取数据到数码管显示,然后对值加1再写入24C02,最终数码管中的数据就是开机的次数,具有一定的实用意义
;本电路所使用24C02为ATMEL的,或不是该厂的,则烧写时间可能会有差异
;必须调整本程序的DELAY时间
;本实战的目的是让大家进上步熟悉I2C通信的时序,熟悉24CXX的读写,会用软件模拟I2C通信
;硬件接法:
;1.24CXX的SDA接877A的RB5口,SCLK接877A的RB4口,WP接地,A0,A1,A2接地
LIST P=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;
;************************************ 定义查表偏移量
#define SDA PORTB,5
#define SCLK PORTB,4
;*********************
COUNT EQU 20H
ADDR EQU 21H
DAT EQU 23H
TEMP EQU 24H
;**********************
ORG 000H
NOP ;放置一条ICD必需的空操作指令
GOTO MAIN
ORG 004H
RETURN
ORG 0008H
;******************************************************
TABLE
ADDWF PCL,1 ;地址偏移量加当前PC值
RETLW 0C0H ;0
RETLW 0F9H ;1
RETLW 0A4H ;2
RETLW 0B0H ;3
RETLW 99H ;4
RETLW 92H ;5
RETLW 82H ;6
RETLW 0F8H ;7
RETLW 80H ;8
RETLW 98H ;9
RETLW 00H ;A
RETLW 00H ;B
RETLW 00H ;C
RETLW 00H ;D
RETLW 00H ;E
RETLW 00H ;F
;*******************************************************
MAIN
MOV LW 0FFH
MOV WF PORTC ;数码管先全部熄灭
MOV LW 0FFH
MOV WF PORTA
MOV LW 0FFH
MOV WF PORTB ;SDT,SCLK都为高
BSF STATUS,RP0 ;定义RA口,RC,RB口全部为输出
MOV LW 07H
MOV WF ADCON1 ;设置RA口全部为普通数字IO口
CLRW
MOV WF TRISB ;
MOV WF TRISA
MOV WF TRISC
MOV WF OPTION_REG ;开启RB口内部弱上拉
BCF STATUS,RP0
CLRW ;地址00H
CALL RD24 ;读地址
MOV WF DAT ;读出的值送F1
SUBLW .9 ;若读出的值大于9,则F1送为0,从0开始(因为1位数码管只能显示到0-9)
BC TT2 ;C=0就转TT2
TT1
CLRF DAT
TT2
MOV FW DAT
CALL TABLE ;取显示段码
MOV WF PORTC ;段码送C口
BCF PORTA ,1 ;点亮第一位数码管
INCF DAT ,1 ;每次上电,存入24CXX的00H地址的值加1
CLRW ;地址00H
CALL WT24 ;写24CXX
GOTO $
;****************************
RD24
MOV WF ADDR ;地址暂存于F4中
CALL START24 ;启动I2C
MOV LW 0A0H
CALL SUBS ;写器件地址1010000+最后一位0写操作
MOV FW ADDR ;载入地址
CALL SUBS ;写地址
CALL START24 ;再发开始信号
MOV LW 0A1H ;写器件地址1010000+最后一位1读操作
CALL SUBS
BSF STATUS ,RP0
BSF TRISB ,5 ;设SDA脚为输入,准备读
BCF STATUS ,RP0
MOV LW 08H ;共读8位数据
MOV WF COUNT
RD000
NOP
NOP
NOP
BSF SCLK ;读数据
NOP
BSF STATUS,C
BTFSS SDA
BCF STATUS,C
RLF TEMP ,1
BCF SCLK