PIC16F877 I2C programme


Closed Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Apr 2008
    Posts
    3

    Default PIC16F877 I2C programme

    ;************************************************* ***
    ;* 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 frequency : 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 0x00
    ;************************************************* ************

    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 !!!!!

  2. #2
    Join Date
    Mar 2006
    Location
    INDIA
    Posts
    89


    Did you find this post helpful? Yes | No

    Question

    So what's the problem in this code ?

    .

  3. #3
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Talking

    May be the problem is assembler !!!

    or

    Code:
    #include
    could be a problem too ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  4. #4
    Join Date
    Mar 2006
    Location
    INDIA
    Posts
    89


    Did you find this post helpful? Yes | No

    Talking

    Oh, forget to include

    Code:
    list p=16f877a
    include "p16f877a.inc"
    This code example is Written by: Richard Yang , Sr. Corporate Application Engineer, Microchip Technology Inc.

    Read this app. note

    http://www.pic16.com/tigao/041013/I2C_EE.asm


    .

Similar Threads

  1. I2C Master/Slave 16F88/16F767 working code
    By DanPBP in forum Code Examples
    Replies: 2
    Last Post: - 23rd October 2012, 22:31
  2. HARDWARE I2C SAMPLE CODE question
    By Michael Wakileh in forum Code Examples
    Replies: 2
    Last Post: - 16th June 2009, 21:07
  3. I2C Master Slave issues.
    By cpayne in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 29th March 2008, 19:33
  4. I2C slave
    By Charles Linquis in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 16th March 2008, 03:46
  5. Please help with i2cslave i2c slave
    By cycle_girl in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 1st December 2005, 13:55

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts