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: