Problem mit Zeiger auf Array

Gast #2087236
Lesenswert?

Hi,

ich bin grad dabei mir eine kleine uart-empfangsroutine zu schreiben und 
häng an einem Problem fest.

Also die uart läuft ohne probleme und löst auch interrupts aus.
1
#define rx_buffer_len 32
2

3
unsigned char rx_buffer[rx_buffer_len];
4
unsigned char *ptr_read = rx_buffer;
5
unsigned char *ptr_write = rx_buffer;
6

7

8
void init_uart (void){
9
  UBRRH = (unsigned char)(bauddivider>>8);
10
  UBRRL = (unsigned char)bauddivider;
11

12
  UCSRA = (1<<U2X);
13
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
14
  UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
15

16
}
17

18

19
void uart_putchar(unsigned char c)
20
{
21
  while( !( UCSRA & (1<<UDRE)));
22
  UDR = c;
23
}
24

25

26

27
ISR(USART_RX_vect)
28
{
29
  *ptr_write= UDR;
30
  ptr_write++;
31
  if(ptr_write == rx_buffer + rx_buffer_len) ptr_write = rx_buffer;
32

33
    while ( !( UCSRA & (1<<UDRE)) );
34

35
}
36

37

38
int main(void){
39

40
  DDRB = 0x1F;
41
  PORTB = 0xFF;
42

43
  DDRD = 0x30;
44
  PORTD = 0x00;
45

46
  init_uart();
47

48
  sei();
49

50
  while(1){
51

52
    for(unsigned char i = 0 ; i < rx_buffer_len ; i++)
53
      uart_putchar(rx_buffer[i]);
54

55

56
    uart_putchar(*ptr_write);
57
    uart_putchar(*ptr_read);
58

59

60
    _delay_ms(5000);
61

62

63
  }
64

65
}

also wie schon erwähnt senden und empfangen funtioniert sehr gut.
wenn ich das programm starte bekomm ich folgendes auf dem 232-Term:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00

also der Buffer-inhalt + die zwei zeigerinhalte alles 00 ... soweit so 
gut
sende ich jetzt ein zeichen (z.B. 0xAA) bekomm ich so etwas:

AA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 AA AA

das Zeichen 0xAA steht am anfang vom Buffer. Der lesezeiger (ptr_read) 
zeigt auf das erste element, was auch so sein soll ... aber wiso zeigt 
der zweite Zeiger auf das gleiche Zeichen?
wenn ich jetzt aber 0xff sende bekomm ich folgendes:

AA FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 AA AA

der ptr_write zeigt also immer auf das nächste element im speicher.. 
aber nur in der ISR .. sonst immer auf das erste... kamm mir da einer 
weiterhelfen? Was mache ich da falsch?

gruß Mathias
Gast #2087258
Lesenswert?

Danke für die schnelle Antwort! also mit volatile hab ich schon versucht 
... da hat sich nix verbessert.

Es geht mir jetzt zwar in erster linie darum wiso das nicht funktioniert 
damit ich beim nächsten mal bescheid waiß, aber wie könnte ich denn die 
Pointerverwaltung meines Puffers verbessern?

gruß Mathias
Gast #2087281
Lesenswert?

also die ISR an sich sieht nicht sonderlich durchdacht aus.
1
if(ptr_write == rx_buffer + rx_buffer_len) ptr_write = rx_buffer;

hier vergleichst du die adresse des pointers ptr_write mit dem Wert von 
rx_buffer[0]+rx_buffer_len? bringt wohl nichts...also ich denke du 
willst prüfen ob du das ende erreicht hast und dann den pointer zurück 
aufs erste element setzen...also müsste es heißen:
1
if(ptr_write == &rx_buffer + rx_buffer_len) ptr_write = &rx_buffer;

als nächstes...die while-schleife gehört nicht in eine ISR!! Also nur 
aufs ereignis warten...pointer, etc. setzen und weiter im Text.

Bei Fehlern möge man mich bitte korrigieren...

mfg
TheMiB
Gast #2087301
Lesenswert?

Hi

also bei mir klappt es so mit der end of buffer erkennung ... ich mein 
auch das " *ptr = array " das gleiche ist wie " *ptr = &array[0] "

gut mit der while-schleife in der ISR is net so ganz schön .. hatte ich 
irgendwann zwischendurch eingefügt um den fehler zu finden bevor ich mir 
den ganzen puffer hab ausprinten lassen wo ich dann gesehen hab das 
soweit alles klappt mit den Puffer befüllen ...
Gast #2087324
Lesenswert?

also ich habs so gemacht:
1
volatile unsigned char *ptr_read;
2
volatile unsigned char *ptr_write;

habs aber auch mal so probiert (?) :
1
unsigned char volatile *ptr_read;
2
unsigned char volatile *ptr_write;

oder macht man das bei pointern noch anders?
Gast #2087478
Lesenswert?

Hi,

ja hab ich auch schon bemerkt ... besonders blöd wird es wenn genau 32 
Bytes kommen .. dann steht der Pointer genau an der selben stelle und 
man kann nicht mehr mit einem pointervergleich sehen ob was gekommen ist 
oder nich ... hab jetzt eine abbruchbedingung nach Buffer_len -1 gemacht 
... alles was dann kommt ignorier ich dann einfach ... in meinem fall 
kommen aber eh nie so viele daten auf einmal ...

trozdem danke für den Hinweis!
Gast #2088069
Lesenswert?

ja wie gesagt ich bekomm eh nur max 5 Byte auf einmal und das auch nur 
max ein mal pro sec. also sollten die 32 Byte locker reichen!

die while schleife ist auch schon raus ... wie gesagt hatte sie nur bei 
der fehlersuche rein gemacht ... aber jetzt läuft alles wie es soll ..

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