Pic18F45K22 - RS485 & I2C At The Same Time

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
Ditch
Posts: 71
Joined: 23 Jan 2017 23:14

Pic18F45K22 - RS485 & I2C At The Same Time

#1 Post by Ditch » 28 Dec 2023 13:50

Hi All,

I'm playing around with a Pic18f45k22 with RS485 & I2C working at the same time.

My code is below and this is working fine and i have communication with the RS485 slave but when I uncomment the '//minutes = ReadFromDS3231(1);' at the bottom of my main loop, my RS485 comms stops and i get no response from the RTC.


My question is, is it possible to run the RS485 and the I2C at the same time or is there somethig i'm missing? Is it becuase i'm using UART2_Init and I2C2_Init - is there something stopping me for using these at the same time?

Any light you can cast on this would be appreciated.

Code: Select all



#pragma ReentrancyCheck OFF

// Define DS3231 I2C address
#define DS3231_I2C_ADDRESS 0xD0


sbit hb_led at RB3_bit;
sbit data_led at RB2_bit;
sbit rtc_sqw at RC2_bit;

unsigned int

            i,
            j,
            hb_cnt,
            data_led_cnt;

//RS485 Network

bit
            tx_now;


unsigned int

            rs485_tx_cnt;

char dat[10];                                                                   // buffer for receving/sending RS485 messages


unsigned char

            seconds,
            minutes,
            hours,
            day,
            date,
            month,
            year;



sbit  rs485_rxtx_pin  at RD5_bit;               // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISD5_bit;   // set transcieve pin direction


void InitTimer0(){
  T0CON	 = 0x88;
  TMR0H	 = 0xFE;
  TMR0L	 = 0x70;
  GIE_bit	 = 1;
  TMR0IE_bit	 = 1;
}

// Function to write data to DS3231
void WriteToDS3231(unsigned short address, unsigned short rtc_data) {
    I2C2_Start();         // Start condition
    I2C2_Wr(DS3231_I2C_ADDRESS); // Send DS3231 address with write bit
    I2C2_Wr(address);     // Send register address
    I2C2_Wr(rtc_data);        // Send data
    I2C2_Stop();          // Stop condition
}

// Function to read data from DS3231
unsigned short ReadFromDS3231(unsigned short address) {
    unsigned short read_data;

    I2C2_Start();         // Start condition
    I2C2_Wr(DS3231_I2C_ADDRESS); // Send DS3231 address with write bit
    I2C2_Wr(address);     // Send register address

    I2C2_Repeated_Start(); // Repeated start condition
    I2C2_Wr(DS3231_I2C_ADDRESS | 1); // Send DS3231 address with read bit
    read_data = I2C2_Rd(0); // Read data and send NACK
    I2C2_Stop();          // Stop condition

    return read_data;
}






void Interrupt(){


      if (TMR0IF_bit){
        TMR0IF_bit = 0;
        TMR0H	 = 0xFE;
        TMR0L	 = 0x70;

         hb_cnt++;
         rs485_tx_cnt++;


         //control of heartbeat led. toggle every 1/2 second
         if(hb_cnt >= 5000){ hb_led++; hb_cnt = 0; }
         if(data_led_cnt > 0){
           data_led_cnt--; data_led = 1;
         } else { data_led = 0; }


         if(rs485_tx_cnt >= 2500){

           rs485_tx_cnt = 0;
           tx_now = 1;
         }
      }

      RS485Master_Receive(dat);
}





void main() {

        // 8Hz Speed
        /*  //Internal RC Oscillator Frequency Select bits
        111 = HFINTOSC ? (16 MHz)
        110 = HFINTOSC/2 ? (8 MHz)
        101 = HFINTOSC/4 ? (4 MHz)
        100 = HFINTOSC/8 ? (2 MHz)
        011 = HFINTOSC/16 ? (1 MHz)(3)
        */

        OSCCON.IRCF2 = 1;
        OSCCON.IRCF1 = 1;
        OSCCON.IRCF0 = 1;
        OSCCON.SCS1 = 1; //Internal oscillator block
        OSCCON.SCS0 = 0;
        OSCTUNE.PLLEN = 0;

        CM1CON = 0; //Disable Comparator 1; CM1CON0: COMPARATOR 1 CONTROL REGISTER
        CM2CON = 0;

        TRISA  = 0x00;        // PORTA pins 00000000
        ANSELA = 0x00;        // PORTA all digital pins
        PORTA  = 0x00;        // clear PORTA

        TRISB  = 0x00;        // PORTB pins 00000000
        ANSELB = 0x00;        // PORTB all digital pins
        PORTB  = 0x00;        // clear PORTB

        TRISC  = 0x04;       // PORTC pins 00000100
        ANSELC = 0x00;       // PORTC all digital pins
        PORTC  = 0x00;       // clear PORTC

        TRISD  = 0x00;       // PORTD pin 00000000
        ANSELD = 0x00;       // PORTD all digital pins
        PORTD  = 0x00;       // clear PORTD

        TRISE  = 0x00;       // PORTE pin 00000000
        ANSELE = 0x00;       // PORTE all digital pins
        PORTE  = 0x00;       // clear PORTE


        UART2_Init(9600);                  // initialize UART2 module
        Delay_ms(100);

        RS485Master_Init();                  // initialize MCU as Master

        dat[0] = 0xAA;
        dat[1] = 0xF0;
        dat[2] = 0x0F;
        dat[4] = 0;                          // ensure that message received flag is 0
        dat[5] = 0;                          // ensure that error flag is 0
        dat[6] = 0;

        InitTimer0();
        delay_ms(100);

        I2C2_Init(100000);        // initialize I2C communication


        while (1) {

        if(tx_now){

        tx_now = 0;
        data_led_cnt = 100;

        RS485Master_Send(dat, 3, 1);
        delay_ms(10);
        }
        else {
         //minutes = ReadFromDS3231(1);
         delay_ms(10);
        }

}
}



Ian

User avatar
IvanJeremic
mikroElektronika team
Posts: 316
Joined: 05 Sep 2022 14:32

Re: Pic18F45K22 - RS485 & I2C At The Same Time

#2 Post by IvanJeremic » 29 Dec 2023 09:44

Hi,

There are plenty of click board examples which use UART and I2C at the same time, so that shouldn't be an issue here.

For example you can take a look at the Uart I2C/SPI click.
https://libstock.mikroe.com/projects/do ... c_pic.mpkg

Regards,

Ivan.

Ditch
Posts: 71
Joined: 23 Jan 2017 23:14

Re: Pic18F45K22 - RS485 & I2C At The Same Time

#3 Post by Ditch » 29 Dec 2023 21:35

Ok. Thanks Ivan.

Ian

Post Reply

Return to “mikroC PRO for PIC General”