transfomer Posted April 21, 2008 Report Share Posted April 21, 2008 ;**************************************************** ;* 877I2CA.asm * ;* Very simple I2C sample program without Display * ;**************************************************** ;******************************************************************************* *********** ; This source code provides a demonstration of the MSSP peripheral ; on the PIC16F877 MCU. ; The additional external subroutine are used for LCD Module ; PIC16F877 执行频率 : 4 Mhz ; ; The subroutines for I2C ; :I2C_BYTE_READ ; Read a Byte from Address I2C_Addr and put into I2C_Data ; :I2C_BYTE_WRITE ; Write to I2C_Addr with data @ I2C_Data ; :I2C_ACK_CHECK ; Wait until I2C device can accept further command ; :InitI2C ; Initial I2C Module ; :StartI2C ; Set START Condition !! ; :StopI2C ; Set STOP Condition ; :RstartI2C ; Set Restart Condition ; :RecI2C ; Enable I2C Receive ; :ACKI2C ; Initial ACK response ; :NACKI2C ; Initial NACK response ; :WaitI2C ; Wait until SSPIF Set ;******************************************************************************* ************** list p=16f877 #include <p16f877.inc> CBLOCK 0x20 I2C_Data I2C_Addr ENDC w_temp EQU 0x72 status_temp EQU 0x73 pclath_temp EQU 0x74 ;******************************************** ; Locates startup code @ the reset vector ;******************************************** Reset_Addr org 0x00 nop goto Prog_Main nop nop ;*************************************************************************** ;**** The Start Address of ISR is 0x004 ;**** "PUSH" & "POP" 的使用范例 : 适用于像 PIC16F877 有SHARE BANK 的 PIC ;*************************************************************************** PUSH movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,W movwf pclath_temp POP movf pclath_temp,W movwf PCLATH movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;---------------------------------------------------------------------- Prog_Main BANKSEL TRISB ; Select Bank 1 movlw b'11000000' ; setup PORTB movwf TRISB BSF OPTION_REG,NOT_RBPU ; Disable PORTB pull-ups BCF STATUS, RP0 ; Select Bank 0 call InitI2C Main: BANKSEL I2C_Addr movlw 0x18 movwf I2C_Addr ; BANKSEL I2C_Data ; Bank Switching, in case its bank is differ than I2C_Addr !! movlw 0x99 movwf I2C_Data ; call I2C_BYTE_WRITE ; Write to I2C Device when Address & Data are set OK call I2C_ACK_CHECK ; Check the ACK response, Wait until the Device Acknowledge ; Issue !! The subroutine will not return until the device send ACK !! ; ; BANKSEL I2C_Addr movlw 0x18 movwf I2C_Addr ; call I2C_BYTE_READ nop ; nop ; goto $ ;**************************************************************************** I2C_BYTE_READ: ; Read a Byte @ I2C_Addr to Buffer I2C_Data ;**************************************************************************** call StartI2C ; Set SSPCON2.SEN call WaitI2C ; Wait PIR1,SSPIF BANKSEL SSPBUF movlw B'10100000' ; Write Command movwf SSPBUF call WaitI2C BANKSEL I2C_Addr ; The "BANKSEL" may not necessary if I2C_Addr is @ the same bank with SSPBUF movf I2C_Addr,W ; The Address you wish to "READ" from BANKSEL SSPBUF movwf SSPBUF call WaitI2C call RstartI2C ; Restart Condition !! call WaitI2C ; Wait Until Restart OK !! BANKSEL SSPBUF movlw B'10100001' ; Write Read Command movwf SSPBUF call WaitI2C call RecI2C ; Enable I2C Receive call WaitI2C ; Wait Until Buffer Received BANKSEL SSPBUF movf SSPBUF,W ; Save to I2C_Data First !! BANKSEL I2C_Data movwf I2C_Data call NACKI2C ; Initial NACK Response !! call WaitI2C ; Wait until NACK sent out call StopI2C ; Initial STOP Condition call WaitI2C ; Wait Until STOP Condition Terminated return ;**************************************************************************** I2C_ACK_CHECK: ; Read a Byte @ I2C_Addr to Buffer I2C_Data ;**************************************************************************** call StartI2C ; Set SSPCON2.SEN call WaitI2C ; Wait PIR1,SSPIF BANKSEL SSPBUF movlw B'10100001' ; Read Command movwf SSPBUF call WaitI2C BANKSEL SSPCON2 btfss SSPCON2,ACKSTAT ; Check ACKSTAT bit , 0 = ACK , 1 = NACK goto ACK_Return call StopI2C call WaitI2C goto I2C_ACK_CHECK ACK_Return: call StopI2C ; Initial STOP Condition call WaitI2C ; Wait Until STOP Condition Terminated return ;**************************************************************************** I2C_BYTE_WRITE: ; Write a Byte to I2C_Addr with I2C_Data ;**************************************************************************** call StartI2C ; Set SSPCON2.SEN call WaitI2C ; Wait PIR1,SSPIF BANKSEL SSPBUF movlw B'10100000' ; Write Command movwf SSPBUF call WaitI2C BANKSEL I2C_Addr ; The "BANKSEL" may not necessary if I2C_Addr is @ the same bank with SSPBUF movf I2C_Addr,W ; The Address you wish to "READ" from BANKSEL SSPBUF movwf SSPBUF call WaitI2C BANKSEL I2C_Data movf I2C_Data,W BANKSEL SSPBUF movwf SSPBUF call WaitI2C call StopI2C ; Initial STOP Condition call WaitI2C ; Wait Until STOP Condition Terminated return ;********************************************************************** ; The following subroutines perform commonly used I2C functions. ;********************************************************************** InitI2C: ; The subroutine of I2C Initialization BANKSEL TRISC movlw B'00011000' ; Initial PortC,bit 3 & 4 as Input movwf TRISC ; RC3 = SCL , RC4 = SDA BANKSEL PORTC movlw 0xff movwf PORTC movlw 0x09 ; This gives 100KHz I2C clock @ 4MHz banksel SSPADD movwf SSPADD movlw b'10000000' ; Disable slew rate control. banksel SSPSTAT movwf SSPSTAT movlw b'00000000' ; movwf SSPCON2 ; Setup MSSP for continuous reception. movlw b'00101000' ; Enable MSSP and setup for I2C master banksel SSPCON ; mode. movwf SSPCON return StartI2C ; Initiate the I2C START condition. banksel SSPCON2 bsf SSPCON2,SEN return StopI2C ; Initiate the I2C STOP condition. banksel SSPCON2 bsf SSPCON2,PEN return RstartI2C ; Initiate the I2C restart condition. banksel SSPCON2 bsf SSPCON2,RSEN return NACKI2C banksel SSPCON2 bsf SSPCON2,ACKDT ; Set the ACK bit bsf SSPCON2,ACKEN ; Initiate the NACK sequence. return ACKI2C banksel SSPCON2 bcf SSPCON2,ACKDT ; Clear the ACK bit bsf SSPCON2,ACKEN ; Initiate the NACK sequence. return RecI2C banksel SSPCON2 ; bsf SSPCON2,RCEN ; Set the receive enable bit. return WaitI2C ; Poll for SSPIF banksel PIR1 FLoop btfss PIR1,SSPIF goto FLoop bcf PIR1,SSPIF return ;---------------------------------------------------------------------- end ; *********** End Of Program !!!!! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now