Hi
Kann mir jemand sagen was für Flags gesetzt werden, wenn auf der
seriellen Schnittstelle Daten daherkommen?
Ich möchte in einer while(1) schleife Strings einlesen. (Aber nur dann
einlesen wenn welche daherkommen).
Kann mir jemand ein Teilfragment vom einlesen eines Strings posten?
mfg
Atmega 64.
Hier meine Problembeschreibung:
Ich möchte mit dem Atmega64 SMS lesen und versenden können.
Dafür würde ich ja wie immer uart_gets() benutzen um etwas vom modem
einzulesen.
Jedoch weiß ich ja nicht wann eine sms eintrifft und um dies zu erkennen
müsste der µC ja permanent an der seriellen Schnittstelle auf text
warten.
Dies wäre mit dem aufruf von uart_gets() erledigt, da die funktion erst
beendet wird wenn die max string länge erreicht wurde oder ein string
endzeichen erkannt wird.
eine ausgabe vom modem wäre z.B. +CMTI:"SM",3 diese zeile sagt mir das
eine neue sms im speicherbereich 3 gespeichert wurde.
die darauf folgende antwort vom µC wäre dann (öffne SMS 3)-->AT+CMGR=3.
folglich wird der inhalt der sms ausgegeben mit dem sich dann arbeiten
ließe.
mein problem ist nun:
nach dem aufruf der funktion uart_gets() wartet der µC auf zeichen.
falls aber keine sms eintrifft, empfängt der µC keine zeichen vom modem,
wartet bis ins nächste jahrhundert und beendet die uart_gets()
funktion nicht um mit dem programm fortzufahren.
kurz gesagt in zwei fällen soll reagiert werden:
wenn sich pinX verändert und wenn eine sms mit befehl eintrifft.
wie löse ich dieses problem?
Hallo,
schau mal ins Datenblatt vom ATMega64. In einem UART-Register UCSRA
gibt's ein Flag, das heißt RXC. Es wird auf 1 gesetzt, wenn ein Zeichen
empfangen wurde.
Es reicht also wenn du vor dem Aufruf von uart_gets() überprüfst ob
dieses Bit gesetzt ist. Wenn nein kannst den PinX abfragen, oder
sonstige Aktionen durchführen.
Gruß, Florian
Wenn du mit
>uart_gets()
nichts anfangen kannst, dann ist das die falsche Funktion für dich.
In eine Hauptprogrammschleife vom Typ
while(1){}
gehört nichts, was die Ausführung der Schleife grundsätzlich verhindern
kann.
Mein Tipp:
1) sieh nach, ob ein Zeichen gekommen ist z.B. über uart_getc()
2) falls nein: mach weiter mit der Schleife 4)
3) falls ja: füge es zu deinem String dazu,
ist es ein CR oder LF dann ersetze es durch \0 und
werte dann den so erhaltenen String aus
4) Tu den Rest der Schleife (Pinabfrage....)
5) Weiter bei 1)
Kann mir jemand sagen wo da der Fehler liegen könnte.
Der Atmega bleibt in der While(1) schleife hängen.
1
unsignedcharneu[10];
2
3
while(1)
4
{
5
if((UCSR0A&(1<<RXC)))
6
{
7
printf("Hallo\n");//Gibt Hallo an die Serielle Schnittstelle aus.
8
gets(neu);//Speichert den String auf neu ab.
9
}
10
}
Wie gesagt will ich einen String einlesen, sobald ich was auf der
seriellen Schnittstelle empfang, sonst soll das Programm andere
Tätigkeiten ablaufen lassen.
schurli wrote:
> Kann mir jemand sagen wo da der Fehler liegen könnte.> Der Atmega bleibt in der While(1) schleife hängen.
warum eigentlich nicht über den RXC interrupt?
>
1
>unsignedcharneu[10];
2
>
3
>while(1)
4
>{
5
>if((UCSR0A&(1<<RXC)))
^^^ RXC0 muss es heißen
1
>{
2
>printf("Hallo\n");//Gibt Hallo an die Serielle Schnittstelle aus.
3
>gets(neu);//Speichert den String auf neu ab.
4
>}
5
>}
6
>
>> Wie gesagt will ich einen String einlesen, sobald ich was auf der> seriellen Schnittstelle empfang, sonst soll das Programm andere> Tätigkeiten ablaufen lassen.
klingt wie gemacht für interrupts
schurli wrote:
> ist drauf gerichtet und funtkioniert auch, aber irgenwas hats mit der> abfrage von der seriellen schnittstelle glaube ich.
Dan erläutere bitte, was genau du mit "bleibt in der While(1) schleife
hängen" meinst.
Im Moment besteht dein Codeschnippsel nämlich aus einer Endlosschleife;
das Programm MUSS in der while(1) Schleife bleiben.
Wenn du andere Tätigkeiten abzuarbeiten hast, könntest du die hier
unterbringen:
unsigned char neu[10];
while (1)
{
// Auf UART-Eingabe prüfen
if((UCSR0A & (1<<RXC)))
{
printf("Hallo\n"); //Gibt Hallo an die Serielle Schnittstelle aus.
gets(neu); //Speichert den String auf neu ab.
}
// ggf. Eingabe auswerten und
// sonstigen Code ausführen
}
deine register stimmen nicht. die routinen wurden wohl für einen andren
µc geschrieben. lies dir einfach mal das datenblatt und das tutorial
hier jeweils zum thema uart durch
Hat zwar schon anstandslos mit RXC statt RXC0 funktioniert obwohl es
definitiv falsch ist.
Trotzdem hängt das Programm beim Einlesen des Strings.
"Hallo" wird mir auf der Seriellen ausgegeben, aber dann steht alles.
printf("Hallo\n");//Gibt Hallo an die Serielle Schnittstelle aus.
8
neu=uart_getchar();
9
}
10
}
Komischerweise funktioniert das einlesen eines Zeichens wunderbar.
Wenn ich im Hyperterminal irgenwas eingebe, schickt mir der AVR "Hallo"
zurück und das Programm läuft in der while(1) weiter.
10mal irgendwas drücken ergibt 10mal "Hallo" also funktiniert es.
Warum funktioniert gets() nicht?
mfg
Stefan "stefb" B. wrote:
> Wenn du andere Tätigkeiten abzuarbeiten hast, könntest du die hier> unterbringen:>> unsigned char neu[10];>> while (1)> {>> // Auf UART-Eingabe prüfen> if((UCSR0A & (1<<RXC)))> {> printf("Hallo\n"); //Gibt Hallo an die Serielle Schnittstelle aus.> gets(neu); //Speichert den String auf neu ab.> }>> // ggf. Eingabe auswerten und> // sonstigen Code ausführen>> }
Das setzt allerdings voraus, dass der restliche Code nicht zu viel Zeit
braucht (abh. von F_CPU und BAUDRATE). Der Hardware-UART-Puffer ist
derzeit nur 2 Zeichen gross und es besteht grosse Gefahr, dass Zeichen
verloren gehen.
Ein grösserer Empfangspuffer und eine vom Userprogramm unabhängig
laufende RX-Interruptroutine wären sicher die geschicktere Lösung.