Navigation

Mitglieder Online

· Gäste Online: 1

· Mitglieder Online: 0

· Anzahl Mitglieder: 107
· Neuestes Mitglied: Klimparfed

Neueste Artikel

Login

Benutzername

Passwort



Noch kein Mitglied?
Hier klicken um Dich zu registrieren.

Passwort vergessen?
Um ein neues Passwort anzufordern klicke hier.

Latest Downloads

Forum Themen

Neueste Themen
· Multi-Master IIC Int...
· HCS08 im DIP Gehäuse
· Rotary Encoder
· Serial Software Buffer
· Embedded World 3-5.3...
Heisseste Themen
Keine Themen erstellt

Thema ansehen

 Thema drucken
Serial Software Buffer
norticum
Hallo!

Ich arbeite gerade an einer RS232 Kommunikation zwischen einem AW60 und einem Siemens GSM Modul. Die Senderoutine vom Controller zum GSM Modul läuft bereits Einwandfrei. Als nächstes möchte ich SMS Texte und Statusmeldungen vom GSM Modul auswerten. Dazu müsste ich einen FIFO Softwarebuffer im Controller anlegen. Der Empfang der Zeichen arbeitet auch schon. Ich benutze zur Zeit den RX Interrupt. Nur wie lege ich einen Buffer an bzw wie schreibe ich in diesen und werte das dann aus?

Vielleicht hat jemand einen Input für mich?

norticum
It´s not a bug!
It´s a feature!
 
ego
Hallo,

das ist im Prinzip ganz einfach. ich habe das bei bei Zwobots LCD Controller mal implementiert. Das Projekt gibt es hier http://www.eckhard-gosch.de/de/readarticle.php?article_id=11.

Man legt einen Puffer und zwei Zähler an.

extern unsigned char databuf[32];
extern unsigned char readptr,writeptr;

Der eine Zähler zeigt auf die Position ab der gelesen wird und der andere auf die Schreibposition.

Die Interruptroutine schreibt dann in den Puffer.
Download Code  Code

__interrupt void isrINT_SCIReceive(void)
{
  /* Write your interrupt code here ... */


while ( !(SCS1 && 0x20 ));
databuf[writeptr++] = SCDR;
if ( writeptr == 40 ) { 
  writeptr = 0;
}






Wenn das Ennde des Puffers erreicht ist, wird der Zähler wieder auf den Anfang gesetzt. So funktioniert der Puffer quasi als Ringpuffer.

Die Funktion getchar holt dann einfach ein Zeichen aus dem Puffer und zählt den Lesezähler hoch.

Download Code  Code

unsigned char getchar()


{
if ( readptr == 40 ) {
  readptr = 0;
}

/* warten bis ein Zeichen angekommen ist */

while ( readptr == writeptr ){
}
return databuf[readptr++];
}






Im Hauptprogramm wird dann der Inhalt mittels getchar verarbeitet.

Download Code  Code

void main(void) {

unsigned char input;
signed char i;
int value;

 
   MCU_init();

  EnableInterrupts; /* enable interrupts */

 

readptr = 0;
writeptr = 0;
LCD_initialize();

LCD_puts("Zwobot LCD ready");

LCD_puts("Warte auf Zwobot");
wait_mS(100);
SCI_SendByte('a');
while(1){
  input = getchar();
  if ( input == '%' ) {
    input = getchar();
   
    switch (input) {
      case 'b':   
            input = getchar();
            for ( i=7; i >= 0; i--) {
                if (get_bit(input,i) == 1 ) {                 
                    LCD_putchar('1');               
                }
                else {                 
                    LCD_putchar('0');
                }
            }
            /* Byte als folge von Bits ausgeben */
            break;
      case 'n':
            input = getchar();
            LCD_putn(input);

            /* Byte numerisch ausgeben */
            break;
      case 'i' :
            input = getchar();
            value = 256*input;
            input = getchar();
            value = value + input;
            LCD_putn(value);
            /* 2 Byte Integer ausgeben */
            break;
      case 'l':
            input = getchar();
            LCD_locate ( input, column);
            /* zeile setzen */
            break;
      case 's':
            input = getchar();
            LCD_locate(row, input);
                  /* spalte setzen */
                  break;
      case 'p':
            row = getchar();
            column = getchar();
            LCD_locate( row, column );
                  /* cursorposition setzen Byte 1 Zeile, Byte 2 Spalte */
                   break;
      case 'c':
            /* clear befehl für das LCD */
            LCD_clear();
            break;
      case '%':
            /* % Zeichen ausgeben */
            LCD_putchar('%');
            break;
                  
     } /* switch */
  } /* if */
  else {
        LCD_putchar(input);
  }
} /* while */






Hoffe das hilft.

Eckhard
 
norticum
Hallo ego!

Ja das mit dem zwobots Display hab ich gelesen. Bis jetzt kann ich den Code aber nicht interpretieren da ich in Assembler programmiere. Ende März mache ich einen C Kurs. Vielleicht würde es dann gehen. Ich überlege auch schon einen Kurs bei der Hilf! Gmbh zu machen aber die Kurse dort Freescale betreffend sind sauteuer. 1600€ für drei Tage Kurs. Ich hab auch im Freescaleforum einen Thread geöffnet der mein "Problem" behandelt.

http://forums.freescale.com/freescale/board/message?board.id=8BITCOMM&thread.id=12849

Da habe ich auch einige hilfreiche Infos dazu bekommen.

Vielen Dank für deine Mühe!

norticum
It´s not a bug!
It´s a feature!
 
ego
Hallo Norticum,

ein Beispiel in Assembler habe ich hier : http://www.eckhar...cdterm.asm

Ich benutze hier zwar den Keyboard Interrupt aber das Prinzip ist gleich.

Die Variablen deklarieren :

Download Code  Code

inptr            ds      1              ; position im Empfangspuffer für empfang
outptr          ds      1              ; position im empfangspuffer für ausgabe
data            ds      32T            ; Empfangsdaten puffer 32 Byte





dann das empfangene Zeichen in den Puffer schreiben :
Download Code  Code

**************************************************************************
* Keyboard Interrupt service Routine                                     *
*                                                                        *
* Wird bei fallender Flanke auf PTA0 aufgerufen                          *
* Ruft GetByte auf und schreibt empfangene Daten in den Empfangspuffer   *
* ca 20 Takte bis Getbyte beginnt. Gebtbyte geht auf die Mitte des Bits  *
* Dadurch Verschiebung um ca 20 Takte nach hinten. bei 9600 Baud ist     *
* ein bit ca 330 Takte sollte kein Problem sein                          *
* Stopbit wird beim Empfang ignoriert, deshalb nach empfang              *
* ca 300 Takte zeit bevor nächstes Zeichen kommen kann.                  *
**************************************************************************
KbdIsr:

               pshh                     ;2 save H-reg
               sei                      ;2 keine weiteren Interrupts zulassen
               mov  #%00000010,KBIER    ;4 KB-Int disablen
               bclr PTA0,PTA            ;4initialize PTA0 for serial comms
               jsr  GetByte             ; RS232 Byte empfangen
               ldx  inptr               ; Zeiger für Empfangspuffer laden
               sta  data,x              ; und Zeichen sichern
               incx                     ; Zeiger erhöhen
               cpx  #$20                ; ende des Puffers ?
               bne  kbd1                ; nein dann weiter
               clrx                     ; sonst auf Anfang setzen
kbd1:
               stx  inptr               ; und speichern
               mov  #%00000100,KBSCR    ; ACK schreiben um alles zu clearen
               mov  #%00000001,KBIER    ; ints auf PTA0 wieder zulassen
               cli                      ; ints wieder erlauben
               pulh                     ; H-Reg zurückholen
               rti





und mit getchar den Puffer auslesen und weiterverarbeiten :

Download Code  Code

**************************************************************************
* getchar                                                                *
*                                                                        *
* holt das nächste Zeichen aus dem Puffer und gibt es im akku zurück     *
*                                                                        *
**************************************************************************

getchar:

                pshx                ; x-reg sichern
getch1
                ldx  outptr         ; Ausgabezeiger im Empfangspuffer
                cpx  inptr          ; Mit eingabezeiger vergleichen
                beq  getch1         ; beide gleich dann ist nix da
                lda  data,x         ; sonst in akku laden
                incx                ; index erhöhen
                stx  outptr         ; und ausgabezeiger speichern
                cpx  #20            ; ende des puffers ?
                bne  getchend       ; nein dann raus
                clr  outptr         ; sonst zeiger auf Anfang des Puffers setzen
getchend:
                pulx                ; x-reg zurückholen
                rts                 ; und zurück







Das paßt dann vielleciht besser .


Eckhard
 
norticum
Vielen Dank! Ich werd mir das mal ansehen und die Zeilen die relevant für mich sind mal markieren. Da ja der QY4 zumal keinen UART hat.

Vielen Dank nochmal,

norticum
It´s not a bug!
It´s a feature!
 
norticum
Hallo!

Ich hab mir den Code angesehen. Momentan stecke ich an der Subroutine "Getbyte" fest. Die ist nirgends zu finden. Anhand dieser könnte ich sehen wohin eingehende Zeichen gespeichert werden.


norticum
It´s not a bug!
It´s a feature!
 
ego
Hallo,

getbyte ist eine ROM Routine für den Software UART, die das empfangene Zeichen in A zurückliefert. Bei der Hardware SCI braucht man die nicht. Da liegt das Zeichen ja im SCDR vor. Der Teil dahinter ist eigentliche erst Interessant.

Eckhard
Bearbeitet von ego am 04-02-2009 11:15
 
Springe ins Forum:
Seitenaufbau: 0.07 Sekunden
728,908 eindeutige Besuche