Hola,
Personalmente utilicé el proyecto de Pacalaconcurso como base para hacer un Esclavo Modbus ASCII con un PIC16F876. Si querés ejemplos de tramas de mensajes lo mejor es utilizar el programa "Modbus Poll" disponible en la web de Pacalaconcurso. Si te fijás en la seccion de ayuda del programa figuran tramas que debe enviar el maestro y las que debe responder el esclavo, tanto en RTU como en ASCII.
Para comprender bien el protocolo lo mejor es usar una PC con dos puertos series. Bajar el programa "Modbus Poll" y el "Modbus Slave" de esta página:
http://www.modbustools.comLuego conectas, digamos el COM1 al COM2 con un cable null-modem. Inicias ambos programas, al maestro (Modbus Poll) lo configuras para que se conecte al COM1 y al esclavo (Modbus Slave) lo conectas al COM2, usando los mismos parámetros de comunicación (ej, 19200, N, 8, 1, RTU). Luego probás enviar distintas funciones. Ambos programas tienen una funcion para ver los bytes de la comunicación en hexa, por lo que se puede ver el pedido que transmite el maestro y la respuesta del esclavo. Una vez comprendido el protocolo y principalmente la respuesta que debe enviar el PIC según el pedido del maestro, se pasa a hacer el programa.
Dependiendo del micro, hay dos formas de hacerlo. Si tenés memoria lo mejor es ir guardando los bytes en un array a medida que llegan, luego vas comparando byte por byte. El primer byte es la direccion y la comparás con la tuya. Si es tu direccion seguis, sino, esperas el siguiente mensaje. El segundo byte es la función Modbus (ej, 0x03, 0x04, de acuerdo a lo que quieras hacer), si la funcion es soportada por el esclavo se guarda el byte y se pasa al siguiente, sino se descarta el mensaje y se espera el siguiente. Dependiendo de la funcion vienen los otros bytes. El ultimo debería ser el byte de CRC. Aquí se recalcula el CRC con los bytes anteriores y se lo compara con el recibido. Si es correcto se procesa el pedido Modbus, sino se descarta el mensaje y se espera el siguiente, si te animás podés emitir un mensaje de error.
La otra forma es procesar los bytes a medida que llegan, de esta forma se usa menos memoria, pero se complica el código porque se usa una máquina de estado para saber que se debe hacer de acuerdo al byte que va llegando.
Se cual sea la técnica te recomiendo que primero pruebes con una sola funcion modbus, por ejemplo Leer Bobina 0, para verificar el funcionamiento del reconocimiento y luego si funciona vayas agregando funciones.
Lo primero es hacer que se reciba y se reconozca bien el mensaje, por ejemplo encendiendo y apagando un led. Luego se arma la respuesta de acuerdo al pedido y se envia el paquete.
Espero te sirva