arthurdubois King Arthur | Bonjour,
je bosse avec un microcontrôleur possedant deux USARTs(USART0 et USART1). USART0 recoit sucessivement des donnees en ASCII du PC sous la forme: DX,YF . X, Y prennent les valeurs comprises entre 0 et 9. Cependant X et Y contienent au maximum 5Bytes chacun. Exemple: D10021,12425F ou D12,2356F.
Les donnees recues par l`USART0 sont ecris continuellement dans un tableau 2D. Des lors que l`USART0 ne recoit plus de donnees du pc, alors je vide progressivement le tableau 2D en envoyant les donnees au moteur via USART1. Jusqu´ici ca va !!
Chaque fois que le moteur recoit via USART1 une instruction du microcontrôleur, le moteur retourne aussitôt via USART1 une reponse au microcontrôleur pour dire si oui ou non l´instruction sera execute.
Si j´envoie 10 instructions via USART1 au moteur, le moteur recevra la 1er instruction et ensuite il retournera via USART1 au microntrôleur une reponse pour dire si oui ou non l´instruction est correct. Apres le moteur pourra recevoir la 2ieme instruction et le processus sera pareil pour les autres instructions.
Exemple:
Miconcontrôleur envoie:---> "#1A\r"
Reponse moteur:----------> "1A\r" : instruction correct( '?' est absent)
Miconcontrôleur envoie:---> "#1°\r"
Reponse moteur:----------> "1°?\r" : instruction pas correct( '?' est present)
J´ai essaye de synchroniser l´envoie des instructions via USART1 vers le moteur et le retour de reponses du moteur pour chaque instruction recue. Mais je pense que je m´y prends mal au niveau de la fonction ISR(USART1_RX_vect) qui est charge de recevoir les reponses du moteur et ensuite d´activer l´envoie des autres instructions.
Pourriez-vous m´aider s´il vous plaît !! Merci d´avance.
PS: Dans mon programme, je me contente de gerer les reponses du moteur qui sont corrects au niveau de la fonction ISR(USART1_RX_vect).
Programme:
Code :
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #include <util/delay.h>
- #define F_CPU 3686400UL
- #define FOSC 7372000 // Clock Speed
- #define BAUD 9600UL
- #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1) // clever runden
- ///////////////////////////////////////////////////////////////////
- #define usart_buffer_max_size 16u
- #define usart_command_max_size 16u
- #define ROW 200
- #define COLUMN 12
- #define MAX 10
- ///////////////////////////////////////////////////////////////////
- char Table_2D[ROW][COLUMN]; // table in dimensional two
- char Table_1D[COLUMN] = {0}; // table in dimensional one
- char motor_command[COLUMN];
- char usart0_tx_buffer[usart_buffer_max_size];
- char usart1_tx_buffer[usart_buffer_max_size];
- volatile uint8_t usart0_tx_buffer_size = 0;
- volatile uint8_t usart0_tx_buffer_start = 0;
- volatile uint8_t usart1_tx_buffer_size = 0;
- volatile uint8_t usart1_tx_buffer_start = 0;
- volatile uint8_t command_execution = 0;
- volatile uint8_t command_start = 0;
- volatile uint8_t COMMAND_SIZE = 0;
- volatile uint8_t command_ready = 0;
- /////////////////////////////////////////////////////////////////////
- int i = 0; // Number of elements in a row
- int j = 0; // Number of rows
- int N = sizeof(Table_2D) / sizeof(Table_2D[0]); // Number of rows
- int M = sizeof(Table_2D) / sizeof(Table_2D[j][0]); // Number elements of a row
- /////////////////////////////////////////////////////////////////////
- // Configuration USART0, USART1 and setting Baudrate
- void USART_Init(unsigned int ubrr)
- {
- UBRR0H = (unsigned char)(ubrr>>8);
- UBRR0L = (unsigned char) ubrr;
- UBRR1H = (unsigned char)(ubrr>>8);
- UBRR1L = (unsigned char) ubrr;
- UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0);
- UCSR0C = (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00); // 1 Stopbit, data = 8 Bits
- UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (0<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1);
- UCSR1C = (0<<USBS1) | (1<<UCSZ11) | (1<<UCSZ10); // 1 Stopbit, data = 8 Bits
- }
- /////////////////////////////////////////////////////////////////////
- // Entry of circular buffer for USART0
- void USART0_QueueIn(char c)
- {
- int i;
- if (usart0_tx_buffer_size < usart_buffer_max_size)
- {
- i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
- usart0_tx_buffer[i] = c;
- ++usart0_tx_buffer_size;
- }
-
- }
- // Exit of circular buffer for USART0
- char USART0_QueueOut(void)
- {
- char c;
- if (usart0_tx_buffer_size == 0)
- return 0;
- c = usart0_tx_buffer[usart0_tx_buffer_start];
- --usart0_tx_buffer_size;
- usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart_buffer_max_size;
- return c;
- }
- // Entry of circular buffer for USART1
- void USART1_QueueIn(char c)
- {
- int i;
- if (usart1_tx_buffer_size < usart_buffer_max_size) // Circular buffer is not full
- {
- i = (usart1_tx_buffer_size + usart1_tx_buffer_start) % usart_buffer_max_size;
- usart1_tx_buffer[i] = c;
- ++usart1_tx_buffer_size;
- }
-
- }
- // Exit of circular buffer for USART1
- char USART1_QueueOut(void)
- {
- char c;
- if (usart1_tx_buffer_size == 0)
- return 0;
- c = usart1_tx_buffer[usart1_tx_buffer_start];
- --usart1_tx_buffer_size;
- usart1_tx_buffer_start = (usart1_tx_buffer_start + 1) % usart_buffer_max_size;
- return c;
- }
- // Sending response via circular buffer to the USART0
- static void USART0_Send(const char *s)
- {
- int i;
- for (i = 0; s[i] != 0; ++i)
- USART0_QueueIn(s[i]);
- if (usart0_tx_buffer_size > 0)
- UCSR0B |= 1 << UDRIE0;
- }
- // Sending a command via circular buffer to the USART1
- static void USART1_Send(const char *s)
- {
- int i;
- for (i = 0; s[i] != 0; ++i)
- USART1_QueueIn(s[i]);
- if (usart1_tx_buffer_size > 0)
- UCSR1B |= 1 << UDRIE1;
- }
- // Treatment of command
- static void ProcessCommand(void)
- {
- int i;
- int k;
- int x;
- int y;
- int pos_x;
- int pos_y;
- char x_motor[12];
- char y_motor[12];
- for (i = 0; i < COMMAND_SIZE; ++i)
- if (motor_command[i] == ',')
- break;
- if (i <= 0 || i >= COMMAND_SIZE - 1)
- {
-
- USART0_Send("\x15" ); // NAK, Sending didn´t work.
- COMMAND_SIZE = 0;
- return;
- }
- // Conversion of x and y in integer for the execution of calculation,if it is necessary
- // Extraction of X and Y
-
- motor_command[i] = 0;
- motor_command[COMMAND_SIZE] = 0;
- x = atoi(motor_command);
- y = atoi(motor_command + i + 1);
- COMMAND_SIZE = 0;
- // Conversion in stepping motor
- pos_x= x * 127/500;
- pos_y= y * 127/500;
- // Conversion in ascii
- itoa(pos_x, x_motor, 10);
- itoa(pos_y, y_motor, 10);
- if(command_start == 0)
- {
- // Sending position x_moteur
- USART1_Send("#1s" );
- USART1_Send(x_motor);
- USART1_Send("\r" );
- }
- if(command_start == 1)
- {
- USART1_Send("#1A\r" ); // the plate can move in axis x
- }
-
- if(command_start == 2)
- {
- // Sending of position y_moteur
- USART1_Send("#2s" );
- USART1_Send(y_motor);
- USART1_Send("\r" );
- }
- if(command_start == 3)
- {
- USART1_Send("#2A\r" ); // the plate can move in axis y
- }
-
- wait(3000); //wait 3000ms ---> 3s
-
- }
- ISR(USART1_RX_vect)
- {
- char response[MAX] = {0};
- int n,m;
- for(n = 0; n < MAX; n++)
- {
- response[n] = UDR1;
- }
-
- if(strcmp(response, "1D0\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_ready = 1;
- }
- if(strcmp(response, "2D0\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_ready = 2;
- }
- if(strcmp(response, "1p2\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_ready = 3;
- }
- if(strcmp(response, "2p2\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_ready = 0;
- }
- if(strcmp(response, "1sx_motor\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_start = 1;
- }
- if(strcmp(response, "1A\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
-
- }
- if(strcmp(response, "Ziel erreicht" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_start = 2;
- }
- if(strcmp(response, "1sy_motor\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_start = 3;
- }
- if(strcmp(response, "2A\r" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- }
-
- if(strcmp(response, "Ziel erreicht" ) == 0)
- {
- for(m = 0; m < MAX; m++)
- {
- response[m] = '\0'; // String is empty
- }
- command_start = 0;
- }
- }
- // function wait
- void wait(unsigned int time)
- {
- unsigned int counter = 20;
- for(int i = 0; i < counter; i++)
- {
- _delay_ms(time);
- }
- }
- // function receive interrupt of Byte
- // the fuction receice interrupt is High, if RXCIE0 = 1
- ISR(USART0_RX_vect)
- {
- char data;
- data = UDR0;
- // Reception of command -->("D X,Y F" )
- // X = x_motor and Y = y_motor
- if (data == 'F')
- {
- ++j;
- USART0_Send("\x06" ); // ACK ---> PC can send next data
-
- }
- else if (data == 'D')
- {
- // Generation of a new command
- i = 0;
- }
-
- else
- {
- // If we not receive 'F' or 'D', we store
- // the positions of coordinate in a table
-
- if(j < ROW)
- {
- if(i < COLUMN)
- {
- Table_2D[j][i] = data;
- ++i;
- }
-
- }
- else
- {
- //USART0_Send("\x04" );// EOT --> PC must wait a few minuts
- // j = 0;
- }
- }
- command_execution = 1; // Sending of data begin to USART1
- }
- void Copytable(char Originaltable2D[N][M], char Copytable1D[], int N1, int M1)
- {
- int j1;
- int i1;
- for(j1 = 0; j1 < N1; j1++)
- {
- for(i1 = 0; i1 < M1; i1++)
- {
- Copytable1D[i1] = Originaltable2D[j1][i1];
- motor_command[COMMAND_SIZE] = Copytable1D[i1];
- ++COMMAND_SIZE;
- }
- ProcessCommand();
- }
- }
- // The function interrupt for sending of Byte
- // The function interrupt is active, if UDRIE0 = 1
- ISR(USART0_UDRE_vect)
- {
- UDR0 = USART0_QueueOut();
- // Stop sending,if we don´t have data to send.
- if (usart0_tx_buffer_size == 0)
- UCSR0B &= ~(1 << UDRIE0);
- }
- // The function interrupt for sending of Byte
- // The function interrupt is active, if UDRIE1 = 1
- ISR(USART1_UDRE_vect)
- {
- UDR1 = USART1_QueueOut();
- // Stop sending,if we don´t have data to send.
- if (usart1_tx_buffer_size == 0)
- UCSR1B &= ~(1 << UDRIE1);
- }
- void ConfigurationMotor(void)
- {
- //USART1_Send("#1|0\r" ); // Deactivation of response motor-control Nr 1
- //USART1_Send("#2|0\r" ); // Deactivation of response motor-control Nr 2
- //USART1_Send("#1:baud=7" ); // Baudrate = 9600
- //USART1_Send("#2:baud=7" ); // Baudrate = 9600
- USART1_Send("#1D0\r" ); // The actual position of plate is the origin in axis x
-
- }
- int main (void)
- {
- sei(); // Activation of function Interrupt
- USART_Init(UBRR_VAL); // Initialisation of USART0 and USART1
- ConfigurationMotor(); // Initialisaton of Motor-control
-
-
-
- while (1) // Infinite loop
- {
-
- if(command_ready == 1)
- {
- USART1_Send("#2D0\r" ); // The actual position of plate is the origin in axis y
- }
- if(command_ready == 2)
- {
- USART1_Send("#1p2\r" ); // Mode: Positioning absolut --> p=2
- }
- if(command_ready == 3)
- {
- USART1_Send("#2p2\r" ); // Mode: Positioning absolut --> p=2
- }
-
-
- if(command_execution == 1)
- {
- Copytable(Table_2D, Table_1D, ROW, COLUMN);
- command_execution = 0;
- }
-
- }
- }
|
|