1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <stdio.h>
|
4 | #include <stdlib.h>
|
5 | #include <string.h>
|
6 | #include <stdint.h>
|
7 | #include <util/delay.h>
|
8 |
|
9 | #define F_CPU 9.6e6
|
10 | #define FOSC 8000000 // Clock Speed
|
11 | #define BAUD 115200UL
|
12 |
|
13 | #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1) // clever runden
|
14 | ///////////////////////////////////////////////////////////////////
|
15 | #define usart_buffer_max_size 64u
|
16 | #define usart_command_max_size 10
|
17 |
|
18 | char usart_command[usart_command_max_size + 1] = {0};
|
19 | char usart0_tx_buffer[usart_buffer_max_size];
|
20 | char usart1_tx_buffer[usart_buffer_max_size];
|
21 | volatile uint8_t usart_command_size = 0;
|
22 | volatile uint8_t usart0_tx_buffer_size = 0;
|
23 | volatile uint8_t usart0_tx_buffer_start = 0;
|
24 | volatile uint8_t usart1_tx_buffer_size = 0;
|
25 | volatile uint8_t usart1_tx_buffer_start = 0;
|
26 |
|
27 | // Configuration USART0, USART1 and setting Baudrate
|
28 |
|
29 | void USART_Init(unsigned int ubrr)
|
30 | {
|
31 | UBRR0H = (unsigned char)(ubrr>>8);
|
32 | UBRR0L = (unsigned char) ubrr;
|
33 | UBRR1H = (unsigned char)(ubrr>>8);
|
34 | UBRR1L = (unsigned char) ubrr;
|
35 | UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0);
|
36 | UCSR0C = (1<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);
|
37 | UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (0<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1);
|
38 | UCSR1C = (1<<USBS1) | (1<<UCSZ11) | (1<<UCSZ10);
|
39 | }
|
40 |
|
41 | // Eingang vom Ringpuffer
|
42 | void USART0_QueueIn(char c)
|
43 | {
|
44 | int i;
|
45 |
|
46 | if (usart0_tx_buffer_size < usart_buffer_max_size)
|
47 | {
|
48 | i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
|
49 | usart0_tx_buffer[i] = c;
|
50 | ++usart0_tx_buffer_size;
|
51 | }
|
52 | }
|
53 |
|
54 | // Ausgang vom Ringpuffer
|
55 | char USART0_QueueOut(void)
|
56 | {
|
57 | char c;
|
58 |
|
59 | if (usart0_tx_buffer_size == 0)
|
60 | return 0;
|
61 | c = usart0_tx_buffer[usart0_tx_buffer_start];
|
62 | --usart0_tx_buffer_size;
|
63 | usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart_buffer_max_size;
|
64 | return c;
|
65 | }
|
66 |
|
67 | // Eingang vom Ringpuffer
|
68 | void USART1_QueueIn(char c)
|
69 | {
|
70 | int i;
|
71 |
|
72 | if (usart1_tx_buffer_size < usart_buffer_max_size)
|
73 | {
|
74 | i = (usart1_tx_buffer_size + usart1_tx_buffer_start) % usart_buffer_max_size;
|
75 | usart1_tx_buffer[i] = c;
|
76 | ++usart1_tx_buffer_size;
|
77 | }
|
78 | }
|
79 |
|
80 | // Ausgang vom Ringpuffer
|
81 | char USART1_QueueOut(void)
|
82 | {
|
83 | char c;
|
84 |
|
85 | if (usart1_tx_buffer_size == 0)
|
86 | return 0;
|
87 | c = usart1_tx_buffer[usart1_tx_buffer_start];
|
88 | --usart1_tx_buffer_size;
|
89 | usart1_tx_buffer_start = (usart1_tx_buffer_start + 1) % usart_buffer_max_size;
|
90 | return c;
|
91 | }
|
92 |
|
93 | // Sendung einer Antwort über der Ringpuffer zum USART0
|
94 | static void USART0_Send(const char *s)
|
95 | {
|
96 | int i;
|
97 |
|
98 | for (i = 0; s[i] != 0; ++i)
|
99 | USART0_QueueIn(s[i]);
|
100 | if (usart0_tx_buffer_size > 0)
|
101 | UCSR0B |= 1 << UDRIE0;
|
102 | }
|
103 |
|
104 | // Sendung eines Befehls über der Ringpuffer zum USART1
|
105 | static void USART1_Send(const char *s)
|
106 | {
|
107 | int i;
|
108 |
|
109 | for (i = 0; s[i] != 0; ++i)
|
110 | USART1_QueueIn(s[i]);
|
111 | if (usart1_tx_buffer_size > 0)
|
112 | UCSR1B |= 1 << UDRIE1;
|
113 | }
|
114 |
|
115 | // Verarbeitung eines Befehls
|
116 | static void ProcessCommand(void)
|
117 | {
|
118 | int i;
|
119 | int x;
|
120 | int y;
|
121 | char x_moteur[12];
|
122 | char y_moteur[12];
|
123 |
|
124 |
|
125 | for (i = 0; i < usart_command_size; ++i)
|
126 | if (usart_command[i] == ',')
|
127 | break;
|
128 |
|
129 | if (i <= 0 || i >= usart_command_size - 1)
|
130 | {
|
131 | // Man hat kein Kommazeichen in Mitte des Strings gefunden -> Fehler
|
132 | USART0_Send("\x15"); // NAK, Sendung von Data hat nicht geklappt.
|
133 | usart_command_size = 0;
|
134 | return;
|
135 | }
|
136 | // Ich wandle x und y in Integer um, um Berechnung durchzuführen, wenn es nötig ist
|
137 | // Extraktion von X und Y
|
138 | usart_command[i] = 0;
|
139 | usart_command[usart_command_size] = 0;
|
140 | x = atoi(usart_command);
|
141 | y = atoi(usart_command + i + 1);
|
142 | usart_command_size = 0;
|
143 | itoa(x, x_moteur, 10);
|
144 | itoa(y, y_moteur, 10);
|
145 |
|
146 | // Sendung position x_moteur
|
147 | USART1_Send("#1s");
|
148 | USART1_Send(x_moteur);
|
149 | USART1_Send("\r");
|
150 |
|
151 | USART1_Send("#1A\r"); // Losfahren der Platine auf die x-Achse
|
152 |
|
153 | // Sendung position y_moteur
|
154 | USART1_Send("#2s");
|
155 | USART1_Send(y_moteur);
|
156 | USART1_Send("\r");
|
157 |
|
158 | USART1_Send("#2A\r"); // Losfahren der Platine auf die y-Achse
|
159 | USART0_Send("\x06"); // ACK ---> Freigabe: PC kann der nächste Data senden
|
160 |
|
161 |
|
162 | }
|
163 |
|
164 | // La fonction d´interruption de reception du byte
|
165 | // Cette fonction est active lorsque RXCIE0 = 1
|
166 | ISR(USART0_RX_vect)
|
167 | {
|
168 | char data;
|
169 | data = UDR0;
|
170 |
|
171 | // Verarbeitung des Befehls -->("D X,Y F")
|
172 | // X = x_moteur und Y = y_moteur
|
173 | if (data == 'F')
|
174 | {
|
175 | ProcessCommand();
|
176 |
|
177 | }
|
178 |
|
179 | else if (data == 'D')
|
180 | {
|
181 | /* Erzeugung eines neuen Befehls */
|
182 | usart_command_size = 0;
|
183 | }
|
184 |
|
185 | else
|
186 | {
|
187 | // Als man weder F, noch D empfängt, speichert man
|
188 | //die Koordinatenposition(X,Y) in einem Befehl
|
189 | if (usart_command_size < usart_command_max_size)
|
190 | {
|
191 | usart_command[usart_command_size] = data;
|
192 | ++usart_command_size;
|
193 | }
|
194 | }
|
195 | }
|
196 |
|
197 | // Interruptsfunktion für Byte-Übertragung
|
198 | // Diese Funktion ist an, wenn UDRIE1 = 1
|
199 | ISR(USART0_UDRE_vect)
|
200 | {
|
201 | UDR0 = USART0_QueueOut();
|
202 | // Sendung stoppen, wenn es keine Daten mehr gibt zu senden
|
203 | if (usart0_tx_buffer_size == 0)
|
204 | UCSR0B &= ~(1 << UDRIE0);
|
205 | }
|
206 |
|
207 | // Interruptsfunktion für Byte-Übertragung
|
208 | // Diese Funktion ist an, wenn UDRIE1 = 1
|
209 | ISR(USART1_UDRE_vect)
|
210 | {
|
211 | UDR1 = USART1_QueueOut();
|
212 | // Sendung stoppen, wenn es keine Daten mehr gibt zu senden
|
213 | if (usart1_tx_buffer_size == 0)
|
214 | UCSR1B &= ~(1 << UDRIE1);
|
215 | }
|
216 |
|
217 | void VorEinstellungMotor(void)
|
218 | {
|
219 | USART1_Send("#1|0\r"); // Deaktivierung von Antwort der Motorsteuerung Nr 1
|
220 | USART1_Send("#2|0\r"); // Deaktivierung von Antwort der Motorsteuerung Nr 2
|
221 | USART1_Send("#1D0\r"); // Festlegen der Position der Platine als Ursprung auf die x-Achse
|
222 | USART1_Send("#2D0\r"); // Festlegen der Position der Platine als Ursprung auf die y-Achse
|
223 | USART1_Send("#1p2\r"); // Modus: Absolut Positionierung --> p=2
|
224 | USART1_Send("#2p2\r"); // Modus: Absolut Positionierung --> p=2
|
225 |
|
226 | }
|
227 |
|
228 | int main (void)
|
229 | {
|
230 | USART_Init(UBRR_VAL); // Initialisierung von USART0 and USART1
|
231 | VorEinstellungMotor(); // Initialisierung Motorsteuerung
|
232 | sei(); // Aktierung Interruptsfunktion
|
233 |
|
234 | while (1) // Endlosschleife
|
235 | {
|
236 |
|
237 | }
|
238 |
|
239 | }
|