File: transfer_position.c - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

001: #include <avr/io.h>
002: #include <avr/interrupt.h>
003: #include <stdio.h>
004: #include <stdlib.h>
005: #include <string.h>
006: #include <stdint.h>
007: #include <avr/pgmspace.h>
008: #define F_CPU 9.6e6
009: #include <util/delay.h>
010: 
011: #define FOSC 8000000 // Clock Speed
012: #define BAUD 115200UL
013: #define BaseDeTempsSEC 3
014: 
015: // Berechnungen zur Baudrate:
016: 
017: #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
018: 
019: #define usart_buffer_max_size 64u
020: #define usart_command_max_size 10
021: 
022: /***************************************************/
023: 
024: char usart_command[usart_command_max_size + 1] = {0};
025: char usart0_tx_buffer[usart_buffer_max_size ];
026: char usart1_tx_buffer[usart_buffer_max_size ];
027: volatile uint8_t usart_command_size = 0;
028: volatile uint8_t usart0_tx_buffer_size = 0;
029: volatile uint8_t usart0_tx_buffer_start = 0;
030: volatile uint8_t usart1_tx_buffer_size = 0;
031: volatile uint8_t usart1_tx_buffer_start = 0;
032: /***************************************************/
033: /* cha�nes de caracteres statiques servant a stocker les echos(reponses du moteur de commande) */
034:   char machaine1[30];
035:   char machaine2[30];
036:   char machaine3[30];
037:   char machaine4[30];
038:   char machaine5[30];
039:   char machaine6[30];
040:   char machaine7[30];
041: 
042: /****************************************************/
043:     /* Configuration USART0 and USART1 */
044:        /* Set baud rate */
045: void USART_Init (unsigned int ubrr)
046: {
047:   UBRR0H = (unsigned char)(ubrr>>8);
048:   UBRR0L = (unsigned char) ubrr;
049:   UBRR1H = (unsigned char)(ubrr>>8);
050:   UBRR1L = (unsigned char) ubrr;
051:  
052: /* Enable receiver and transmitter and set frame format: 8data, 2stop bit */
053: 
054:   UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
055:   UCSR0C = (1<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);
056: 
057:   UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(0<<TXCIE1)|(0<<UCSZ12)|(0<<UDRIE1);
058:   UCSR1C = (1<<USBS1) |(1<<UCSZ11)|(1<<UCSZ10);
059:  
060: }
061: 
062: /**********************************************************/
063: 
064: /*-- function receive USART0 --*/
065: 
066: unsigned char USART0_Receive (void)
067: {
068:     while(!(UCSR0A & (1<<RXC0)) ); // Wait for data to be received
069:    
070:      return UDR0; // Get and return received data from buffer
071: }
072: 
073: 
074: /*-- function transmit USART0 --*/
075: 
076: void USART0_Transmit (unsigned char data0)
077: {
078:   while ( !(UCSR0A & (1<<UDRE0)) ); // Wait for empty transmit buffer  
079:  
080:    UDR0 = data0; // Put data into buffer, sends the data
081: }
082: 
083: /*-- function receive USART1 --*/
084: 
085: unsigned char USART1_Receive (void)
086: {
087:   while(!(UCSR1A & (1<<RXC1)) );  // Wait for data to be received
088:    
089:    return UDR1; // Get and return received data from buffer
090: }
091: 
092: /*-- function transmit USART1 --*/  
093: 
094: void USART1_Transmit (unsigned char data1)
095: {
096:   while ( !(UCSR1A & (1<<UDRE1)) ); // Wait for empty transmit buffer  
097:    
098:    UDR1 = data1; // Put data into buffer, sends the data  
099: }
100: 
101: /**********************************************************/
102: /* Configuration du Timer1 Overflow */
103: void Timer1_Init(void)
104: {       // Timer 1 overflow
105:   TCCR1B |= (1<< CS12)|(1<<CS11)|(1<< CS10); // Reglage du Prescaler a 1024
106:   TIMSK1 |= (0 << TOIE1);            // Timer1 Overflow Interrupt unenable
107: }
108: 
109: /* Fonction d�interruption du Timer1 Overflow */
110: /* Cette fonction permet de faire une pause lorsque la
111: platine aura achevee son deplacement */
112: ISR(TIMER1_OVF_vect)
113: {
114:     static unsigned char counter1 = 0;
115:     counter1++;
116:     if (counter1 == BaseDeTempsSEC)
117:     {
118:       counter1 = 0;
119:       TIMSK1 |= (0 << TOIE1); // Deactivation Timer1 Overflow
120:     }
121: }
122: 
123: 
124: /**********************************************************/
125: /*-Aktivierung der Daten�bertragung �ber RS485 von USART1-*/
126: 
127:  void RS485_Init (void)
128: {
129:   DDRD = (1<<PD4)|(1<<PD3)|(1<<PD5); //Steuer- und Datenausgang aktivieren
130:   PORTD = (1<<PD4); //auf Senden stellen (Aktivierung Datensendung)
131: }
132: 
133: /**********************************************************/
134:            /* Configuration des entrees et sorties */
135: 
136: void configuration(void)
137: {
138:   // Pin 0 jusqu�a 7 definient comme entrees pour les boutons poussoirs
139:   DDRC = 0x00;
140: 
141:   // Activation Pull-up interne a partir du Pin 0 jusqu�a 7
142:    PORTC = 0xff;
143: 
144:   // Definir Pin 0 jusqu�a 7 comme sorties pour les LEDs
145:    DDRA = 0xff;
146: }
147: /**********************************************************/
148: 
149: /* Ajout dans une file */
150: void USART0_QueueIn(char c)
151: {
152:   int i;
153:  
154: 
155:   if (usart0_tx_buffer_size < usart_buffer_max_size)
156:   {
157:     i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
158:     usart0_tx_buffer[i] = c;
159:     ++usart0_tx_buffer_size;
160:   }
161: }
162: 
163: /* Sortie d'une file */
164: /* J'utilise le caract�re nul pour dire qu'il ne reste rien dans la file */
165: /* Ca signifie que la file n'est pas pr�te � recevoir du binaire */
166: char USART0_QueueOut(void)
167: {
168:   char c;
169: 
170:   if (usart0_tx_buffer_size == 0)
171:     return 0;
172:   c = usart0_tx_buffer[usart0_tx_buffer_start];
173:   --usart0_tx_buffer_size;
174:   usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart_buffer_max_size;
175:   return c;
176: }
177: 
178: /* Ajout dans une file */
179: void USART1_QueueIn(char c)
180: {
181:   int i;
182:  
183:   if (usart1_tx_buffer_size < usart_buffer_max_size)
184:   {
185:     i = (usart1_tx_buffer_size + usart1_tx_buffer_start) % usart_buffer_max_size;
186:     usart1_tx_buffer[i] = c;
187:     ++usart1_tx_buffer_size;
188:   }
189: }
190: 
191: /* Sortie d'une file */
192: /* J'utilise le caract�re nul pour dire qu'il ne reste rien dans la file */
193: /* Ca signifie que la file n'est pas pr�te � recevoir du binaire */
194: char USART1_QueueOut(void)
195: {
196:   char c;
197: 
198:   if (usart1_tx_buffer_size == 0)
199:     return 0;
200:   c = usart1_tx_buffer[usart1_tx_buffer_start];
201:   --usart1_tx_buffer_size;
202:   usart1_tx_buffer_start = (usart1_tx_buffer_start + 1) % usart_buffer_max_size;
203:   return c;
204: }
205: 
206: /* Envoie une r�ponse sur l'USART0 via la file de transfert */
207: static void USART0_Send(const char *s)
208: {
209:   int i;
210:  
211:   for (i = 0; s[i] != 0; ++i)
212:     USART0_QueueIn(s[i]);
213:   if (usart0_tx_buffer_size > 0)
214:     UCSR0B |= 1 << UDRIE0;
215: }
216: 
217: /* Envoie une commande sur l'USART1 via la file de transfert */
218: static void USART1_Send(const char *s)
219: {
220:   int i;
221:  
222:   for (i = 0; s[i] != 0; ++i)
223:     USART1_QueueIn(s[i]);
224:   if (usart1_tx_buffer_size > 0)
225:     UCSR1B |= 1 << UDRIE1;
226: }
227: 
228: /* Traitement de la commande */
229: static void ProcessCommand(void)
230: {
231:   int i;
232:   int x;
233:   int y;
234:   char x_moteur[12];
235:   char y_moteur[12];
236:  
237: 
238:   /* On extrait le X et le Y, puis on g�n�re les commandes moteurs */
239:   for (i = 0; i < usart_command_size; ++i)
240:     if (usart_command[i] == ',')
241:       break;
242:   if (i <= 0 || i >= usart_command_size - 1)
243:   {
244:     /* On n'a pas trouv� la virgule au milieu de la cha�ne -> erreur */
245:     USART0_Send("\x15");  /* NAK , L�envoi est un echec */
246:     usart_command_size = 0;
247:     return;
248:   }
249: 
250:   /* Je transforme volontairement x et y en int pour te permettre des contr�les ou des calculs */
251:   usart_command[i] = 0;
252:   usart_command[usart_command_size] = 0;
253:   x = atoi(usart_command);
254:   y = atoi(usart_command + i + 1);
255:   usart_command_size = 0;
256:   /* Envoi des commandes moteurs */
257:   itoa(x, x_moteur, 10);
258:   itoa(y, y_moteur, 10);
259:  
260:   /* Position x_moteur a envoyer */
261:   USART1_Send("#3s");
262:   USART1_Send(x_moteur);
263:   USART1_Send("\r");
264:   USART1_Receive(); // Wait for response to be received from USART1
265:   machaine1[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
266: 
267:   USART1_Send("#3A\r"); // Activation de l�envoi de x_moteur via USART1
268:   USART1_Receive(); // Wait for response to be received from USART1
269:   machaine2[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
270:  
271:   /* Position y_moteur a envoyer */  
272:   USART1_Send("#2s");
273:   USART1_Send(y_moteur);
274:   USART1_Send("\r");
275:   USART1_Receive(); // Wait for response to be received from USART1
276:   machaine3[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
277:    
278:   USART1_Send("#2A\r"); // Activation de l�envoi de y_moteur via USART1
279:   USART1_Receive(); // Wait for response to be received from USART1
280:   machaine4[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
281: 
282:   USART1_Send("#3C\r"); // Lecture de la position actuelle
283:   USART1_Receive(); // Wait for response to be received from USART1
284:   machaine5[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
285: 
286:   USART1_Send("#2C\r"); // Lecture de la position actuelle
287:   USART1_Receive(); // Wait for response to be received from USART1
288:   machaine6[30] = USART1_Receive(); // stockage de la reponse du Moteur de commande
289: 
290:   }
291: 
292: /* La fonction d�interruption de reception du byte */
293: /* Cette fonction est active lorsque RXCIE0 = 1 */
294: ISR(USART0_RX_vect)
295: {
296:   char data;
297:   data = UDR0;
298: 
299:   if (data == '\r')
300:   {
301:     /* Traitement de la commande ("/n X,Y /r") */
302:      ProcessCommand();
303:          
304:    }
305:   else if (data == '\n')
306:   {
307:     /* D�marrage d'une nouvelle commande */
308:     usart_command_size = 0;
309:     machaine1[0] = '\0'; // Vidage de la chaine
310:     machaine2[0] = '\0'; // Vidage de la chaine
311:     machaine3[0] = '\0'; // Vidage de la chaine
312:     machaine4[0] = '\0'; // Vidage de la chaine
313:     machaine5[0] = '\0'; // Vidage de la chaine
314:     machaine6[0] = '\0'; // Vidage de la chaine
315:    }
316: 
317:   else
318:   {
319:     /* Quand on ne re�oit ni \r ni \n, on enregistre le caract�re dans la commande */
320:     if (usart_command_size < usart_command_max_size)
321:     {
322:       usart_command[usart_command_size] = data;
323:       ++usart_command_size;
324:     }
325:   }
326: }
327: 
328: ISR(USART1_RX_vect)
329: {
330:  char machainereponse[30] ;
331:  machainereponse[30] = UDR1;
332: 
333:  switch(machainereponse[30])
334:  {
335:    
336:    case '3sx_moteur\r':
337:    machainereponse[0] = 0 ; // Vider la chaine
338:    break;
339: 
340:    case '3A\r':
341:    machainereponse[0] = 0 ; // Vider la chaine
342:    break;
343: 
344:    case '2sy_moteur\r':
345:    machainereponse[0] = 0 ; // Vider la chaine
346:    break;
347: 
348:    case '2A\r':
349:    machainereponse[0] = 0 ; // Vider la chaine
350:    break;
351: 
352:    case '3C\r':
353:    machainereponse[0] = 0 ; // Vider la chaine
354:    break;
355: 
356:    case '2C\r':
357:    machainereponse[0] = 0 ; // Vider la chaine
358:    TIMSK1 |= (1 << TOIE1); // Activation de la fonction d�interruption Timer1 Overflow
359:    USART0_Send("\x06"); // ACK --> l�envoi est un succes
360:    break;
361: 
362:    default:
363:    break;    
364: 
365:  }
366:  
367: 
368: }
369: 
370: 
371: 
372: /* La fonction d�interruption d�envoi de byte */
373: /* Cette fonction est active lorsque UDRIE0 = 1 */
374: ISR(USART0_UDRE_vect)
375: {
376:   UDR0 = USART0_QueueOut();
377:   /* S'il n'y a plus de donn�es � envoyer on arrete l'emission */
378:   if (usart0_tx_buffer_size == 0)
379:     UCSR0B &= ~(1 << UDRIE0);
380: }
381: 
382: /* La fonction d�interruption d�envoi de byte */
383: /* Cette fonction est active lorsque UDRIE1 = 1 */
384: ISR(USART1_UDRE_vect)
385: {
386:   UDR1 = USART1_QueueOut();
387:   /* S'il n'y a plus de donn�es � envoyer on arrete l'emission */
388:   if (usart1_tx_buffer_size == 0)
389:     UCSR1B &= ~(1 << UDRIE1);
390: }
391: 
392: void ParametrageMoteur(void)
393:  {
394:    USART1_Send("#2c\r"); // Considerer la position actuelle comme origine du repere sur l�axe x
395:    /* Attente reponse moteur de commande via USART1 */
396:    USART1_Receive(); // Wait for response to be received from USART1
397:    machaine7[30] = USART1_Receive();
398:    machaine7[0] = 0;
399: 
400:    USART1_Send("#3c\r"); // Considerer la position actuelle comme origine du repere sur l�axe y
401:    /* Attente reponse moteur de commande via USART1 */
402:    USART1_Receive();// Wait for response to be received from USART1
403:    machaine7[30] = USART1_Receive();
404:    machaine7[0] = 0;
405:    
406:    USART1_Send("#2p2\r");// Mode de travail: deplacement absolu --> p = 2
407:    /* Attente reponse moteur de commande via USART1 */
408:    USART1_Receive();// Wait for response to be received from USART1
409:    machaine7[30] = USART1_Receive();
410:    machaine7[0] = 0;
411: 
412:    USART1_Send("#3p2\r");
413:    /* Attente reponse moteur de commande via USART1*/
414:    USART1_Receive();// Wait for response to be received from USART1
415:    machaine7[30] = USART1_Receive();
416:    machaine7[0] = 0;      
417:  }
418:  
419: 
420: int main (void)
421: {
422:   USART_Init(UBRR_VAL); // Initialisation de l�USART0 et l�USART1
423:   Timer1_Init(); // Compteur permettant de faire une pause apres de deplacement de la platine
424:   RS485_Init(); // Contr�l de l�envoi des positions via l�USART1
425:   configuration(); // Configuration des entrees et sorties des PORTA, PORTC
426: /* TODO: Ici il faut param�trer les moteurs (mode de positionnement etc.) */
427:   ParametrageMoteur(); // Mode de Positionnement et de travail
428:   sei(); // Activation des fonctions d�interruption
429:  
430:  
431:   while (1) // Endlosschleife
432:   {
433:      
434:   }
435:  
436: }
437: 
438: 
439: 
440: 
441: 
442: 
443: 
444: 
445: