No compilador MikroC tem um exemplo de comunicação mestre e escrava via RS485 mas não sei se é modbus, ou seja, não sei identificar se é modbus ou não. Segue abaixo o exemplo:
PIC Master Code:
char dat[10]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_dire ction at TRISC2_bit; // set transcieve pin direction
// Interrupt routine
void interrupt() {
RS485Master_Receive(dat);
}
void main(){
long cnt = 0;
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
PORTB = 0;
PORTD = 0;
TRISB = 0;
TRISD = 0;
UART1_Init(9600); // initialize UART1 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;
RS485Master_Send(dat,1,160);
PIE1.RCIE = 1; // enable interrupt on UART1 receive
PIE2.TXIE = 0; // disable interrupt on UART1 transmit
INTCON.PEIE = 1; // enable peripheral interrupts
INTCON.GIE = 1; // enable all interrupts
while (1){
// upon completed valid message receiving
// data[4] is set to 255
cnt++;
if (dat[5]) { // if an error detected, signal it
PORTD = 0xAA; // by setting portd to 0xAA
}
if (dat[4]) { // if message received successfully
cnt = 0;
dat[4] = 0; // clear message received flag
j = dat[3];
for (i = 1; i <= dat[3]; i++) { // show data on PORTB
PORTB = dat[i-1];
} // increment received dat[0]
dat[0] = dat[0]+1; // send back to master
Delay_ms(1);
RS485Master_Send(dat,1,160);
}
if (cnt > 100000) {
PORTD ++;
cnt = 0;
RS485Master_Send(dat,1,160);
if (PORTD > 10) // if sending failed 10 times
RS485Master_Send(dat,1,50); // send message on broadcast address
}
}
// function to be properly linked.
}
PIC Slave Code:
char dat[9]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_dire ction at TRISC2_bit; // set transcieve pin direction
// Interrupt routine
void interrupt() {
RS485Slave_Receive(dat);
}
void main() {
long cnt = 0;
//ANSEL = 0; // Configure AN pins as digital I/O
//ANSELH = 0;
PORTB = 0;
PORTD = 0;
TRISB = 0;
TRISD = 0;
UART1_Init(9600); // initialize UART1 module
Delay_ms(100);
RS485Slave_Init(160); // Intialize MCU as slave, address 160
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that message received flag is 0
dat[6] = 0; // ensure that error flag is 0
PIE1.RCIE = 1; // enable interrupt on UART1 receive
PIE2.TXIE = 0; // disable interrupt on UART1 transmit
INTCON.PEIE = 1; // enable peripheral interrupts
INTCON.GIE = 1; // enable all interrupts
while (1) {
if (dat[5]) { // if an error detected, signal it by
PORTD = 0xAA; // setting portd to 0xAA
dat[5] = 0;
}
if (dat[4]) { // upon completed valid message receive
cnt++;
dat[4] = 0; // data[4] is set to 0xFF
j = dat[3];
for (i = 1; i <= dat[3];i++){
PORTB = dat[i-1];
}
if (cnt>=100){ // besteira, conta de 1 até 7 a cada 100 ciclos
dat[0] = dat[0]+1; // increment received dat[0]
cnt=0;
if(dat[0] > 7) {
dat[0] = 0;
}
}
Delay_ms(1);
RS485Slave_Send(dat,1); // and send it back to master
}
}
}
Nesses códigos comunica PIC com PIC, não sei se dá pra aproveitar alguma coisa porque não sei se está usando protocolo Modbus RTU.