I2C Display/keypad problem

Discussion in 'Embedded Systems and Microcontrollers' started by geoffers, Dec 8, 2013.

  1. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    Hi all,

    Stuck yet again I'm afraid! I've a BV4618 keypad display module which is giving me grief now, its probably simple but I've been going at it for hours now :mad:. A little bit of background, I've got a pic18f2523 on a board I had made up, until now it just had a eeprom on the I2C bus and was happy. The bv4618 module goes on the I2C bus and allows you to interface to a display and 4x4 keypad.

    The display is working just fine, I can write to it clear the screen etc no problems. My problem starts when I want to read data from the keypad buffer. The module has a output that is driven low when there is data in the buffer, this works fine, with the pickit2 debugger, I can see I've sent a command to read data from the bv4618, data has come back to the pic and is in the w reg (number of bytes in buffer).

    This is the receive code I'm using

    Code ( (Unknown Language)):
    1. RX_BYTE
    2.     bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    3.     bsf     SSPCON2,RCEN        ; Initiate reception of byte
    4. rx_wait
    5.     btfss   PIR1,SSPIF          ; Check if operation completed
    6.     bra     rx_wait             ; If not, keep checking
    7.     movf    SSPBUF,W            ; Copy byte to WREG
    8.     movwf   datai               ; Copy WREG to datai
    9.     bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    10.     bsf     SSPCON2,ACKEN       ; Generate ACK/NO ACK bit  
    11. rx_wait2
    12.     btfss   PIR1,SSPIF          ; Check if operation completed
    13.     bra     rx_wait2            ; If not, keep checking
    14.  
    15.     return
    The problem is after this I can't create a stop condition, if I add another generate ACK command I can get a stop condition but then can't create a start condition, it appears the slave (bv4618) is holding the sda line low.

    I searched about a bit read another post on this forum and have tried disabling the i2c module after the stop bit and pulsing the scl line a few time before I try and get the start condition, still hangs!

    Any input is welcome before I chuck the whole lot in the bin and get a pic with more i/o!:eek::eek:

    Cheers Geoff
     
  2. JohnInTX

    Moderator

    Jun 26, 2012
    2,345
    1,028
    It could be several things but one thing I see is that after reading the (last) byte, you should send a NAK instead of ACK. The slave transmitter (keypad) is then supposed to release the bus so that the master can generate a stoP. Sending ACK tells the slave transmitter that you will be reading another byte and it will keep control of SDA.
     
    geoffers likes this.
  3. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    Thank you ever so much, this has been bugging me for some time! Changed my code to this....

    Code ( (Unknown Language)):
    1. RX_BYTE
    2.     bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    3.     bsf     SSPCON2,RCEN        ; Initiate reception of byte
    4. rx_wait
    5.     btfss   PIR1,SSPIF          ; Check if operation completed
    6.     bra     rx_wait             ; If not, keep checking
    7.     movf    SSPBUF,W            ; Copy byte to WREG
    8.     movwf   datai               ; Copy WREG to datai
    9.     bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    10.     BSF    SSPCON2,ACKDT        ;GENERATE NACK
    11.     bsf     SSPCON2,ACKEN       ; Generate ACK/NO ACK bit  
    12. rx_wait2
    13.     btfss   PIR1,SSPIF          ; Check if operation completed
    14.     bra     rx_wait2            ; If not, keep checking
    15.  
    16.     return
    And its all happy! Cheers Geoff:):)
     
Loading...