Ich habe grade erst angefangen, mich mit PICs auseinanderzusetzen. Ich würde jetzt gern eine Menüroutine schreiben, die ich nur mit dem Anfang eines Textes füttern muss, um den ganzen Text auf einem LCD anzeigen zu können. Z.B. eine Schleife, die 16 mal hintereinander einen Wert abfragt und ausgibt. Eine verlinkte Liste also im Prinzip. Das muss eigentlich noch nicht mal verlinkt sein, wenn ich in einem immer ein Hilfsregister als Adressspeicher incrementieren würde. Auslesen kann man dann ja über PCL, wie bei http://www.ic.unicamp.br/~celio/mc404/pic/pic_for_programmers.html sehr schön beschrieben. Bleibt die Frage, wie ich die Daten in den Programmspeicher bekomme. Einfach Eintippen ist ja nicht.. Außerdem: Sehe ich das richtig, dass man beim PIC nur ganze Register testen kann, wenn man zB ein Literal davon abzieht und STATUS, Z testet? Byte-Tests oder sowas gibt es ja nicht in dem Sinn. Kennt jemand eine Lösung für eins meiner Probleme (in Assembler)? Bitte so einfach wie möglich schreiben, weil ich total neu in Assembler und Programmieren generell bin, mal von einfachen Delphiprogrammen abgesehen.
Ich habe zwar auch nicht viel Ahnung von ASM (schreibe die Programme in Pascal) aber einen wichtigen Befehl hab ich mir dann doch angeeignet: dt 15,'bla','blubb',10,'ein Text',17,45,145,235; Mit DT = Define Table kann man beliebige Byte Werte bequem im Speicher ablegen... MfG, Dominik S. Herwald
Danke vielmals, das hat mir schon sehr geholfen. Es hat mich vor allem auf die unglaublich abwegige Idee gebracht, mir mal die MPLAB Hilfe anzuschauen ;)
"...unglaublich abwegige Idee..." scheint wirklich sehr abwegig zu sein, die DT-Anweisung nutzt nämlich fast niemand. Sie wird vom Assembler in die RETLW-Anweisung übersetzt, ist also nur eine viel bequemere Schreibweise. Man sieht leider oft PIC-Texte mit seitenlangen RETLWs (für jedes Byte extra). Schade um die viele Schreibarbeit und viel Vergnügen, wenn da mal ein Text geändert werden muß. Und nicht vergessen, der PIC ist segmentiert !!! Wenn also Deine Tabelle über eine oder mehrere Segmentgrenzen geht, reicht es nicht mehr, nur PCL mit dem Index zu laden, Du must dann auch noch das Segment richtig einstellen. Gab schon viele Leute, die sich wunderten, warum ab einer bestimmten Tabellengröße das RETLW abstürzt. Peter
Segmentierter Speicher? Und ich dachte, das war nur so eine bösartige Erfindung von Intel aus den Ur-x86er Zeiten :-) Kann mich nich gut an die CS DS ES und SS Register erinnern...
Hier nochmal ein Beispiel mit 2 Tabellen: http://www.mikrocontroller.net/forum/read-4-24512.html#57487 Die kleine muß komplett im gleichen Segment stehen und die große ist mit Segmentberechnung: Bei beiden das "Achtung..." durchlesen, damit sie auch richtig funktionieren. Peter
Danke, eins der beiden müsste für meine Zwecke funktionieren. Erst mal einarbeiten..
Ich habe mir das Beispiel angesehen und ich denke auch verstanden. Dann habe ich in Anlehnung daran meine eigene Version neu geschrieben. Die funktioniert auch soweit ganz gut. Ich kann einen Bildschrim anzeigen und per Steuerzeichen macht er auch Zeilenumbrüche. Nur bei der Subroutine, die mir den Anfang des gesuchten Bildschirms aus der Tabelle fischen soll, haperts und ich finde einfach nicht den Fehler. Wäre nett, wenn sich das mal jemand erfahrenes anschauen könnte. Das Problem ist folgendes: Wenn ich den Akku mit .0 lade und die Routine aufrufe, zeigt er "Hallo" an, wie er soll. Bei .1 zeigt er "1. Zeile<Umbruch>2. Zeile" an. Nur bei allem was danach kommt, will er irgendwie nicht mehr und beendet die Routine mit dem 2. Bildschirm (1. Zeile...) in den Adressbytes. Ich bin dankbar für jeden Tipp!
Die Forumsoft mag mich nicht. Hier der Code: Get_Screen_Adr ;Anfangsadresse des Screens rausfinden movf snr,0 call OutLcdDaten call WAIT incf snr,1 ;Screennummer auf Schleife vorbereiten movf snr,0 call OutLcdDaten call WAIT movlw high Screen_Tab ;Anfang der verketteten Liste holen movwf AdrH movlw low Screen_Tab movwf AdrL GSA_Loop movf snr,0 call OutLcdDaten call WAIT decf snr,1 ;beim gesuchten Screen angekommen? movf snr,0 call OutLcdDaten call WAIT incf snr,0 decf snr,0 btfsc STATUS,Z return GSA_Loop2 call Get_Char movwf pruef incf pruef,1 ;prüfen, ob Ende des Screens btfsc STATUS,Z goto GSA_Loop call Next_Char ;Wenn nicht, nächstes Zeichen goto GSA_Loop2 Get_Char movf AdrH,0 movwf PCLATH movf AdrL,0 movwf PCL Screen_Tab DT 'N', "Hallo", 0xff, "1. Zeile", 0xfe , "2. Zeile", 0xff, "3. Zeile", 0xfe, "4. Zeile", 0xff, "5. Zeile", 0xfe, "6. Zeile", 0xff
das war jetzt natürlich die falsche version. hier nochmal ohne den müll zwischendurch, sorry für die vielen postings: Get_Screen_Adr ;Anfangsadresse des Screens rausfinden incf snr,1 ;Screennummer auf Schleife vorbereiten movlw high Screen_Tab ;Anfang der verketteten Liste holen movwf AdrH movlw low Screen_Tab movwf AdrL GSA_Loop decf snr,1 ;beim gesuchten Screen angekommen? incf snr,0 decf snr,0 btfsc STATUS,Z return GSA_Loop2 call Get_Char movwf pruef incf pruef,1 ;prüfen, ob Ende des Screens btfsc STATUS,Z goto GSA_Loop call Next_Char ;Wenn nicht, nächstes Zeichen goto GSA_Loop2 Get_Char movf AdrH,0 movwf PCLATH movf AdrL,0 movwf PCL Screen_Tab DT 'N', "Hallo", 0xff, "1. Zeile", 0xfe , "2. Zeile", 0xff, "3. Zeile", 0xfe, "4. Zeile", 0xff, "5. Zeile", 0xfe, "6. Zeile", 0xff
1. Umständlicher geht es ja wohl kaum (sorry, ist nicht böse gemeint) GSA_Loop decf snr,1 ;beim gesuchten Screen angekommen? incf snr,0 ; snr+1 --> in w????? decf snr,0 ; snr-1 --> in w????? btfsc STATUS,Z return GSA_Loop decfsz snr,1 ;beim gesuchten Screen angekommen? goto L1 return L1 ..... würde so ziehmlich das Gleiche bewirken. 2. Ein Label (Unterprogramm) Next_Char gibt es nicht (in deinem Code). 3. AdrH und AdrL wird in deinem Code nirgendwo geändert. Was soll die Routine eigentlich machen? Dem Name nach die Adresse finden oder was sonst. Steffen
1. Das eine incf und decf-paar war irgendwie dazu gedacht, snr zwischendurch auf dem display anzuzeigen, denn nach der display-routine wäre ja das Z-Bit nicht mehr gesetzt. Trotzdem hätte ich es natürlich in f schreiben müssen. Ob ich jetzt GSA_Loop decf snr,1 ;beim gesuchten Screen angekommen? btfsc STATUS,Z return oder deine Version schreibe kommt denke ich aufs Selbe raus. 2.&3. Das ist nur ein Auszug des Codes. Next_Char incrementiert AdrL und bei Überlauf auch AdrH. Trotzdem danke für die Antwort. Ich poste wenn ich heim komme mal die gesamte Routine.
Na dann sehn wir mal. Unter den Vorraussetzungen müsste deine Routine eigentlich funktionieren. Ich sehe auf Anhieb jedenfalls keinen Fehler. Steffen
Ich habe jetzt mal die komplette Routine angehängt. Ich hoffe, er lädt die Datei diesmal hoch.. Kann es sein, dass ich den PIC schon nach grob geschätzt 100-200 mal flashen kaputtgeflasht habe? Ich dachte 1000 mal halten die locker aus.. Mittlerweile hört er nämlich nach dem 4. Zeichen auf. Das würde zu dem unberechenbaren Verhalten passen.. Und wenn ich einen Befehl irgendwo zwischendrin weglasse, zeigt er ein Zeichen mehr an, also ist wohl immer das selbe Word im Programmspeicher betroffen.
100-200 Programmierzyklen sollten eigentlich kein Problem sein. Könnte es evtl. sein, dass der WDT überläuft? In deinen Routinen kann ich eigentlich keinen Fehler entdecken. Hast Du die Routinen mal durch den Simulator gejagt? Steffen
simulator hab ich bis jetzt noch nicht benutzt/gefunden.freut mich,dass mein code keine offensichtlichen fehler enthält, das gibt mir hoffnung. wdt war glaub ich aus, kann ich aber vor sonntag nicht nachschauen weil ich 1. nicht daheim sein werde und 2. ist 1. mai, also werde ich wohl nicht fähig sein;)
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.