Problem mit simplem FiFo

OP #1979075
Lesenswert?
• ▲
▼
Moin Moin,
ich versuche zur Zeit einen einfachen FIFO zu implementieren. Dazu habe 
ich einen externen SRAM-Baustein im Einsatz, der 16 Speicherbänke à 32kB 
beherbergt. Eine Testfunktion, die alles mit fortlaufenden Nummern 
beschreibt und später wieder kontrolliert, funktioniert einwandfrei.

Nun versuche ich eine Eingabe über UART zu realisieren, bei der zunächst 
beliebig viele Zeichen in den FIFO geschrieben werden und bei Eingabe 
eines '#' die ersten hundert Zeichen im FIFO ausgegeben werden sollen. 
Leider bleibt die Ausgabe immer bei Zeichen 98 hängen. Nun weiß ich 
nicht, wo der Fehler liegt, bei der FIFO-Routine, die im vorherigen Test 
ja reibungslos funktioniert hat, oder bei der UART-Ausgabe (P. Fleury), 
die ja eigentlich auch erprobt ist... Vielleicht könnt ihr mir ja 
weiterhelfen...
1
#define UART_BAUD_RATE 9600
2
#define XMEM_OFFSET 0x2200
3
#define XMEM_BANK_SIZE 0x8000
4

5
struct {
6
  uint16_t address;
7
  uint8_t bank;
8
} fifo_read, fifo_write;
9

10
void fifo_init(void){
11
  XMCRA |= (1<<SRE);
12
  XMCRB |= (1<<XMM0);
13

14
  DDRF |= 0xF0;
15
  PORTF &= 0x0F;
16

17
  fifo_read.address = XMEM_OFFSET;
18
  fifo_read.bank = 0;
19

20
  fifo_write.address = XMEM_OFFSET;
21
  fifo_write.bank = 0;
22
}
23

24
void fifo_putc(char c){
25
  PORTF = (fifo_write.bank << 4) | (PORTF & 0x0F);
26
  *((char*) fifo_write.address) = c;
27

28
  if(++fifo_write.address == XMEM_BANK_SIZE+XMEM_OFFSET){
29
    fifo_write.address = XMEM_OFFSET;
30
    if(++fifo_write.bank == 0x10)
31
      fifo_write.bank = 0;
32
  }
33
}
34

35
char fifo_getc(void){
36
  PORTF = (fifo_read.bank << 4) | (PORTF & 0x0F);
37
  uint8_t rtrn = *((char*) fifo_read.address);
38

39
  if(++fifo_read.address == XMEM_BANK_SIZE+XMEM_OFFSET){
40
    fifo_read.address = XMEM_OFFSET;
41
    if(++fifo_read.bank == 0x10)
42
      fifo_read.bank = 0;
43
  }
44

45
  return rtrn;
46
}
47

48
int main(void){
49
  uint16_t c;
50

51
  sei();
52

53
  uart_init(UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU));
54
  fifo_init();
55

56
  fdevopen(uart_putc, NULL);
57

58
  while(1){
59
    c = uart_getc();
60
    
61
    if(!(c & UART_NO_DATA)){
62
      if((char) c != '#'){
63
        fifo_putc((char)c);
64
        uart_putc('X');
65
      }
66
      else{
67
        printf("End-Zeichen erhalten!\n");
68
        break;
69
      }
70
    }
71
  }
72
  
73
  for(uint8_t i=0; i<100; i++){
74
    printf("Zeichen %d: %c\n", i, fifo_getc());
75
  }
76

77
  return 0;
78

79
}

Danke und Gruß
Sven
#1979105
Lesenswert?
• ▲
▼
Häng entweder deine Ausgabe noch mit in die Endlosschleife mit rein, 
oder mach noch eine Endlosschleife hinter deine Ausgabe.

Dein Programm darf main() nie verlassen!
Tut es dass, dann sorgt die C-Runtime dafür, dass zb Interrupts 
abgeschaltet werden und damit steht dann auch deine Ausgabefunktion, die 
die Zeichen im Hintergrund per Interrupt an den Mann bringt.

Die bessere Lösung ist es, wenn du dich daran gewöhnst, dass sich deine 
Programmlogik immer innerhalb der einzigen
1
  while( 1 ) {
2

3
    ....
4
  }

Schleife in main abspielt. Und zwar nur dort! Ein µC beendet sein 
Programm nie!
Auch wenn das heißt, dass du deinen jetzigen Code dazu etwas umbauen 
musst.

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.