www.mikrocontroller.net

Forum: Compiler & IDEs Serielle, Hyperterminal


Autor: Birgit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define USART_RXC_vect      _VECTOR(11)

#ifndef F_CPU
#define F_CPU 1000000 /* Oszillator-Frequenz in Hz */
#endif

#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1) //Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
#define UART_BAUD_RATE 9600



volatile uint16_t control_sign;      //Steuerzeichen (Protokoll) von SS


void Send(int sign)
{
  while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich, Usart Data Register Empty (!!) */
  UDR = sign; /* schreibt das Zeichen x auf die Schnittstelle */
}


ISR(USART_RXC_vect)
{
  control_sign = UDR; //?????
  Send(0x02);
}

void init_serial()
{
  //Serielle:
  //Baudrate: 9600
  //Frame: 8 Datenbits, 1 Stoppbit, 1 Parity (even)
  
  cli(); //Nur während der Initialisierung der Seriellen SS
  
  UCSRB |= (1<<TXEN) | (1<<RXEN) | (1<<RXCIE);  // UART TX und RX einschalten, RX Complete Interrupt Enable
    UCSRC |= (1<<URSEL)|(1<<UCSZ1) | (1<<UCSZ0) | (1<<UPM1) |(0<<UPM0); //Frameeinstellungen
  
  //Baudrate
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
  /* alternativ bei der avr-libc "direkt 16bit" : */
  //UBRR = UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );

  sei(); //Global Interrupt Enable
}



int main()
{

  PORTD &= ~(1<<PD0) & ~(1<<PD1);
  DDRD |= (1<<PD1);   
  DDRD &= ~(1<<PD0);
    
  PORTC &= ~(1<<PC0);
  DDRC |= (1<<PC0);
  PORTC |= (1<<PC0);
  
  init_serial();
  
  for(;;);

}

danke
Birgit

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define USART_RXC_vect      _VECTOR(11)

Wofür soll das denn gut sein?

Autor: Birgit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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??

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.