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