Ü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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.