Forum: Mikrocontroller und Digitale Elektronik Hyperterminal lääst LED's springen


von Anfänger (Gast)


Lesenswert?

Guten Tag,

ich möchte gern vom HyperTerminal aus meine LED's am PORTC durch 
Eingaben wie "0b11101100" ansteuern. Jedoch werden die eingegebenen 
Muster nicht korrekt übertragen und schon allein durch Tippen der 
Leertaste springen die LED's wie wild herum. Das man solche Sachen 
irgendwie Filtern muss ist mir bewusst, nur worum es hier eigentlich 
geht ist, dass die Muster nich korrekt wiedergegeben werden.
1
#include <avr/io.h>
2
#include <stdlib.h>
3
4
#define F_CPU 16000000UL  // Systemtakt in Hz - Definition als unsigned long beachten
5
#define BAUD 9600UL      // Baudrate
6
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
8
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
9
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
10
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
11
#endif
12
#include "util/delay.h"
13
14
uint8_t uart_getc(void)
15
{
16
  while (!(UCSR0A & (1<<RXC0)));   // warten bis Zeichen verfuegbar
17
    
18
  return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
19
}
20
21
int uart_putc(unsigned char c)
22
{
23
  while(!(UCSR0A & (1<<UDRE0)))
24
  {
25
    
26
  }
27
  _delay_ms(100);
28
  UDR0= c;
29
}
30
31
void uart_puts (char *s)
32
{
33
  while (*s)
34
  {   
35
    
36
    uart_putc(*s);
37
    s++;
38
  }
39
}
40
  
41
42
int main(void)
43
{
44
  UBRR0H = UBRR_VAL >> 8;
45
  UBRR0L = UBRR_VAL & 0xFF;
46
47
  UCSR0C=(0<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01); //Asynchroner Mode, 8-bit
48
  UCSR0B= (1<<TXEN0)|(1<<RXEN0);              //Transmitter einschalten
49
  
50
  uart_puts("Bereit zum Empfangen von Daten""\n");
51
52
  while(1)
53
  {
54
    
55
  
56
57
        if ( (UCSR0A & (1<<RXC0)) )
58
        {
59
          uint8_t c;
60
          c = uart_getc();
61
          DDRC = 0xFF; 
62
          PORTC = c;
63
      _delay_ms(200);
64
        }
65
        else
66
        {
67
68
        }
69
70
  }
71
}
Meine Einstellungen im HyperTerminal: BAUD 9600, 8-bit, keine Parität, 1 
Stoppbit, keine Flusssteuerung. Mein Prozessor ist ein ATmega8 und das 
Senden von Daten an den PC funktioniert einwandfrei.

Vielen Dank schonmal!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Naja, Du wertest diese Nummer, die Du Dir da vorstellst, auch in keiner 
Weise aus, sondern Du gibst jedes empfangene Zeichen direkt an Deinen 
Port C aus:
1
          c = uart_getc();
2
          DDRC = 0xFF; 
3
          PORTC = c;

Das Muster, das Du dann mit Deinen LEDs angezeigt bekommst, entspricht 
dem von Dir getippten Zeichen.

Wenn Du die Leertaste drückst, ist das 0x20, bzw. 0010 0000
Bei einer 0 ist das 0x30, bzw. 0011 0000

Und bei einem 'b' ist das 0x62, bzw. 0110 0010

Übrigens ist es nicht nötig, für jedes empfangene Zeichen DDRC erneut zu 
setzen, das genügt genau einmal am Anfang.

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:
> Guten Tag,
>
> ich möchte gern vom HyperTerminal aus meine LED's am PORTC durch
> Eingaben wie "0b11101100" ansteuern.

?

Willst du tatsächlich 0b11101100 eingeben. Also
Die Taste '0' drücken.
Die Taste 'b' drücken.
Die Taste '1' drücken.
etc. etc.


Wenn ja, dann erzeugst du auf die Art erst mal einen String. Eine 
Abfolge der Zeichen '0', 'b', '1', '1' ....

Die musst du natürlich auch so auf dem AVR empfangen, wieder zu einer 
Zahl zusammensetzen und erst dann kannst du damit auf den Port gehen.

> Jedoch werden die eingegebenen
> Muster nicht korrekt übertragen

Wenn deine UART funktioniert, werden die schon korrekt übertragen. Das 
Problem ist nur, dass dir nicht wirklich klar ist, was da eigentlich 
übertragen wird.

> und schon allein durch Tippen der
> Leertaste springen die LED's wie wild herum.

Logisch. Die Leertaste hat den ASCII Code 0x20. In Binärer SChreibweise 
ist das 0b00100000

Jedes Zeichen hat einen bestimmten ASCII Code. Wenn du das empfangene 
Byte einfach auf den Port gibst
1
          c = uart_getc();
2
          PORTC = c;

dann zeigen dir die LED genau diesen Code des gerade empfangenen 
Zeichens an.

Siehe ASCII Tabelle

Auf einer UART werden komplette Bytes übertragen. Keine einzelnen 
Bits(*). Jedes Zeichen, jede Taste, hat einen bestimmten Bytewert je 
nach Code-Tabelle, die heutzutage meistens die ASCII Tabelle ist.


Edit:
(*) Natürlich werden da einzelne Bits übertragen. Schliesslich besteht 1 
Byte ja aus 8 Bits. Gemeint ist, dass du beim Sender nicht einfach nur 1 
Bit auf den Weg schickst, sondern dass da immer 1 Byte rausgeht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.