Code pour le projet de robot autonome : Partie 2

Afin de vous simplifier le travail dans le cadre du projet robot, les éléments de code de taille importante à insérer au fur et à mesure du projet sont regroupés sur cette page. A noter qu’en cas d’incohérence avec le sujet, c’est celui-ci qui fait est juste a priori. Si c’est le cas, merci de me le signaler.

Pour formater proprement vos fichiers dans MPLABX, vous pouvez utiliser le raccourci de formatage automatique ALT+MAJ+F, après avoir au préalable sélectionné le texte à formater.

Liaison série en embarqué

 

#include <xc.h>
#include “UART.h”
#include “ChipConfig.h”

#define BAUDRATE 115200
#define BRGVAL ((FCY/BAUDRATE)/4)-1

void InitUART(void) {
U1MODEbits.STSEL = 0; // 1-stop bit
U1MODEbits.PDSEL = 0; // No Parity, 8-data bits
U1MODEbits.ABAUD = 0; // Auto-Baud Disabled
U1MODEbits.BRGH = 1; // Low Speed mode
U1BRG = BRGVAL; // BAUD Rate Setting

U1STAbits.UTXISEL0 = 0; // Interrupt after one Tx character is transmitted
U1STAbits.UTXISEL1 = 0;
IFS0bits.U1TXIF = 0; // clear TX interrupt flag
IEC0bits.U1TXIE = 0; // Disable UART Tx interrupt

U1STAbits.URXISEL = 0; // Interrupt after one RX character is received;
IFS0bits.U1RXIF = 0; // clear RX interrupt flag
IEC0bits.U1RXIE = 0; // Disable UART Rx interrupt

U1MODEbits.UARTEN = 1; // Enable UART
U1STAbits.UTXEN = 1; // Enable UART Tx
}

 

Interruption en mode loopback

//Interruption en mode loopback
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
IFS0bits.U1RXIF = 0; // clear RX interrupt flag
/* check for receive errors */
if (U1STAbits.FERR == 1) {
U1STAbits.FERR = 0;
}
/* must clear the overrun error to keep uart receiving */
if (U1STAbits.OERR == 1) {
U1STAbits.OERR = 0;
}
/* get the data */
while (U1STAbits.URXDA == 1) {
U1TXREG = U1RXREG;
}
}

Buffer circulaire en émission

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include “CB_TX1.h”
#define CBTX1_BUFFER_SIZE 128

int cbTx1Head;
int cbTx1Tail;
unsigned char cbTx1Buffer[CBTX1_BUFFER_SIZE];
unsigned char isTransmitting = 0;

void SendMessage(unsigned char* message, int length)
{
unsigned char i=0;

if(CB_TX1_RemainingSize()>length)
{
//On peut écrire le message
for(i=0;i<length;i++)
CB_TX1_Add(message[i]);
if(!CB_TX1_IsTranmitting())
SendOne();
}
}

void CB_TX1_Add(unsigned char value)
{

}

unsigned char CB_TX1_Get(void)
{

} 

void __attribute__((interrupt, no_auto_psv)) _U1TXInterrupt(void) {
IFS0bits.U1TXIF = 0; // clear TX interrupt flag
if (cbTx1Tail!=cbTx1Head)
{
SendOne();
}
else
isTransmitting = 0;
}

void SendOne()
{
isTransmitting = 1;
unsigned char value=CB_TX1_Get();
U1TXREG = value; // Transmit one character
}

unsigned char CB_TX1_IsTranmitting(void)
{

}

int CB_TX1_RemainingSize(void)
{
int rSize;
..
return rSize;
}

 

Buffer circulaire en réception

 

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include “CB_RX1.h”

#define CBRX1_BUFFER_SIZE 128

 

int cbRx1Head;
int cbRx1Tail;
unsigned char cbRx1Buffer[CBRX1_BUFFER_SIZE];

void CB_RX1_Add(unsigned char value)
{
if(CB_RX1_GetRemainingSize()>0)
{

}
}

unsigned char CB_RX1_Get(void)
{
unsigned char value=cbRx1Buffer[cbRx1Tail];

return value;
}

unsigned char CB_RX1_IsDataAvailable(void)
{
if(cbRx1Head!=cbRx1Tail)
return 1;
else
return 0;
}

void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
IFS0bits.U1RXIF = 0; // clear RX interrupt flag
/* check for receive errors */
if (U1STAbits.FERR == 1) {
U1STAbits.FERR = 0;
}
/* must clear the overrun error to keep uart receiving */
if (U1STAbits.OERR == 1) {
U1STAbits.OERR = 0;
}
/* get the data */
while(U1STAbits.URXDA == 1) {
CB_RX1_Add(U1RXREG);
}
}

int CB_RX1_GetRemainingSize(void)
{
int rSizeRecep;

return rSizeRecep;
}

int CB_RX1_GetDataSize(void)
{
int rSizeRecep;

return rSizeRecep;
}

 

Décodage des messages en C#

public enum StateReception
{
Waiting,
FunctionMSB,
FunctionLSB,
PayloadLengthMSB,
PayloadLengthLSB,
Payload,
CheckSum
}

StateReception rcvState = StateReception.Waiting;
int msgDecodedFunction = 0;
int msgDecodedPayloadLength = 0;
byte[] msgDecodedPayload;
int msgDecodedPayloadIndex = 0;

private void DecodeMessage(byte c)
{
switch(rcvState)
{
case StateReception.Waiting:

break;
case StateReception.FunctionMSB:

break;
case StateReception.FunctionLSB:

break;
case StateReception.PayloadLengthMSB:

break;
case StateReception.PayloadLengthLSB:

break;
case StateReception.Payload:

break;
case StateReception.CheckSum:

if (calculatedChecksum == receivedChecksum)
{
//Success, on a un message valide
}

break;
default:
rcvState = StateReception.Waiting;
break;
}
}

 

Décodage des messages en embarqué

#include <xc.h>
#include “UART_Protocol.h”

unsigned char UartCalculateChecksum(int msgFunction,
int msgPayloadLength, unsigned char* msgPayload)
{
//Fonction prenant entrée la trame et sa longueur pour calculer le checksum

}

void UartEncodeAndSendMessage(int msgFunction,
int msgPayloadLength, unsigned char* msgPayload)
{
//Fonction d’encodage et d’envoi d’un message

}

int msgDecodedFunction = 0;
int msgDecodedPayloadLength = 0;
unsigned char msgDecodedPayload[128];
int msgDecodedPayloadIndex = 0;

void UartDecodeMessage(unsigned char c)
{
//Fonction prenant en entrée un octet et servant à reconstituer les trames

}

void UartProcessDecodedMessage(unsigned char function,
unsigned char payloadLength, unsigned char* payload)
{
//Fonction appelée après le décodage pour exécuter l’action
//correspondant au message reçu

}

 

//*************************************************************************/
//Fonctions correspondant aux messages
//*************************************************************************/