PIC16F877A I2C communication problem

  • Thread starter Thread starter thegreengineer
  • Start date Start date
  • Tags Tags
    Communication
Click For Summary
The discussion revolves around issues with I2C communication between a PIC16F877A microcontroller and a DS3231 RTC module for a programmable clock project. The user has developed subroutines for I2C operations but encounters a problem where the RTC does not update from its initial time of 00:00:00 after uploading the code. Suggestions include ensuring the RST line is properly connected and implementing a reset mechanism for the devices to ensure they function correctly. Additionally, it is recommended to add more comments in the code for clarity. The user is encouraged to verify the addressing of the I2C commands as this could be a potential source of the issue.
thegreengineer
Messages
54
Reaction score
3
Good evening people, I was planing to make a programmable clock using a PIC16F877A microcontroller, a LM016 LCD display and a DS3232 RTC module. The DS3231 RTC module communicates with the PIC via I2C bus. At first I built some subroutines for controlling I2C communication: the commands have names in Spanish yet I explain what they do:

Code:
    i2c_inicializa    ;This subroutine is for initiating the I2C module
    bcf    STATUS,RP1
    bsf    STATUS,RP0
    bsf    TRISC,TRISC3
    bsf    TRISC,TRISC4
    movlw    B'10000000'
    movwf    SSPSTAT
    bcf    STATUS,RP0
    movlw    B'00101000'
    movwf    SSPCON
    bsf    STATUS,RP0
    movlw    B'00000000'
    movwf    SSPCON2
    movlw    D'9'
    movwf    SSPADD
    return

    i2c_espera    ;This is just an idle subroutine for producing a delay time between commands
    call    retardo_2ms
    return

    i2c_inicio    ;Start condition
    bcf    STATUS,RP1
    bsf    STATUS,RP0
    call    i2c_espera
    bsf    SSPCON2,SEN
    return
   
    i2c_reinicio    ;Restarting condition
    bcf    STATUS,RP1
    bsf    STATUS,RP0   
    call    i2c_espera
    bsf    SSPCON2,RSEN
    return

    i2c_parada    ;Stop condition
    bcf    STATUS,RP1
    bsf    STATUS,RP0
    call    i2c_espera
    bsf    SSPCON2,PEN
    return

    i2c_envia_dato    ;Write data into slave device
    bcf    STATUS,RP1
    bcf    STATUS,RP0
    call    i2c_espera
    movwf    SSPBUF
    return

    i2c_recibe_dato    ;Reading data from slave
    bcf    STATUS,RP1
    bsf    STATUS,RP0
    call    i2c_espera
    bsf    SSPCON2,RCEN
    call    i2c_espera
    bsf    SSPCON2,ACKDT
    bsf    SSPCON2,ACKEN
    bcf    STATUS,RP1
    bcf    STATUS,RP0
    movf    SSPBUF,0
    return

I built the circuit in Proteus to test if the I2C communication works fine. For this purpose I just built the DS3231 part.
22789211_1982901315327736_5943802453130935664_n.jpg

If I upload a hex file with no i2c instructions the RTC starts counting from TIME at 00:00:00 and DATE at 00/00/00. Now let's suppose when I start the simulation I want the TIME to display at 00:10:00. For this what do I have to do? Well it's obvious that I need to write into the DS3232. So the first thing I do is initialializing the I2C comunication by calling the i2c_inicializa function at the very first. After that I send the start condition with the i2c_inicio command. Then I have to send the adress of the slave plus the R/W bit for declaring if I want to read or write. Since DS3232 has an address of B'1101000' and I want to write in the DS3232 I send the byte B'11010000' with the i2c_envia_dato command (by previously loading the B'11010000' value into the W register). The I send the address, so I check the DS3232 datasheet and I find that the MINUTES register is in address 01H of the adress map, so I send the value B'00000001' with the i2c_envia_dato command. Then I'm at the MINUTES register so if I want a "10" at the minutes register then I send (in BCD) B'00010000' with the i2c_envia_dato command. Finally to end the communication I call the i2c_parada for the stop condition. The source code is this:
Code:
;RELOJ PROGRAMABLE CON ALARMA ELABORADO CON PIC16F877A
;AUTOR: MARCO AURELIO VILLARREAL DEL VALLE
;MATRICULA: 1639019
;CLASE DE MICROCONTROLADORES
    __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
    LIST    P=16F877A
    #INCLUDE    <P16F877A.INC>
    ;Iniciando en el banco 0
    ORG 0x00
    CBLOCK  0x26
    CONT_PAL
    ENDC
    bcf    STATUS,RP1
    bsf    STATUS,RP0
    clrf    TRISB
    clrf    TRISC
    clrf    TRISD
    bcf    STATUS,RP0
    call    i2c_inicializa
    call    i2c_inicio
    movlw   B'11010000'
    call    i2c_envia_dato
    movlw   B'00000001'
    call    i2c_envia_dato
    movlw   B'00010000'
    call    i2c_envia_dato
    call    i2c_parada
    principal
 
    goto principal
    #INCLUDE    <retardos.INC>
    #INCLUDE    <i2c.INC>
    #INCLUDE    <lcd.INC>
    END
After that I compile (build) and there are no errors, however when loading the code in PROTEUS the simulation still starts at time 00:00:00. And I don't know where my mistake is, I already checked the datasheet of the RTC module, still don't know. I would appreciate your answers. Thanks.
 

Attachments

  • 22789211_1982901315327736_5943802453130935664_n.jpg
    22789211_1982901315327736_5943802453130935664_n.jpg
    57.8 KB · Views: 1,240
Engineering news on Phys.org
MarcusAu314 said:
I built the circuit in Proteus to test if the I2C communication works fine. For this purpose I just built the DS3231 part.
I'll try to check the addressing later today (that is the trickiest part of I2C for me), but first, in your schematic, what is pin 18/20 on U2 supposed to represent? I have not seen that notation before...
 
Two things.

1. You need to tie your RST line to something, and you should reset all devices before using them. Typically if a device isn't reset you are not sure of its states and it will not function properly. You can either reset the device through the pic, or use an RC network to reset the device shortly after powerup. (use a lowpass filter with a time constant greater than the min required reset time.

2. Try to include more comments inside of each of your functions in the code. It will help you, trust me!
 
Thread 'I thought it was only Amazon that sold unsafe junk'
I grabbed an under cabinet LED light today at a big box store. Nothing special. 18 inches in length and made to plug several lights together. Here is a pic of the power cord: The drawing on the box led me to believe that it would accept a standard IEC cord which surprised me. But it's a variation of it. I didn't try it, but I would assume you could plug a standard IEC cord into this and have a double male cord AKA suicide cord. And to boot, it's likely going to reverse the hot and...

Similar threads

  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 10 ·
Replies
10
Views
4K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
2
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 3 ·
Replies
3
Views
3K