Hallo liebe uc-Freunde, ich blicke gerade nicht mehr durch, ggf. kann mir ja einer von euch weiterhelfen! Ich versuche gerade eine Hardware an die UART0 zu hängen ( andere laufen einwandfrei) (Hardware und Pegel alle i.O.!) Ich schildere mal kurz: uc--> Sende Daten --> Hardware OK! Paket_1 delay(mit Hardware-Timer!) Paket_2 usw..... ist OK! Paket_1 ohne delay Paket_2 .... hängt.... Paket_1(fordert Daten an) Delay eingebaut ReceiveUART() --> bleibt hängen... mit delay bleibt der RX UART Hängen... aber ich brauche nen delay für die Timeout-Zeit... Was nun machen, damit ich zur richtigen Zeit die Daten empfange ? Ohne Code ne Idee ? gruß
Schwer zu durchblicken, für Dich und für andere.
Hi, ich weiß, bin selber sehr konfus :-( Ich habe an meinem uC ein externes Display über RS-232 angeschlossen. Hardwareseitig funktioniert es einwandfrei(Pegel und Leitungen alle korrekt verdrahtet etc!) Also uC --> Display Display --> uC Version A: uC --> (Daten) --> Paket_1(Daten) --> Timeout --> Paket_2(Daten) -->Display(habe verstanden, gibt mir ein ACK zurück über Receive!) Version B: uC --> (Daten) --> Paket_1(Daten) --> KEIN Timeout --> Paket_2(Daten) -->Display(habe nichts verstanden NAK, du bist zu schnell!) --> BRauche Timeout! Version C: uC --> (Daten) --> Paket_1(erzähle mir was) --> Timeout --> "Warte auf Antwort des Displays" .... bleibt stehen und nichts passiert mehr! so verständlicher?
Kann es sein dass Du den Sinn der Begriffe "Delay, Timeout, Pause Zeitüberschreitung" nicht ganz verstanden hast und durcheinander würfelst? Grundsätzlich sollte man sich bei so einer gegensetigen Kommunikation ein vernünftiges Protokoll bzw. Handshake ausdenken, um verstümmelte Informationen oder "hängenbleiben" auszuschließen.
Route_66 wrote: > Kann es sein dass Du den Sinn der Begriffe "Delay, Timeout, Pause > Zeitüberschreitung" nicht ganz verstanden hast und durcheinander > würfelst? > > Grundsätzlich sollte man sich bei so einer gegensetigen Kommunikation > ein vernünftiges Protokoll bzw. Handshake ausdenken, um verstümmelte > Informationen oder "hängenbleiben" auszuschließen. So wie ich das verstanden habe, kommt er da mit einem Protokoll nicht weiter. Genau das ist ja letztendlich sein Problem: Er schickt was raus, aber die Gegenstelle antwortet nicht. Ergo: Timeout um rauszukriegen, dass die Gegenstelle aus irgendeinem Grund down ist. Allerdings mit einem schönen Softwaredesign, ev. eine Statemachine und einem Timer, der einen Systemtakt erzeugt, ist das doch kein Problem. -> Ich tippe mal wieder, dass die Systemarchitektur nicht stimmt. Mit einer kleinen Änderung ist es da oft nicht getan. Ist halt immer wieder Mist, wenn man im Nachhinein auf solche Kleinigkeiten, wie Kommunikation gegen alle Eventualitäten absichern, draufkommt.
Hallo Jungs, ich bin dabei ne State-Maschine aufzubaune... mag wohl wahrlich das beste sein!
@kbuchegg Aus seiner Beschreibung geht meine Erachtens hervor, daß er gerade nicht Timeout im Sinne von Timeout sondern im Sinne einer Pause (Delay) verwendet? Das Timeout was wir beide meinen, ist gar nicht eingebaut. So kann man eine - noch dazu paketweise - Kommunikation nicht aufbauen! Das klappt nie richtig.
Gast wrote: > Ich habe an meinem uC ein externes Display über RS-232 angeschlossen. Dann könnte vielleicht die Möglichkeit bestehen, daß es keine ganz so blöde Idee wäre, erstmal das Protokoll zu kennen, welches das Display spricht. Das Hellsehen hat sich nämlich als völlig untaugliche Methode erwiesen, irgendwelche Softwareprobleme zu lösen bzw. überhaupt erstmal zu erkennen. > Hardwareseitig funktioniert es einwandfrei(Pegel und Leitungen alle > korrekt verdrahtet etc!) Das behauptet erstmal jeder, auch wenn dem nicht so ist. Peter
Hallo liebe Mithelfer :-) wo wir nun beim etwas anderen Thema sind... Was eine State-Maschine ist etc, das ist mir alles bekannt (habe auch shcon einge erfolgreich programmiert!) Ich würde mal gerne erfahren, wie ihr eine programmiert. Nutzt ihr dafür Finite State-Maschine Editoren(quasi grafisches programmieren!) oder programmiert ihr das "Hard" in C ?
>wie ihr eine programmiert. Beitrag "Re: Programm bzw. Ablaeufe steuern" Beitrag "Re: BHKW-Steuerung"
Gast wrote: > wo wir nun beim etwas anderen Thema sind... Wenn Du Dein erstes Problem (Display-Protokoll) nicht lösen willst, bitte, Dein Bier. Ich habe aber die Erfahrung gemacht, daß einem nichtgelöste Probleme immer wieder auf die Füße fallen und jedesmal etwas wuchtiger. > Was eine State-Maschine ist > etc, das ist mir alles bekannt (habe auch shcon einge erfolgreich > programmiert!) Ich würde mal gerne erfahren, wie ihr eine programmiert. > Nutzt ihr dafür Finite State-Maschine Editoren(quasi grafisches > programmieren!) oder programmiert ihr das "Hard" in C ? Ganz hart, mit Papier und Bleistift. Und erst wenn alle States aufgemalt sind, gehts an den C-Code. Grafische Tools gehen nur für sehr einfachen Sachen (werden schnell unübersichtlich, wenn größer) und lassen sich schlecht dokumentieren/sichern. Man braucht dann immer diese speziellen Tools zum Ansehen/Drucken. Peter
Hallo, ne ne. Ich löse gerade das andere Problem. Weiß auch schon fast woran es liegt... Ich habe ja das Display über 232 an meinen uC angeschlossen. Ich kann Daten zu ihm wie wahre Wonne senden. Sobald ich aber Daten von ihm haben möchte(wenn z.B Tastendruck etc!) dann kann ich den ersten Tastendruck einwandfrei lesen und verarbeiten, aber der 2. der möchte dann nicht mehr und ich kriege die Daten dann nicht daraus...Hatte das mal am SPI dran hängen, da lief es besser... Aber SPI in einer schmutzigen EMV-verseuchten Umgebung besser nicht... Mal schauen ob ich noch ne Lösung finde...
>Mal schauen ob ich noch ne Lösung finde...
Programmkonzept?
Das sieht eig. sehr gut aus... Dachte ich zumindestens....
Hi, gibt es hier eig einen geschützten Bereich für nur ein paar von euch und mir ? Wegen Code und so...
Gast wrote: > Hi, > > gibt es hier eig einen geschützten Bereich für nur ein paar von euch und > mir ? Wegen Code und so... Ach komm. Kein Mensch klaut hier Code, der nicht aus der Codesammlung kommt. Zumal in diesem Forum geposteter Code meist sowieso fehlerhaft ist und die finale, fehlerkorrigierte Version eh nicht mehr gepostet wird.
Achso, nicht dass das einer falsch versteht... Es ist nur, weil ich offiziell ne Diplomarbeit schreibe und das hier nicht veröffentlichen darf...
>Es ist nur, weil ich >offiziell ne Diplomarbeit schreibe und das hier nicht veröffentlichen >darf... Gib das Forum als Quelle an und gut. Ich hab letztens auch jemanden über das Forum hier, dann (weils besser geht) über ICQ geholfen. Der hat mich dann einfach bei Quellen/Hilfen erwähnt und Stichpunktartig ein "Gesprächsprotokoll" beigelegt. Das war irgendeine Technikerarbeit.
Es gibt noch den Chat. Ich hab aber keine Ahnung ob sich dort viel tut oder nicht. Ob man das also als 'geschützten Bereich' bezeichnen kann.
Hi, habe euch mal meine derzeit runtergestutzte main und die LCD232.c Datei begefügt.
So, nun eine kleine weitere Erläuterung... unsigned char get_Return_Code_LCD() --> Wenn ich eine Taste drücke, dann gibt mir das Display ne Dez-Zahl zurück..Die Funktion filtert mir das aus dem Protokoll heraus void Puffer_LCD(unsigned char *Puffer_Data) --> Daten aus Puffer empfangen Bytes_free = get_Puffer_Bytes_LCD(); // Abfragen der abholbereiten Bytes (wenn keine abholbar, dann 0 Bytes! PIND0 --> Pin vom Display, wenn Daten zum abholen dann LOW!! Danke euch allen :-)
>Dateianhang: LCD_main.zip (3,1 KB, 2 Downloads)
Ich halte ALLE delays da drin für kontraproduktiv.
(höchstens mit einem delay_eine_mikrosekunde für das LCD kann ich mich
anfreunden)
Das war ja eig. auch nur ne Notlösung(sind über Hardware-Timer!), aber ohne die will er so gar nicht richtig die Daten schon nacheinander schlucken... Obwohl..ich könnte ja nachfragen, ob das erste Paket verstanden ist, wenn ja (ACK) dann sende ich dir das nächste
Übrigens, wenn ich aus der Puffer_LCD(..) unter MARKIERUNG A das auskommentiere, dann toggelt PINDO(mein HArdwareDatenabrufKabel!) nur noch auf Null rum... wenn ich das einfüge, dann toggelt das PIND0 auch mal wieder auf high rum!!
1 | void Puffer_LCD(unsigned char *Puffer_Data) |
2 | {
|
3 | unsigned char Bytes_free; |
4 | unsigned int sum=0,i; |
5 | |
6 | |
7 | Bytes_free = get_Puffer_Bytes_LCD(); // Abfragen der abholbereiten Bytes |
8 | |
9 | smallprot_receive(2,1,'S'); //Anfordern der Daten aus dem Datenpuffer des LCD |
10 | |
11 | if (ReceiveByte_LCD() == ACK) // Daten am LCD korrekt empfangen? |
12 | {
|
13 | for(i=0;i<Bytes_free;i++) //Falls ja, dann Daten auslesen |
14 | {
|
15 | Puffer_Data[i] = ReceiveByte_LCD(); |
16 | // Summe für Prüfsumme bilden
|
17 | sum += Puffer_Data[i]; |
18 | }
|
19 | sum = sum - Puffer_Data[(Bytes_free-1)] ; // BCC abziehen |
20 | sum = (unsigned char) sum; |
21 | |
22 | if (sum == Puffer_Data[(Bytes_free-1)]) //Prüfsumme vergleichen |
23 | {
|
24 | //show_content(150,50,'H');// Absolut OK!
|
25 | }
|
26 | else //Fehlerhafte Übermittlung |
27 | {
|
28 | //return FALSECHECKSUM;
|
29 | //show_content(70,50,'A');// Absolut OK!
|
30 | }
|
31 | |
32 | }
|
33 | else
|
34 | {
|
35 | //return NOCONNECTION ;
|
36 | }
|
37 | ///MARKIERUNG A
|
38 | /*for(i=0;i<6;i++)
|
39 | {
|
40 | |
41 | show_content(50 +(i*20),150,0x30 +Puffer_Data[i]);
|
42 | }
|
43 | */
|
44 | }
|
>Das war ja eig. auch nur .... sende ich dir das nächste
Du solltest das AVRStudio schließen, dir Gedanken über den
Programmablauf machen. Also wer was an wen schickt, welche Datenmengen
in welchen Zeiten entstehen. ..
Dann solltest du für solche Kommunikationen einen kleinen Handler mit
FIFO schreiben...
Somit entkoppelst du alles.
Ich habe bei einem aktuellen Projekt mit nem 4x20 LCD das genauso
gemacht.
die Fkt. LCD4x20_put usw. , die Texte ausgeben, füllen das nur intern im
Handler in eine Struktur. Das geht schnell, da die Fkt sozusagen nur
paar Bytes a la memcpy kopiert.
Der Handler (der zyklisch aufgerufen wird) kümmert sich dann in aller
Ruhe um die Ausgabe auf das Display unter Beachtung des Timings
(busyflag). Damit ich dort ohne Delays auskomme, ist das als
State-Maschine programmiert.
SOmit dauert die Displayausgabe halt einige wenige ms (mehr) aber das
spielt eh keine Rolle. Für das Auge ist der Text sofort da.
Heute abend kann ich, falls Interesse besteht, das mal posten.
Hi, ich hätte immer interesse :-) will ja lernen :-)
Kannst du noch ein paar Worte zum Protokoll sagen? In der LCD232 kommen mir ein bischen zuviele konstante Dinge vor. Sind die empfangenen Pakete immer gleich lang? Du prüfst zwar in der get_Puffer_Bytes_LCD auf korrekte Checksumme. Der Rest vom Protokoll (sprich ob auch das was du als Rückgabe erwarten müsstest) wird nicht ausgewertet, sondern das eine dich interessierende Byte rausgepickt. Allerdings ist das Rückschleusen des Wertes nur über den return etwas zweifelhaft. Wie hältst du FALSCHECKSUM, NOCONNECTION von einer gültigen Anzahl auseinander? (Vermutung: grosse Werte für die beiden Konstanten, die in den Daten nicht vorkommen können?) Auf jeden Fall interessiert den Aufrufer in Puffer_LCD ein möglicher Fehlerfall in get_Puffer_Bytes_LCD erst mal gar nicht. Noch nicht mal, wenn das LCD sagt, dass es 0 Bytes für dich bereit hat, gibt Puffer_LCD auf die Daten anzufordern. (Ich les mir den Code weiter durch. Das sind jetzt Dinge, die mir beim Durchlesen aufgefallen sind. Ich hab noch nicht grossartig über die Logik im Programm nachgedacht)
Hmm. Ohne das hier simulieren zu können ist es schwer das alles nachzuvollziehen. Ich denke aber, dass dein Hauptproblem tatsächlich darin besteht, dass du mit möglichen 'Fehlerfällen' nicht richtig umgehst. Ich würde mal in get_Puffer_Bytes_LCD() anfangen und nachsehen, wie sich mögliche Fehler oder 0-Längen an die aufrufenden Funktionen weitergeben, bzw. ob das dort korrekt abgehandelt wird. Auch würd ich versuchen mir einen Mechanismus zu schaffen, mit dem ich direkt auf der Schnittstelle mitlesen kann, welche Bytes da hin und her gehen (also noch bevor dein Programm versucht die Bytes in Pakete zu zerlegen). Normalerweise gibt das die besten Hinweise. Ist natürlich blöd, wenn du kaum andere Mittel als eine UART hast, um die UART-Kommunikation zu belauschen.
Hmm. Könnte das
1 | for(i=0;i<6;i++) |
2 | {
|
3 | show_content(50 +(i*20),150,0x30 +Puffer_Data[i]); |
4 | }
|
der Versuch sein, eine Art Übertragungsprotokoll zu bekommen. Wenn ja, versuch das mal etwas tiefer anzusiedeln. Am besten wäre natürlich, wenn du eine Möglichkeit hättest, direkt aus der ReceiveByte_LCD ein Protokoll anzustossen. Dann kannst du klarerweise das LCD nicht als Ausgabemedium benutzen, aber vielleicht hast du ja noch eine andere Möglichkeit (2.te UART zu einem Terminal?)
Matthias Lipinsky wrote: > Dann solltest du für solche Kommunikationen einen kleinen Handler mit > FIFO schreiben... > > Somit entkoppelst du alles. Würd ich auch sagen. Sowas ist immer gut und nimmt den Stress, das das Timing hinhauen muss. Auch fallen dann all die Warteschleifen weg, die Matthias ja schon angekreidet hat und man kann bequem auf Interrupt umstellen. > Ich habe bei einem aktuellen Projekt mit nem 4x20 LCD das genauso > gemacht. > > die Fkt. LCD4x20_put usw. , die Texte ausgeben, füllen das nur intern im > Handler in eine Struktur. Das geht schnell, da die Fkt sozusagen nur > paar Bytes a la memcpy kopiert. > Der Handler (der zyklisch aufgerufen wird) kümmert sich dann in aller > Ruhe um die Ausgabe auf das Display unter Beachtung des Timings > (busyflag). Damit ich dort ohne Delays auskomme, ist das als > State-Maschine programmiert. Ah, so hast du das gemeint. Quasi ein Display-Ram für das LCD. Ich hatte eher an eine Bufferung der UART Routinen gedacht.
Wow Leute, ich bin echt baff, was ihr euch für Gedanken macht, wobei ihr mich nicht kennt :-) Danke! Ich glaube nun auch, dass ich wirklich die Rückgabe-Routinen(Fehlerfall etc) mal checken sollte und das anders mitschreiben sollte... Das mitschreiben und ausgeben auf dem LCD ist wirklich nicht das wahre, gebe ich schon zu! Es handelt sich um das Smallprotokoll von lcd-module.de Werde mal nicht nur ein Byte rauspicken und ne sinnigere Struktur raus machen, wird wohl im Endeffekt weniger Arbeit sein :-) und mir eure Tipps zu herzen nehmen :-)
Matthias Lipinsky wrote: >>Es ist nur, weil ich >>offiziell ne Diplomarbeit schreibe und das hier nicht veröffentlichen >>darf... > > Gib das Forum als Quelle an und gut. > > Ich hab letztens auch jemanden über das Forum hier, dann (weils besser > geht) über ICQ geholfen. Wenn er über das Forum nichts veröffentlichen möchte, ist ICQ denkbar ungeeignet da AOL sich vorbehält, Gesprächsinhalte zu veröffentlichen.
Gast wrote: > Wow Leute, > > ich bin echt baff, was ihr euch für Gedanken macht, wobei ihr mich nicht > kennt :-) Ich denke jeder von uns war schon mal in der Situation mit einem Gerät kommunizieren zu müssen und ist daran schier verzweifelt. Zumindest bei mir war es dann immer so, dass das Mitschreiben der Kommunikation auf tiefster Byteebene am schnellsten zu einer Lösung oder zumindest zu Hinweisen geführt hat. Und meistens hat sich dann rausgestellt, dass ich irgendwelche Bytes aus der Übertragung nicht richtig interpretiert bzw. im Aufrufstack nicht richtig darauf reagiert habe. Und mehr als einmal sind es die Dinge, die man auf später verschoben hat wie Fehlerprüfung etc. die einem in die Suppe spucken. Sind einfach Erfahrungswerte, so dass man bei einem Fremdcode gleich mal nachsieht, ob das eingehalten wird.
HI, so eine Erfahrung möchte ich auchmal gerne haben :-) :-) Eine kleine Verständnis-Frage(ich weiß Datenblätter!)Bin einfach zu konfus gerade..sollte mal nen We drüber schlafen und eure Gedanken dann verwirklichen! Wenn ich sage, ich nutze nen RXCIE, dann kriege ich doch nen IRQ wenn Daten anstehen und noch NICHT gelesen sind ? Sprich, dann könnte ich doch ne global Var setzen alias DATENabholen und toggeln.. Dann frage ich in einer Funktion ab, sind Daten zum abholen da oder nicht und sperre so lange den anderen Datenverkehr, wenn Daten abzuholen sind? und hole sie dann ab? Danke an allen
Gast wrote: > HI, > > so eine Erfahrung möchte ich auchmal gerne haben :-) :-) Kommt ganz von alleine. Ist einfach nur eine Zeitfrage. Jeden Fehler den du machst, hat jeder von aus auch gemacht. x-mal. Nur halt vor einigen Jährchen. > Wenn ich sage, ich nutze nen RXCIE, dann kriege ich doch nen IRQ wenn > Daten anstehen und noch NICHT gelesen sind ? Yep. > Sprich, dann könnte ich doch ne global Var setzen alias DATENabholen und > toggeln.. Yep. > Dann frage ich in einer Funktion ab, sind Daten zum abholen da > oder nicht und sperre so lange den anderen Datenverkehr, wenn Daten > abzuholen sind? und hole sie dann ab? Guter Plan. (Und jetzt gehst du zum Peter Fleury auf die Website und holst dir von dort die UART-Library. Die macht genau das was du da oben beschrieben hast. Nur dass sie noch einen kleinen Ringbuffer mit dabei hat, der dich vor Datenverlust bewahrt, wenn dein Hauptprogramm mal nicht schnell genug auf DATENabholen reagieren kann) :-)
So. hier ist mein bisheriges Machwerk für ein LCD4x20. Die Kernidee dahinter ist, in der Bibliothek ein Array für alle 4x20 Zeichen zu haben. Wenn ich jetzt einen Text anzeigen möchte, dann rufe ich zB folgendermaßen auf:
1 | lcd4x20_show_P ( /* u8Row */ 3, |
2 | /* u8Col */ 13, |
3 | /* pu8Data */ SMB_MINUS ); |
Diese Funktion kopiert den Text nur in besagtes Array. Das dauert paar µs. Damit dieses Array jetzt (langsam) zum LCD gebracht wird, muss der "Handler" zyklisch aufgerufen werden. Der prüft das Array nach neuen Daten und versendet die häppchenweise (also pro AUfruf max. ein Zeichen) zum Display. Das Versenden kann ja bei dir über UART geschehen.
1 | //-- Endlosschleife -----------------------------------------------
|
2 | while ( 1 ) |
3 | {
|
4 | //-- LCD Display bedienen ----------------------------
|
5 | lcd4x20_run (); |
6 | |
7 | //-- Initialisierung Schrittkette --------------------
|
8 | switch ( scMainStates.u8SmState ) |
9 | {
|
10 | case C_SM_INIT: |
11 | ...
|
Guck dir das einfach mal an, vielleicht hilft dir das, um paar Ideen zu bekommen.. PS: Da ich seit heute einen Logikanaylser habe, werde ich das Timing sicherlich noch weiter verbessern.. Bei Verbesserungsvorschlägen, einfach angeben...
Matthias Lipinsky wrote: > So. hier ist mein bisheriges Machwerk für ein LCD4x20. Ich habs nicht ganz so kompliziert gemacht: Beitrag "Formatierte Zahlenausgabe in C" Da die Ausgabe im Timerinterrupt erfolgt, ist das Busy lesen vollkommen überflüssig. Das Busy ist ja in jedem Fall vorbei beim nächsten Interrupt. Es reichen also 6 IOs zum LCD. Peter
>Da die Ausgabe im Timerinterrupt erfolgt.. Hm.. Naja hab ich auch erst überlegt, aber mein TimerInt ist hier 32ms. Und wenn ich immer eine Zeile ausgebe, dann ist das ne halbe Sekunde. Das ist mir doch etwas viel... Deshalb hab ich das aus dem TimerInt wieder rausgenommen... >Es reichen also 6 IOs zum LCD. Ich hab 8bit Anbindung, da ich gleich acht Taster mit einlese.
Hallo an alle, vielen Dank für die zahlreichen Ideen und Hinweise. Ich habe nun endlich eine funktionsfähige Software geschrieben und nicht mehr so vollgemüllt wie vorheriges! Ich hoffe, dass ich allen anderen(euch ja leider nicht :-P) mal helfen kann. In diesem Sinne Gruß
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.