现在的现象是:第1次按RB0能正常写,按RB1也能正常读,但是按复位键后就再也不能正常读跟写了,必须重新上电才可以。 源程序如下,烦请大家给我指点下 ;实验目的:熟悉MSSP通信协议。 ;当按键RB0按下时,把6个连续的数据写入到6个连续的单元内 ;写完成后数码管显示单个0,做为标志位 ;当按键RB1按下后读取EEPROM连续六个单元 ;读取结果送6位数码管显示 ;硬件要求:拨码开关S2、S5、S6全部置ON, #include<p16f877a.inc> ;包含头文件 ERRORLEVEL -302 SDA EQU 4 ;数据I/O SCL EQU 3 ;时钟I/O DATA_W EQU 75H ;发送数据寄存器 DATA_R EQU 76H ;接受数据寄存器 DL1 EQU 77H ;延时用 DL2 EQU 78H ;延时用 ADDRESS EQU 0AH ;待写入数据的EEPROM地址 VALUE EQU 0H ;待写入EEPROM中的数据 COUNT EQU 20H
ORG 0 ;复位入口地址 GOTO MAIN
TABLE ADDWF PCL,1 ;PC值加上偏移地址 RETLW 0C0H ;0的编码(公阳极数码管) RETLW 0F9H ;1的编码 RETLW 0A4H ;2的编码 RETLW 0B0H ;3的编码 RETLW 99H ;4的编码 RETLW 92H ;5的编码 RETLW 082H ;6 MAIN NOP ;ICD所需要的空指令 CLRF PCLATH ;保证程序在页面0内 CALL INIT_I2C ;调用IIC初始化程序 CLRF DATA_R ;清0接受数据寄存器 MOVLW VALUE MOVWF DATA_W ;待写入数据送寄存器 BTFSC PORTB,0 GOTO $+7 CALL WRITE ;调用写EEPROM子程序 MOVLW 0C0H MOVWF PORTD MOVLW 0FEH MOVWF PORTA ;显示0 GOTO $ ; CALL DELAY10MS ;延时一定时间,保证写EEPROM能完成 BTFSC PORTB,1 GOTO MAIN CALL READ ;调用读EEPROM程序 CALL DISPLAY ;调用显示程序 GOTO $-1
;***********************写EEPROM程序**************************** ;入口参数:DATA_W ;出口参数:无 WRITE CALL I2C_IDLE ;判断是否空闲 BANKSEL SSPCON2 BSF SSPCON2,SEN ;建立起动信号 BANKSEL PIR1 BTFSS PIR1,SSPIF ;等待起动完成 GOTO $-1
MOVLW 0A0H ;发送控制字节 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;等待应答信号
BANKSEL SSPSTAT BTFSC SSPSTAT,BF ;检测寄存器满标志 GOTO $-1 MOVLW ADDRESS ;待写入数据的EEPROM地址 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;等待应答信号 CLRF STATUS MOVLW 6H MOVWF COUNT BANKSEL SSPSTAT BTFSC SSPSTAT,BF ;检测寄存器满标志 GOTO $-1 WRITE_1 INCF DATA_W,1 MOVFW DATA_W ;待写入的数据 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;等待应答信号 BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 DECFSZ COUNT,1 GOTO WRITE_1
BANKSEL SSPCON2 BSF SSPCON2,PEN ;建立停止信号 BANKSEL PIR1 BCF PIR1,SSPIF ;等待信号完成 RETURN ;程序返回 ;***********************读EEPROM程序**************************** ;入口参数:无 ;出口参数:DATA_R READ MOVLW 60H MOVWF FSR MOVLW 6 MOVWF COUNT CALL I2C_IDLE ;调用总线空闲检测程序 BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 BANKSEL SSPCON2 BSF SSPCON2,SEN ;建立起动信号 BANKSEL PIR1 BTFSS PIR1,SSPIF ;等待信号完成 GOTO $-1
MOVLW 0A0H ;发送控制信号 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;调用应答检测程序 MOVLW ADDRESS ;待读取数据的EEPROM地址 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;调用应答信号检测程序 CALL DELAY10MS ;调用延时程序
CALL I2C_IDLE ;调用总线空闲检测程序 BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 BANKSEL SSPCON2 BSF SSPCON2,RSEN ;建立重起信号 BANKSEL PIR1 BTFSS PIR1,SSPIF ;等待信号完成 GOTO $-1
MOVLW 0A1H ;发送控制字节 BANKSEL SSPBUF MOVWF SSPBUF CALL WRTACKTEST ;等待应答信号 BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 READ_1 BANKSEL SSPCON2 BSF SSPCON2,RCEN ;启动接收数据 BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 BTFSS PIR1,SSPIF ;等待数据接收完成 GOTO $-1 BANKSEL SSPBUF MOVFW SSPBUF ; MOVWF DATA_R ;保存数据到指定接收寄存器 CLRF STATUS MOVWF INDF BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 BANKSEL SSPCON2 BCF SSPCON2,ACKDT ;应答信号置1 BSF SSPCON2,ACKEN ;建立一个应答信号 BANKSEL PIR1 BTFSS PIR1,SSPIF ;等待信号完成 GOTO $-1 INCF FSR,1 DECFSZ COUNT,1 GOTO READ_1 BANKSEL SSPCON2 BSF SSPCON2,PEN ;建立一个停止信号 BANKSEL PIR1 BTFSS PIR1,SSPIF ;等待信号完成 GOTO $-1 BCF PIR1,SSPIF ;清除中断标志位 RETURN ;程序返回
;********************总线初始化程序*************************** INIT_I2C CLRF STATUS MOVLW 0FFH MOVWF PORTD BANKSEL ADCON1 MOVLW 07H MOVWF ADCON1 BANKSEL TRISC MOVLW 0FFH MOVWF TRISB CLRF TRISA CLRF TRISD BSF TRISC,SDA BSF TRISC,SCL ;设置SDA跟SCL为输入,将由IIC自动控制 BANKSEL SSPADD MOVLW 9 MOVWF SSPADD ;波特率设置为100kbd BCF SSPSTAT,6 ;选定输入电平遵循IIC规范 BSF SSPSTAT,7 ;关闭转换率控制 BANKSEL SSPCON MOVLW 38H MOVWF SSPCON ;设定控制寄存器 RETURN ;程序返回 ;*********************应答信号检测程序************************ WRTACKTEST BANKSEL PIR1 BCF PIR1,SSPIF ;清除中断标志位 BTFSS PIR1,SSPIF ;判断中断标志位是否为1 GOTO $-1 ;等待中断标志位为1 RETURN ;程序返回
;*********************总线空闲判断程序************************* I2C_IDLE BANKSEL SSPSTAT BTFSC SSPSTAT,R_W ;检测是否在发送过程中 GOTO $-1 ;等待发送完成 BANKSEL SSPCON2 MOVFW SSPCON2 ;读取SSPCON2的值 ANDLW 1FH ;去掉高3位 BTFSS STATUS,Z ;5个状态位是否全为0 GOTO $-3 ;否,总线忙,循环检测 RETURN ;程序返回
;**********************延时程序****************************** DELAY10MS MOVLW 0CH MOVWF DL1 DELAY2 MOVLW 0FFH MOVWF DL2 DELAY1 DECFSZ DL2,1 GOTO DELAY1 DECFSZ DL1,1 GOTO DELAY2 RETURN
DISPLAY MOVFW 60H CALL TABLE MOVWF PORTD BCF PORTA,0 CALL DELAY10MS BSF PORTA,0
MOVFW 61H CALL TABLE MOVWF PORTD BCF PORTA,1 CALL DELAY10MS BSF PORTA,1
MOVFW 62H CALL TABLE MOVWF PORTD BCF PORTA,2 CALL DELAY10MS BSF PORTA,2
MOVFW 63H CALL TABLE MOVWF PORTD BCF PORTA,3 CALL DELAY10MS BSF PORTA,3
MOVFW 64H CALL TABLE MOVWF PORTD BCF PORTA,4 CALL DELAY10MS BSF PORTA,4
MOVFW 65H CALL TABLE MOVWF PORTD BCF PORTA,5 CALL DELAY10MS BSF PORTA,5 RETURN
;************************************************************ END ;程序结束
|
|