Hallo,
ich bin gerade dabei einen C-Code für den Atmega32 auf einen Atmega168A
anzupassen.
Ich habe die Register und Bitnamen dem Datenblatt angepasst, der
Compiler gibt keine Warnung und keinen Fehler zurück. Ich verwende genau
wie beim Mega32 einen externen 8MHz Quarz.
Nun funktioniert meine UART Übertragung nicht. Mit dem Mega32
funktioniert es prima. Ich nutze das Pollin-Evaluationsboard Version
2.0.1 und gehe davon aus, dass die Beschaltung stimmt.
Gibt es irgendwelche Stolperfallen bzw. Tricks die bei der Portierung
der UART-Routine vom Mega32 zum Mega168A zu beachten sind?
Hatte jemand von euch bereits das Problem?
MFG Martin
Hast Du eventuell die beiden Ports vertauscht?
Ansonsten habe ich neben den anderen register-Namen noch diese
Unterscheidung in meinen Programmen, damit sie auf beiden Chips laufen:
// framing format 8N1
#ifdef URSEL
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
#else
UCSRC = (1<<UCSZ1) | (1<<UCSZ0);
#endif
@Stefan: Habe jetzt die Änderungen ebenfalls so angelegt, dass es mit
beiden µCs laufen sollte.
Mit dem Atmega32 läufts super - ich empfange die richtigen Daten im
Hterm. Aber mit dem 168 wills nich laufen :-(
Könntest du mir eventuell deinen Code bzw. einen UART-Auszug zur
Verfügung stellen, damit ich meinen Fehler suchen kann ?
> Gibt es irgendwelche Stolperfallen [..] die [..] zu beachten sind?
Größte Stolperfalle ist wie üblich, den Code nicht oder nicht
vollständig zu zeigen. Passiert leider immer wieder. Die zweitgrößte
Stolperfalle ist eine ungenaue Fehlerbeschreibung wie
> Nun funktioniert meine UART Übertragung nicht.
HTH und nix für ungut
Martin schrieb:> ja das hab ich auch in meinem Code berücksichtigt.
Das würde auch gar nicht kompilieren und stammt ja auch nicht von dir.
Aber es ist einfach nur schlampig und der Compiler verzeiht keine
Schlamperei.
Martin schrieb:> UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
Da liegt dein Fehler auch nicht. Das ist die mit Abstand unwichtigste
Einstellung. Denn der Registerwert ist der gleiche wie nach Reset.
Für eine normale UART-Übertragung müssen beim 168er nur das
UCSR0B-Register und die Baudrate eingestellt werden. Evtl. noch das U2X0
in UCSR0A zur Baudratenverdoppelung.
mfg.
Hallo,
danke an alle die sich bisher die Mühe gemacht haben, zu antworten.
Die UART-Übertragung ist mittlerweile kein Problem mehr. Es war vielmehr
das Problem mit der Umleitung von printf.
Anbei habe ich den angepassten Quellcode (stammt ursprünglich aus dem
Artikel Versenden von SMS mittels Mobiltelefon).
Ich habe in den Code noch den Beschleunigungssensor BMA020 eingebunden,
was aber nichts mit dem Problem zutun haben sollte, dieser funktioniert
einwandfrei.
Ich programmiere im AVRStudio 5 und habe "optimize -O1" für die delay.h
eingestellt.
Der Code wird, je nach Device-Einstellung (ATmega32 oder ATmega168A) im
AVRStudio, fehler- und warnungsfrei übersetzt.
Wenn ich mir das ganze im Hterm betrachte, dann sehe ich mit dem
ATmega168A gar nichts. Mit dem Mega32 werden die Daten richtig
übertragen (siehe Bild: Original_fdevopen_M32).
Wie der Bildname vermuten lässt, habe ich dann die Stdio-Umleitung mit
fdevopen gegen die stdout-Variante aus dem AVR-GCC-Tutorial ersetzt.
1
//in sms.c
2
uart_init();
3
fdevopen(uart_sendc,uart_receive);
1
// in uart.c
2
intuart_sendc(charc,FILE*dummy)
3
{
4
while(!(UCSRA&(1<<UDRE))){}// warten bis Senden möglich
Das Ergebnis der neuen Variante ist, dass es tadellos mit dem Mega32
funktioniert (siehe Bild SMSAlarm_stdout_M32), jedoch nichts mit dem
Mega168 zu sehen ist.
Schiebe ich jetzt den folgenden Teil in die sms.c -> sms_init()
// Initialisierung der seriellen Schnittstelle Asynchron
10
uart_init();
11
// öffnet Kanal für printf
12
stdout=&mystdout;
13
//fdevopen (uart_sendc, uart_receive);
14
15
...
dann erhalte ich mit dem Mega168 erste Lebenszeichen in Hterm (siehe
Bild SMSAlarm_stdout_M168A). Die Daten werden aber immer noch nicht
korrekt übertragen.
Jetzt meine Fragen :-)
Kann das sein, dass in dem Original-Code veraltete Stellen sind, die auf
dem Mega168 Probleme bereiten?
Oder kommt mein Compiler nicht mit dem Code klar?
Wenn ich die Funktionen:
uint8_t sms_check_nr(char* telnr_in)
SMS_MSG sms_state_machine(void)
uint8_t sms_cmdset(uint8_t dat)
auskommentiere, dann sehen die Daten im Hterm schon ganz in Ordnung aus.
Das Problem ist jetzt, dass die Nachrichten, die den Funktionen
sms_send() und sms_display_text() übergeben werden, nicht berücksichtigt
werden :-(
Ich bin bald am verzweifeln und hoffe jemand von euch kann mir da
weiterhelfen.
In der SMSALARM_angepasst_M168.zip ist der aktuelle C-Code der von mir
bis hier hin geschrieben bzw. abgeändert wurde.
Gruß Martin
Hallo,
ich glaube ich konnte die Probleme nun noch weiter eingrenzen:
Kann es sein, dass ich mit strlen(nachricht) und printf Probleme beim
compilieren kriege?
Ich vermute, dass durch das Strlen im folgenden Code-Stück Probleme
auftauchen:
Martin schrieb:> Kann es sein, dass ich mit strlen(nachricht) und printf Probleme beim> compilieren kriege?
Ich denke eher, dass du noch Fehler im Progamm hast, die dir vorher
nicht aufgefallen sind, bzw. die sich nicht bemerkbar gemacht haben.
'Funktioniert auf einem Mega8' ist KEIN Beweis für ein fehlerfreies
Programm.
Warum gehst du nicht schrittweise vor?
Teste doch erst mal nur die UART allein. Verkabel sie mit deinem PC und
schreib dir ein Testprogramm welches die UART für sich alleine testet,
indem sie endlos zb ein Zeichen an den PC schickt.
int main()
{
uart_init();
while( 1 )
uart_putc( 'x', NULL );
}
und dann geht es weiter, indem du sukzessive Teile aus deinem
vorhandenen Programm übernimmst. WObei es nicht schaden kann, wenn man
über den jeweiligen Teil noch mal drüber liest und gezielt nach
Problemstellen sucht.
Gegen 'ich bin bald am verzweifeln' hilft nur systematisches Vorgehen.
Was nicht funktioniert: planlos herumprobieren weil man denkt: dort hat
es ja auch funktioniert. Immer daran denken: Durch testen kann man nicht
die Abwesenheit von Fehlern feststellen sondern immer nur die
Anwesenheit. Nur weil ein Programm scheinbar funktioniert, heißt das
nicht, dass es fehlerfrei wäre.
Die UART und printf-Umleitung funktionieren jetzt.
Ich habe dasselbe Programm auf dem Mega168 und dem Mega32. Nur der
Inhalt der strings, die von sms_display_text() und sms_send()
(Mega168)gesendet werden stimmen nicht mit denen vom Mega32 überein.
Ich krieg's einfach nicht hin :-(
Meine letzte Aussage muss ich leider zurückziehen, die Übertragung eines
einzelnen Zeichens über UART funktioniert, nur die Umleitung will nicht
so wie ich will.
Mit
1
fdevopen(uart_sendc,uart_receive)
funktioniert es auf dem Mega32 und das Handy empfängt die Daten, aber
auf dem Mega168 gehts nicht. Sobald ich die Variante aus dem
AVR-GCC-Tutorial nehme, tut sich etwas am Mega168, aber nicht so wie es
sein soll.
Der Compiler macht alles fehlerfrei, aber im Terminal ist nichts zu
sehen.
Was habe ich nicht beachtet oder was mache ich grundsätzlich falsch?
MfG Martin