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