Forum: Compiler & IDEs Serielle, Hyperterminal


von Birgit (Gast)


Lesenswert?

Habe folgende Probleme mit der Seriellen bzw. dem Hyperterminal:
Verwende das Crumb8USB-Board (Dev.board mit einem ATmega8) und verbinde 
mich dabei mittels USB-Kabel zum PC. Den zugehörigen Treiber hab ich 
installiert. Das folgende Programm müsste doch funktionieren, wenn ich 
ein Zeichen im Hyp.terminal runterschicke und anschließend ein Zeichen 
(0x02) zurückbekomme, oder? wo hab ich den Fehler eingebaut?
1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
6
#define USART_RXC_vect      _VECTOR(11)
7
8
#ifndef F_CPU
9
#define F_CPU 1000000 /* Oszillator-Frequenz in Hz */
10
#endif
11
12
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1) //Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
13
#define UART_BAUD_RATE 9600
14
15
16
17
volatile uint16_t control_sign;      //Steuerzeichen (Protokoll) von SS
18
19
20
void Send(int sign)
21
{
22
  while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich, Usart Data Register Empty (!!) */
23
  UDR = sign; /* schreibt das Zeichen x auf die Schnittstelle */
24
}
25
26
27
ISR(USART_RXC_vect)
28
{
29
  control_sign = UDR; //?????
30
  Send(0x02);
31
}
32
33
void init_serial()
34
{
35
  //Serielle:
36
  //Baudrate: 9600
37
  //Frame: 8 Datenbits, 1 Stoppbit, 1 Parity (even)
38
  
39
  cli(); //Nur während der Initialisierung der Seriellen SS
40
  
41
  UCSRB |= (1<<TXEN) | (1<<RXEN) | (1<<RXCIE);  // UART TX und RX einschalten, RX Complete Interrupt Enable
42
    UCSRC |= (1<<URSEL)|(1<<UCSZ1) | (1<<UCSZ0) | (1<<UPM1) |(0<<UPM0); //Frameeinstellungen
43
  
44
  //Baudrate
45
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
46
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
47
  /* alternativ bei der avr-libc "direkt 16bit" : */
48
  //UBRR = UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
49
50
  sei(); //Global Interrupt Enable
51
}
52
53
54
55
int main()
56
{
57
58
  PORTD &= ~(1<<PD0) & ~(1<<PD1);
59
  DDRD |= (1<<PD1);   
60
  DDRD &= ~(1<<PD0);
61
    
62
  PORTC &= ~(1<<PC0);
63
  DDRC |= (1<<PC0);
64
  PORTC |= (1<<PC0);
65
  
66
  init_serial();
67
  
68
  for(;;);
69
70
}

danke
Birgit

von Joerg X. (Gast)


Lesenswert?

Das Problem ist bestimmt die Baudrate (wenn 9600, 8E1 überhaupt das ist, 
was du willst), schau mal in die Tabelle im Datenblatt mit den 
UBRR-Beispielen (Tipp: Abweichungen von mehr als 2% funktieren kaum). 
und überleg, ob du für dem Atmega nicht besser einen (Baudraten-) Quarz 
nimmst, der interne RC-Oszillator ist Glückssache (+- 3%)

ps.: das "#define USART_RXC_vect" ist sinnlos (steht ja auch genauso in 
der iom8.h, die der Compiler einbindet)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> #define USART_RXC_vect      _VECTOR(11)

Wofür soll das denn gut sein?

von Birgit (Gast)


Lesenswert?

will sehr wohl die 9600 Baud mit dem internen RC-Oszillator verwenden. 
mach ich vielleich einen Fehler mit dem hyperterminal? stimmt ansich der 
code??

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Joerg X. wrote:

> schau mal in die Tabelle im Datenblatt mit den
> UBRR-Beispielen (Tipp: Abweichungen von mehr als 2% funktieren kaum).
> und überleg, ob du für dem Atmega nicht besser einen (Baudraten-) Quarz
> nimmst, der interne RC-Oszillator ist Glückssache (+- 3%)

Naja, sie sollte noch U2X setzen und dann in der Formel durch 8 statt
16 teilen, dann gibt's keinen Grund, warum das nicht zumindest erst
einmal bei Vcc = 5 V (Werkskalibrierung des RC-Oszillators) nicht
funktionieren würde.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Birgit wrote:

> mach ich vielleich einen Fehler mit dem hyperterminal?

Hyperterminal ist verrufen.  Ich nehme aber kein Windows, ich kann dir
da zu nicht viel aus eigener Erfahrung raten.

> stimmt ansich der code?

Vom groben Drübergucken stimmt er.

von Karl H. (kbuchegg)


Lesenswert?

Jörg Wunsch wrote:
> Birgit wrote:
>
>> mach ich vielleich einen Fehler mit dem hyperterminal?
>
> Hyperterminal ist verrufen.  Ich nehme aber kein Windows, ich kann dir
> da zu nicht viel aus eigener Erfahrung raten.

Für ein Terminal ist das gar nicht so schlecht.
Wenn es richtig konfiguriert ist, macht es eigentlich
alles was ich von einem Terminal erarten würde.

@Birgit

Ich würde aber kein
  Send (0x02);

machen. 0x02 ist ein Steuerzeichen, dass von Hyperterminal
nich angezeigt wird. Lass dir doch einfach mal
ein 'x' zurückschicken (oder noch besser: Das Zeichen
das empfangen wurde).

von yalu (Gast)


Lesenswert?

Wenn du den internen RC-Oszillator verwenden möchtest, musst du beim
Programmstart das Calibration-Byte in das OSCCAL-Register schreiben.
Nur dann und nur bei 5 V Betriebsspannung läuft der Oszillator
innerhalb der im Datenblatt angegebenen Toleranz. Ohne das Beschreiben
des OSCCAL-Registers ist die Frequenzabweichung viel zu groß, um damit
RS-232 machen zu können.

Das Calibration-Byte steht bei nagelneuen (noch nie gelöschten) AVRs
am Ende des Flash-Speichers und kann vom Programm ausgelesen werden.
Ansonsten (d.h. in den meisten Fällen) muss es über das
Programmiergerät aus einem für das Programm unzugänglichen
Speicherbereich gelesen und entweder direkt in den Flashspeicher
zurückgeschrieben oder in den Sourcecode eingetragen werden.

Wie das Calibration-Byte per ISP-Programmer gelesen wird, verrät die
die Bedienungsanleitung desselben bzw. der zugehörigen PC-Software.

von yalu (Gast)


Lesenswert?

Quatsch!

Ich nehme alles zurück, was ich irrigerweise in meinem vorigen Post
geschrieben habe. Der ATmega8 lädt das Calibration-Byte automatisch
beim Reset. Lediglich bei älteren AVRs (zb.B: ATtiny15L) muss der
Programmierer noch selbst dafür sorgen.

von Rolf Magnus (Gast)


Lesenswert?

Wenn's unbedingt mit R/C-Oszillator sein soll, dann sollte man die 
Oszillatorfrequenz trotzdem nochmal nachkalibirieren. Ich hab das mal 
gebraucht, als ich nicht extra für ein paar Debug-Ausgaben während der 
Entwicklung einen Quarz einbauen wollte.
Einfach ein kleines Testprogramm schreiben, das z.B. einmal pro Sekunde 
blinkt. Das läßt man für eine Minute laufen und zählt, wie oft es 
geblunken hat. Dann versucht man das Spielchen so oft mit entsprechend 
verändertem OSCCAL, bis man möglichst nahe am richtigen Wert ist.
Ich habe schon erlebt, daß ohne diese Maßnahme nur Datenmüll ankam.

> Nur dann und nur bei 5 V Betriebsspannung läuft der Oszillator
> innerhalb der im Datenblatt angegebenen Toleranz.

Auch die Temperatur spielt eine Rolle. Die Werte gelten für +25°C.

> Der ATmega8 lädt das Calibration-Byte automatisch beim Reset.

Wobei es sich immer um das für 1Mhz handelt. Wenn man ihn mit einem 
anderen Takt betreibt, muß man OSCCAL manuell laden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf Magnus wrote:

> Wenn's unbedingt mit R/C-Oszillator sein soll, dann sollte man die
> Oszillatorfrequenz trotzdem nochmal nachkalibirieren.

Bei den neueren AVRs ist der RC-Oszillator recht gut geworden.  Dort
bekommt man sogar noch eine benutzbare RS-232-Kommunikation ohne
Nachkalibrieren, wenn man von 5 V auf 3 V runtergeht.  (Mit einem
ATmega128 hat das nie funktioniert, mit einem ATmega1281 praktisch
immer.)

Cliff Lawson hat auf avrfreaks.net mal eine interessante Version
beschrieben (wobei ich nicht weiß, ob er auch den Code veröffentlicht
hat): der Benutzer muss zu Beginn der Kommunikation ein paar Mal
<Enter> drücken, das gibt ein Zeichen 0x0d (carriage return).  Dessen
Bitzeiten misst er dann und kalibriert danach den RC-Oszillator nach.

>> Der ATmega8 lädt das Calibration-Byte automatisch beim Reset.

> Wobei es sich immer um das für 1Mhz handelt. Wenn man ihn mit
> einem anderen Takt betreibt, muß man OSCCAL manuell laden.

Auch hier sind die neueren AVRs im Vorteil: die haben nur noch einen
RC-Oszillator.  Der schwingt auf 8 MHz, wird aber im
Auslieferungszustand via CKDIV8 und CLKPR auf 1 MHz geteilt.  Damit
gibt's aber auch nur noch ein Kalibrierungsbyte, das wird beim
power-on automatisch geladen.

von Rolf Magnus (Gast)


Lesenswert?

Es gibt sogar eine Appnote, die sich nur mit den verschiedenen in AVRs 
verbauten Oszillator-Varianten beschäftigt. Ich glaube, es gibt 
mittlerweile 4 oder 5 verschiedene.

von Frank J. (frajo)


Lesenswert?

Die Butterfly Programme arbeiten oft auch mit einer Kalibrierung durch 
den Uhrenquarz. Auf http://butterflylogger.sourceforge.net/ wurde der 8 
MHz Oszillator auf 7.3728 MHZ getrimmt um mit 115200bps zu 
kommunizieren. Ich hab's probiert und kann die kompletten Daten aus dem 
Dataflash ohne Störung übertragen. Der Butterfly lief schon mehrere Tage 
ohne Neustart (und erneutes Kalibrieren) mit drei AA Batterien bei 
unterschiedlichsten Temperaturen. Keine Probleme mit dem UART Timing. 
Terminal Programm war SuperTerm 2.14.

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.