ATMega8 an Serieller SS sendet Müll

#605886
Lesenswert?

Hallo zusammen,
ich habe aus dem UART-Teil des AVGCC-Tutorials mal die Routine für das 
senden eines einzelnen Zeichens auf die Serielle Schnittstelle 
ausgeliehen und versucht mittels diesen Codes meinen ATMega8 dazu zu 
bringen, P (0x50) an meinen Computer zu senden.... Das ganze in einer 
Endlosschleife, der PC empfängt auch tatsächlich jede menge 
(gleiche)zeichen, jedoch nicht P.
anstelle des P empfängt er § (0x15). wenn ich nun hingehe und versuche O 
(großes o = 0x4F) zu senden kommt wider erwarten nicht das Zeichen 
(0x14) welches einen vor §(0x15) ist, sondern aus der ganz anderen Ecke 
der ASCII Tabelle das X (0x58)....

Hier der code
1
#include "avr/io.h"
2

3

4
/* USART-Init beim ATmega16 */
5
#ifndef F_CPU
6
#define F_CPU 16000000           /* Oszillator-Frequenz in Hz */
7
#endif
8
 
9
// Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
10
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
11
 
12
#define UART_BAUD_RATE 19200
13

14

15
int main(void)
16
{
17
  /*        I/O Settings      */
18
  UCSRB |= (1<<TXEN);                 // UART TX einschalten
19
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);     // Asynchron 8N1 
20
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
21
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
22
  
23
  unsigned int i=0;
24
  
25

26
  
27
  while(1)
28
  {    
29
    // bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:
30
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
31
    {
32
      
33
    }
34
    
35
    UDR = 0x50;    // P
36
  }
37
}

kann es vll daran liegen, das in dem Tutorial der Code für einen 
ATMega16/32 ist und ich ihn auf einen ATMega8 anwende ? normal 
unterscheiden die 3 sich doch abgesehen vom Speicher nicht wirklich oder 
??


Danke
#605905
Lesenswert?

Hallo und danke für die rasche Antwort....

leider macht er immer noch das gleiche wie vorher, also das $ anstelle 
des P Senden. naja zumindest empfängt der PC das §, weiß nicht ob der µC 
das P sendet oder doch tatsächlich das §... aber ich denke das liegt am 
µC, das der mist sendet :)

Also ich arbeite mit Programmers Notepad und werfe die Programme dann 
per PonyProg rein. Als Taktquelle habe ich einen externen 16MHz Quarz.
Bei den Fuses habe ich alle Häckchen bei CKSEL entfernt, also sollte auf 
externen Takt umgestellt sein.

Hat sonst noch jemand eine Idee ??
#605909
Lesenswert?

> Als Taktquelle habe ich einen externen 16MHz Quarz.
> Bei den Fuses habe ich alle Häckchen bei CKSEL entfernt, also sollte auf
> externen Takt umgestellt sein.
Für einen Quarz darfst Du aber KEINEN externen Takt einstellen. Du 
musst auf "external Crystal/Resonator" (high Frequency, > 8 MHz) fusen. 
Sonst klappt gar nichts.

EDIT:
"Externer Takt" (external clock) bedeutet, dass ein externer Taktgeber 
(z.B. ein QuarzOSZILLATOR oder eine andere externe Taktquelle) 
dranhängt, die bereits ein "fertiges" Taktsignal liefert. Dabei wird 
durch die Fuses der im µC eingebaute Oszillator komplett abgeschaltet.

Da die Fuses in PonyProg allerdings invertiert sind, müssten die 
Einstellungen bei Dir passen (CKSEL3..0 = 1111). Der Fehler muss dann 
woanders liegen.

Aber verwechsle nie "externer Takt" mit "externer Quarz"! Steht im 
Datenblatt allerdings an einigen Stellen auch ein bisschen verwirrend 
drin...
#605936
Lesenswert?

Hi, also ich habe mir das mal runtergeldan, gefällt mir ehrlich gesagt 
auch schon besse als das von M$

jedoch empfange ich damit auch nur Mist....
Ich sende laut source-code ein 0x50, empfangen wird
ASCII: }
HEX  :7D
Dec  :125


also liegt es auch nicht am Hyperterminal, obwohl ich da auch was 
anderes empfange (§ statt 0x50)
#605940
Lesenswert?

hmm also komischer Effekt ist nun, das wenn ich auf stopp klicke, kurz 
darauf auf start, das dann unterschiedliche daten empfangen werden.....

beim ersten mal war es:
ASCII: }
HEX  :7D
Dec  :125
dann plötzlich
ASCII: -
HEX  :5F
Dec  :095

dann wieder
ASCII: }
HEX  :7D
Dec  :125


????? was ist los mit der verrückten Computerwelt ?
Gast #605956
Lesenswert?

>das dann unterschiedliche daten empfangen werden.....

Kann passieren wenn die Zeichen ununterbrochen kommen, dann kann es 
passieren, dass der PC das Startbit nicht mehr korrekt finden kann.

Hast du einen USB/Seriell-Adapter dran? Dual-Core CPU? Das kann auch 
Probleme machen, besonders wenn mehrere Adapter gleichzeitig laufen.
#605972
Lesenswert?

Mach da
1
/* USART-Init beim ATmega16 */
2
#ifndef F_CPU
3
#define F_CPU 16000000           /* Oszillator-Frequenz in Hz */
4
#endif

mal
1
/* USART-Init beim ATmega16 */
2
#define F_CPU 16000000           /* Oszillator-Frequenz in Hz */

draus.
Also ohne das #ifndef / #endif.
Wer weiss, welche CPU Frequenz dem Compiler über das Makefile
vorgegeben wird.
#605981
Lesenswert?

Studiologe .-. wrote:
> wo finde ich denn die Project Option  ???
Lass Dir nix erzählen. Die Configuration Options gibts nur im AVRStudio, 
mit dem Du ja nicht arbeitest. Du müsstest, wenn überhaupt, dann im 
Makefile die Änderungen direkt machen. Aber die Methode von Karl Heinz 
ist für Deine Einstellungen sicher die sicherste.
#605994
Lesenswert?

BTW:
Wenn bei solchen Sachen irgendwas nicht klappt, ist es IMMER sinnvoll, 
als erstes alle Makros, die irgendwelche kritischen Werte berechnen oder 
angeben (in diesem Falle gilt das besonders für UART_UBRR_CALC und 
F_CPU), rauszuschmeißen und die Register zumindest probeweise von Hand 
zu setzen. Also in diesem Falle alle #defines weg und ins UBRR den 
errechneten Wert (also hier 51, wie ja oben irgendwo schon mal erwähnt) 
reinschreiben.
#605998
Lesenswert?

Studiologe .-. wrote:
> hmm also zu F_CPU finde ich garnichts im Makefile, sollte also daher
> egal sein oder ?
Den Fall hatten wir neulich schon mal. Da war es zwar ein vom AVRStudio 
erstelltes Makefile, in dem ohne eine explizite Angabe bei den 
Configuration Options auch kein F_CPU-Wert zu finden war (ansonsten 
gleicher Aufbau wie bei Dir mit #ifndef F_CPU...). Klappen tat es aber 
nur mit einer Eingabe des korrekten Frequenzwertes in den Configuration 
Options vom AVRStudio (und damit im Makefile).

> Hat auf jeden Fall auch nicht den gewünschten Effekt gebracht :(
Wie gesagt, schmeiß das #ifndef...#endif raus. Dann muss der Compiler 
auf jeden Fall den angegebenen Wert nehmen. Oder, wie oben gesagt, alles 
direkt eingeben. Oder dem F_CPU für Code-interne Anwendungen einen 
anderen Namen verpassen...
#606007
Lesenswert?

Also gut habe jetzt mal alles ins folgende geändert, was leider auch 
nicht geholfen hat....
im Makefile habe cih auch ATMega8 reingeschrieben statt ATMega16, half 
auch nicht :(
1
#include "avr/signal.h"
2
#include "avr/io.h"
3

4
int main(void)
5
{
6
  /*        I/O Settings      */
7
  UCSRB |= (1<<TXEN);                 // UART TX einschalten
8
    UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);     // Asynchron 8N1
9

10
  
11
  unsigned int i=0;
12
  
13

14
  
15
  while(1)
16
  {    
17
    // bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:
18
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
19
    {
20
      
21
    }
22
    
23
    UDR = 0x50;    // P
24
    
25
  }
26
}
#606011
Lesenswert?

Thilo M. wrote:
>>UCSRC |= (1<<URSEL)|(3<<UCSZ0);
>
> URSEL sollte low sein. Mit high schreibst du in UCSRC, nicht in UBRRH.
> Kommentiere diese Zeile einfach mal aus.
Hallo? Genau das will er doch! Da steht explizit, dass UCSRC geschrieben 
werden soll!

Es kann eigentlich tatsächlich nur am Makefile liegen. Wenn da der 
falsche µC-Typ drinsteht, ist die Wahrscheinlichkeit für ein 
Nicht-Funktionieren sehr groß.
#606047
Lesenswert?

Studiologe .-. wrote:
> Pegelwandler ? ähhh hmmm also ich glaube daran liegts, ist nämlich
> keiner dran....
Autsch! Das erklärt einiges. Man sollte Dich...

> wie sieht denn sowas aus ? also bisher gehe ich noch direkt dran, wird
> auch der fehler sein.... oder ?
Google mal nach MAX232. Im AVR-GCC-Tutorial steht übrigens an der 
entsprechenden Stelle auch etwas über die Pegel!
#606062
Lesenswert?

Studiologe .-. wrote:
> wo kann ich denn das UCPOL bit setzten ?
> einfach über UCPOL = 1; ??
> steht so zumindest im datenblatt
Ich frage mich langsam, ob Du Dich überhaupt ernsthaft mit der Materie 
beschäftigt hast, oder ob Du einfach nur hirnlos Code kopiert hast, ohne 
ihn zu verstehen.

Wie setzt Du denn in "Deinem" Code oben die Bits in den Steuerregistern? 
Aha! Und genau so wird auch das UCPOL behandelt...
Gast #606124
Lesenswert?

@ Thilo M. (power)

>Hast du einen USB/Seriell-Adapter dran? Dual-Core CPU? Das kann auch
>Probleme machen, besonders wenn mehrere Adapter gleichzeitig laufen.

???
Schon wieder 1. April? Duo-Core CPU von USB-RS232 Adaptern überlastet? 
Ist die Software für Duo-core Unterstützung soooo schlecht?

MfG
Falk
Gast #606139
Lesenswert?

Hi Falk,
nee, wir hatten auf Arbeit neue Laptops angeschafft (Dualcore), mit 
denen konnten wir unsere Messumformer per RS232 nicht mehr 
parametrieren. Laut Softwareprogrammiere liegt's am Dualcore, warum auch 
immer.
Mit den Adaptern hatte ich selbst schon Probleme, wenn zwei Adapter sich 
einen Treiber teilten gab es schwere Timingprobleme, mehrere Bytes 
wurden 'verschluckt' und beim nächsten Ansprechen kamen die auf einmal.
Das Problem ist nicht aus der Luft gegriffen, hat schon seinen Grund 
warum ich gefragt habe.
#606148
Lesenswert?

Sowas gibt's wirklich. Dass Device-Driver an einem Multiprozessorsystem 
scheitern. Auch schon auf einem alten P4 mit Hyperthreading oder einem 
Pentium-Pro Doppelprozessorsystem. Weil der Programmierer zu blöd war 
das zu berücksichtigen, oder dessen Arbeitgeber zu knauserig ihm eine 
entsprechende Kiste hinzustellen. Konnte einem auch vor 2 Jahren noch 
bei einer USB-Adapterkarte von Adaptec(!) passieren.
Gast #606178
Lesenswert?

@ Thilo M. (power)

>nee, wir hatten auf Arbeit neue Laptops angeschafft (Dualcore), mit
>denen konnten wir unsere Messumformer per RS232 nicht mehr
>parametrieren. Laut Softwareprogrammiere liegt's am Dualcore, warum auch
>immer.

Das ist ein Witz. Wenn gleich ein schlechter. :-(
So ein lausiges 1200 Baud Protokoll scheitert an High-Tec? Und warum. 
Weil garantiert mal wieder jemand irgendwelche Zählschleifen zur 
"Timinganpassung" verwendet.

>Mit den Adaptern hatte ich selbst schon Probleme, wenn zwei Adapter sich
>einen Treiber teilten gab es schwere Timingprobleme, mehrere Bytes
>wurden 'verschluckt' und beim nächsten Ansprechen kamen die auf einmal.

Schnittstelle entweder schlecht geschrieben oder verwendet.
Naja, thats life.

MfG
Falk
#606185
Lesenswert?

> Weil garantiert mal wieder jemand irgendwelche Zählschleifen zur
> "Timinganpassung" verwendet.

Das dürfte aus der Mode sein. Eher schon weil er übersehen hat, dass bei 
einem Multiprozessorsystem der Code des Treibers in mehreren 
Prozessen/Threads gleichzeitig laufen kann.
Gast #606193
Lesenswert?

@ Andreas Kaiser (a-k)

>> Weil garantiert mal wieder jemand irgendwelche Zählschleifen zur
>> "Timinganpassung" verwendet.

>Das dürfte aus der Mode sein.

1.) Darauf würde ich nciht wetten.
2.) War die Software wahrscheinlich schon älter.

> Eher schon weil er übersehen hat, dass bei
>einem Multiprozessorsystem der Code des Treibers in mehreren
>Prozessen/Threads gleichzeitig laufen kann.

Und? Was änders sich da aus Sicht des Programmierers einer Anwendung? 
Ich würde erstmal sagen GAR NCIHTS! Die LOGISCHE Abfolge MUSS 100% 
identisch sein. Und wenn das Timing sauber über Timer, Flags etc. 
gemacht ist darf da auch GAR NICHTS anbrennen. Wenn, ja wenn . . .

MfG
Falk

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren