LP AII – ICR TD RLI n°3 UE4
Programmation d'un Maître Modbus RTU sur PC en langage C
1. Présentation.
L'objectif de ce TD est d'effectuer le travail préparatoire à la programmation d'un un maître Modbus RTU sur le port série d'un PC.
Ce travail sera réutilisé au cours du TP correspondant dans lequel nous établirons une communication Modbus entre un PC (maître) et un automate Schneider TSX3721 (esclave).
Les fonctions Modbus suivantes devront être gérées par le maître :
– Fonction 01 : Lecture n bits de sortie
– Fonction 02 : Lecture n bits d'entree
– Fonction 03 : Lecture n mots de sortie
– Fonction 04 : Lecture n mots d'entree
– Fonction 05 : Ecriture 1 bit de sortie"
– Fonction 06 : Ecriture 1 mot de sortie
– Fonction 0F : Ecriture n bits de sortie
– Fonction 10 : Ecriture n mots de sortie
La programmation de ce maître peut être découpé en 2 grandes parties :
1 / La construction de la trame de requête et son émission sur le port série 2 / La réception de la trame de réponse et son traitement.
Nous allons au travers ce TD présenter les algorithmes correspondants à ces 2 parties. Nous coderons ensuite les principales fonctions appelées pour réaliser ces opération.
Ces fonctions seront appelées par le programme principal que vous aurez à réaliser en TP.
Dpt GEII 1/4
PC :
maître Modbus sur port série COM1 + Convertisseur RS232 -> RS485
Requêtes Réponses
Automate :
esclave Modbus RS485,
Adr = 0x01
LP AII – ICR TD RLI n°3 UE4
2. Algorithme de Calcul du CRC.
Le calcul du CRC est nécessaire effectué à la fois à la construction de la trame de requête pour remplir le champ correspondant, et à la réception de la trame de réponse afin de vérifier sa validité.
1. Coder en langage C le fonction de calcul du CRC 16 des trames Modbus RTU à l'aide du logigramme fourni en cours. Le prototype de cette fonction est :
unsigned short int calc_CRC(unsigned char taille, unsigned char *msg);
avec :
unsigned short CRC : variable contenant la valeur de CRC (ainsi que les calculs intermédiaires au cours du programme). Elle est retournée par la fonction calc_CRC.
char msg[taille] ; tableau d'octets contenant la trame Modbus RTU initiale dont on veut calculer le CRC
char taille ; Longueur en octets de la trame Modbus complète
2. Coder la fonction Construire_Trame_CRC( ) qui complète les 2 derniers octets de la trame Modbus RTU avec le CRC calculé par Calc_CRC( ).
void const_trame_CRC(unsigned char *msg, unsigned short CRC, unsigned char taille)
3. Construction et émission de la trame de requête.
3. Coder une fonction qui calcule la valeur du champ « byte count » des fonctions 15 et 16, dont le prototype est le suivant :
unsigned short calc_nb_oct (unsigned char code_fct, unsigned char nb_obj);
avec :
code_fct : code de la fonction Modbus.
nb_obj ; : nombre d'objets (mots ou bits) à lire/écrire nb_oct ; : valeur retournée par la fonction calc_nb_oct( )
4. Coder une fonction qui calcule la taille en octets de la requête à émettre, dans le but d'allouer l'espace mémoire nécessaire.
unsigned char calc_taille_req (unsigned char code_fct, unsigned char nb_oct);
avec :
code_fct : code de la fonction Modbus.
Dpt GEII 2/4
LP AII – ICR TD RLI n°3 UE4 nb_oct ; : nombre d'octets supplémentaire pour les fonctions 15 et 16, calculé par la
fonction calc_nb_oct( ).
taille_req ; : valeur retournée par la fonction calc_taille_req( )
5. Coder une fonction qui calcule la valeur du champ « byte count » des fonctions 15 et 16, dont le prototype est le suivant :
unsigned short calc_nb_oct (unsigned char code_fct, unsigned char nb_obj);
avec :
code_fct : code de la fonction Modbus.
nb_obj ; : nombre d'objets (mots ou bits) à lire/écrire nb_oct ; : valeur retournée par la fonction calc_nb_oct( )
La fonction const_trame( ) a pour rôle le remplissage d'un tableau d'octets qui constituera la trame Modbus émise, octet par octet sur le port série, après ajout du CRC par les fonctions calc_CRC( ) et const_trame_CRC( ).
Le remplissage de ce tableau est fait à partir
6. Coder cette fonction ,dont le prototype est le suivant :
void const_trame(unsigned char *msg, unsigned char taille, unsigned char slaveID, unsigned char function, unsigned short adresse, unsigned short nbr_obj, unsigned short nbr_oct)
avec :
*msg : pointeur sur le premier octet du tableau de la trame modbus taille : taille (en octets) du tableau contenant la trame (msg[taille]) slave_ID : adresse de l'esclave destinataire de la requête
fonction : code de la fonction Modbus adresse : adresse du 1° objet à lire/écrire nbr_obj : nombre d'objets à écrire
nbr_oct : nombre d'octets correspondant au nombre d'objets à écrire (fonctions15 et 16)
L'algorithme de la partie émission est donnée ci-dessous. La fonction Aff_trame( ) sert à afficher une trame à l'écran, que ce soit à l'émission ou à la réception.
La gestion du port série sera donnée en TP.
La partie réception sera également traitée en TP
Dpt GEII 3/4
LP AII – ICR TD RLI n°3 UE4
Algorithme du programme principal / Partie Requête :
Dpt GEII 4/4