Übertragung von String (DX,Y,F)

OP #2904705
Lesenswert?

Guten Tag,

ich versuche gerade ab dem PC Daten zum Atmega644p zu senden. Die Daten, 
die vom PC gesendet sind, sehen folgendermaße aus: "D X,Y F". Dh, der 
Atmega644p empfämgt nacheinander Befehle in Form von "D X,Y F".
D ---> Anfang der Daten
X----> X Position
Y----> Y Position
F----> Ende der Daten.

Der Atmega664p bekommt die Daten von PC über USART0 und leitet über 
USART1 die empfangenen Daten an zwei anderen Enheiten  weiter.

Wenn ich schritt für schritt der C-Code von Mikrocontroller  debugge, 
läuft die Datenübertragung in Atmega644p perfekt. Dh, der Atmega644p 
führt komplett aus, was er als Daten empfangen hat.

Aber wenn ich auf ein Mal mein  C-code von Atmega644p debugge, führt der 
Atmega644p nicht komplett aus, was er als Daten  empfangen hat.

Ich wäre sehr dankbar, wenn jemand mich unterstützt.

Mit besten Grüßen.

Mein C-Programm lautet:
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
}
#2904758
Lesenswert?

Luffy Monkey schrieb:
> Danke  Daniel V. für deine schnelle Antwort.
>
>>Besser: in der Mainloop schauen, ob was im Puffer steht und dann senden.
>>In der Interrupt-Routine so wenig machen wie möglich. Da solltest du
>>schnell wieder raus kommen.
>
> Kannst du mir bitte ein Beispiel vorschlagen ??
>
> Danke im Voraus.

Echt jetzt? Ich hätte aus deinem Code vermutet, dass du diese 
Kleinigkeit auch noch hinbekommst.
1
volatile uint8_t command_ready = 0;
2

3

4

5
// La fonction d´interruption de reception du byte 
6
// Cette fonction est active lorsque RXCIE0 = 1  
7
ISR(USART0_RX_vect)
8
{
9
  char data;
10
  data = UDR0;
11

12
 // Verarbeitung des Befehls -->("D X,Y F") 
13
  // X = x_moteur und Y = y_moteur 
14
  if (data == 'F')
15
  {    
16
    command_ready = 1;
17
     
18
   }
19

20
  else if (data == 'D')
21
  {
22
    /* Erzeugung eines neuen Befehls */
23
    usart_command_size = 0;
24
  }
25

26
  else
27
  {
28
    // Als man weder F, noch D empfängt, speichert man 
29
  //die Koordinatenposition(X,Y) in einem Befehl 
30
    if (usart_command_size < usart_command_max_size)
31
    {
32
      usart_command[usart_command_size] = data;
33
      ++usart_command_size;
34
    }
35
  }
36
}
37

38

39
int main (void)
40
{ 
41
  USART_Init(UBRR_VAL); // Initialisierung von USART0 and USART1
42
  VorEinstellungMotor(); // Initialisierung Motorsteuerung
43
  sei(); // Aktierung Interruptsfunktion
44

45
  while (1) // Endlosschleife
46
  {
47
    if(command_ready)
48
    {
49
      ProcessCommand();
50
      command_ready = 0;
51
    }      
52
  }
53
  
54
}

nur so auf die Schnelle
OP #2904888
Lesenswert?

иммэр эин нэуёр намэ schrieb:

> Es gibt Verschiedenes zu bemaengeln.
> - QueueIn() geht davon aus, dass die Queue eh genug Platz hat. Wenn
> voll, geht's in den Dreck.

 Bei mir hat QueueIn() genug Platz, um Daten zu bekommen.
Dataform: "DX,YF"
X ----> Höchsten 5 Zeichen in ASCii
Y ----> Höchsten 5 Zeichen in ASCii

Die Übertragung von Daten erfolgt nacheinander, so dass die QueueIn() 
immer genug Platz hat, um Zeichen zu empfangen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren