Author Topic: PIC: Using I2C to communicate with MCP7940N RTC  (Read 2530 times)

0 Members and 1 Guest are viewing this topic.

Offline PerArduaTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: gb
PIC: Using I2C to communicate with MCP7940N RTC
« on: February 01, 2024, 07:42:50 pm »
I am trying to implement I2C comms between a PIC18F45K20 (https://ww1.microchip.com/downloads/en/devicedoc/40001303h.pdf) as a master with a slave MCP7940N RTC (https://ww1.microchip.com/downloads/en/devicedoc/20005010f.pdf). However, after writing a test program to just read the value of a register in the MCP7940N, my I2C seems to be stuck in the "while(I2C -> IsBusy())" loop. I generated the code using the code configurator (running MPLAB X v6.15), which is available (along with my main.c) in the Project Files zip.

Here is my main.c file (slightly trimmed to remove fluff when compared to the version in the zip. I haven't edited the outputs from mcc):

Code: [Select]
#include "mcc_generated_files/system/system.h"
#include <string.h>

#define I2C_SLAVE 0b1101111

#define MINUTES 0x01

const i2c_host_interface_t *I2C = &I2C1_Host;

//Sends a string via UART
void EUSART1_sendString(const char *str)
{
    while(*str)
    {
        while (!(EUSART_IsTxReady()));
        EUSART_Write(*str++);
    }
}

//Sends an int via uart
void EUSART1_sendInt(int num)
{
    char buffer[10];
    int i, sign;
   
    //Handling negatives
    if (num < 0)
    {
        sign = -1;
        num = -num;
    } else {
        sign = 1;
    }
   
    //Convert int to string in reverse
    i = 0;
   
    do
    {
        buffer[i++] = num % 10 + '0';
        num /= 10;
    } while (num > 0);
   
    //Add sign if it's negative
    if (sign == -1) {
        buffer[i++] = '-';
    }
   
    //Send each char in reverse order
    for (int j = i - 1; j >= 0; j--)
    {
        while (!(EUSART_IsTxReady()));
        EUSART_Write(buffer[j]);
    }
   
}


int main(void)
{
    SYSTEM_Initialize();
   
    uint8_t dataRead[1];
    uint8_t dataWrite[1];
   
    dataWrite[0] = MINUTES;
   
    while (1)
    {
        if (I2C -> WriteRead(I2C_SLAVE, dataWrite, 1, dataRead, 1)){
            while(I2C -> IsBusy())
            {
                I2C -> Tasks();
            }
            if (I2C -> ErrorGet() != I2C_ERROR_NONE)
            {
                //Success
            }
            else
            {
                //Error
            }
        }
       
        //process and print dataRead
       
        EUSART1_sendString("The number is: ");
        EUSART1_sendInt(dataRead[0]);
        EUSART1_sendString("\r\n");
        __delay_ms(1000);
       
}
}

I have verified the hardware is properly soldered and have the PIC communicating via UART with success.

This test heavily from the microchip I2C mcc generated example here: https://onlinedocs.microchip.com/pr/GUID-4F9CFB6D-C135-42A9-8522-75972CEC6F0E-en-US-8/index.html?GUID-CF356ACC-625C-4021-A3B4-33C65C9070DB

Probing the SDA/SCL shows some toggling going on, but nothing resembling a correct I2C packet. The following were triggered from an initial power on of the circuit:



And zoomed in:



I'm not really sure what to try now. Am I incorrectly using the MCC generated outputs? Am I missing something important in the rtc datasheet?

The following is a snippet from my schematic:



 

Offline PerArduaTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: gb
Re: PIC: Using I2C to communicate with MCP7940N RTC
« Reply #1 on: February 02, 2024, 06:05:17 pm »
One of the things I'm not confident about in my approach so far is the addressing of the MCP7940.

Figure 4-3 (pg 10) of the datasheet where the RW bit of the address is set to a 1 or 0. I presume as I am only reading from the device, that the address should be 0b11011111? Is this correct?

Because I'm not seeing a proper SCL signal, is it possible the issue is in the config of the peripheral? I've tried reading through the mcc generated code, but I've not been able to identify anything that appears strange (a noob at programming, sorry).
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6266
  • Country: es
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: PerArdua


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf