Hallo, seid ein paar Tagen versuche ich mich im Programmieren eines Mikrocontrollers in Assembler (Microchip MPLAB IDE V8.90). Der Mikrocontroller, den ich mit meinen Versuchen quäle, ist ein PIC16F628. Zum Brennen verwende ich den Sprut-Brenner P8. Das Brennen von fertigen HEX-Dateien und auch das Assemblieren von leicht geänderten *.asm-Files klappt auch. Jetzt habe ich ein eigenes Programm geschrieben und erhalte beim Assemblieren folgende Fehlermeldung in Zeile 71 und somit kein HEX-File: Symbol not previously defined (ZeVs) Ich kann in dieser Zeile keinen Fehler erkennen. Zumindest keinen Tippfehler. Kann mir jemand einen Tip geben? Falls im Programmablauf ein Fehler sein sollte, bitte nicht daraufhin weisen. Dass will ich selber herausfinden. Danke, Norbert
"ZeVs" ist nicht das Gleiche wie "ZeVS" - Groß/Kleinschreibung beachten!
Wo definierst du? movwf Zeit ;Wert für
Fuerst-Rene schrieb: > Wo definierst du? > movwf Zeit ;Wert für Das ist ein Unterprogramm: Call Zeit Aber ein recht eigenartiges, das den Stack versaut: Zeit movf Wert,0 Goto MainShift Solche Unterprogramme/Funktionen sollten per RET(URN) beendet werden, weil übliche Assembler bei einem CALL die Rücksprungadresse auf den Stack legen. Oder ist das beim PIC anders? (Es würde mich nicht wundern... ;-)
Fuerst-Rene schrieb: > Wo definierst du? > > movwf Zeit ;Wert für Tja seltsam, aber der Assembler macht daraus 00F 00AD MOVWF 0x2d 73: movwf Zeit ;Wert für und BUILD SUCCEEDED!!??
Chris B. schrieb: > Das ist ein Unterprogramm: > > Call Zeit ahh stimmt, zu spät gesehen. Aber da ist noch mehr faul...d1,d2,d3 kollidieren mit Wert, ZeVS usw......
Das ging ja schnell! :-) Danke für eure Hilfe. Zigmal durchgelesen und doch ein Tipfehler. Jetzt gibt es keine Fehlermeldung mehr. Zumindest beim Assemblieren. Schöne Grüße, Norbert
Hallo Norbert, Dein Fehler ist ein Missverständnis im Gebrauch von Labels und von Variablen. ;LABELS & KONSTANTEN #define Wert 0x20 ;Speicherzelle für den Wert der Zeitkonstante #define ZeVS 0x21 ;ZeVS = Zelle zum Zwischenspeichern #define ZeAd 0x22 ;ZeAd = Zelle zum Zwischenspeichern eines Du möchtest Wert, ZeVS, ZeAD, sämtlich Labels und keine Variablen, den Inhalt der RAM-Adresse 0x20 - 0x22 zuweisen. Zugleich verwendest Du aber bei der Deklaration von Variablen clrf ZeVS clrf ZeAd die gleichen Namen als Variable. Da meckert der Assembler! Richtig wäre z.B. Zeitverzoegerung equ d'20' ;Konstante, Wert für delay 20x100ms also reale Zahl, keinen Registerinhalt zuweisen! Dann kannst im Programmlauf z.B. so movlw Zeitverzoegerung ;Label (enthält .20) movwf ZeVS ;Variable! übers WREG den Wert in die Variable Delaytime kopieren Nicht vergessen die Variable zu deklarieren: CBLOCK 0x20 ;Variablen ab Adresse 20h anlegen d1,d2,d3 ;Zähler in Sub Delay100ms ZeVS ENDC oder aber: movlw Zeitverzoegerung CALL Delay100ms den Wert übers WREG direkt an das Unterprogramm übergeben. Mit solch einem Label sind auch einfache Berechnungen möglich. Vgl. dazu die MPLAB-Hilfe "arithmetische operatoren" z.B: movlw Zeitverzögerung * 5 ;Die Rechnung macht der Compiler beim assemblieren für Dich movwf Delaytime ;Delaytime hat jetzt den Wert .100. #define verwendet man um komplexere Inhalte einfach lesbar zu machen: #define LED_EIN bsf PORTB,3 #define LED_AUS bcf PORTB,3 Jetzt genügt es im Programmlauf zu schreiben LED_EIN ;der Assembler schreibt nun in das Programm-Memory (vgl. MPLAB - View) "bsf PORTB,3", also den Inhalt des Labels "LED_EIN". Probier es einfach mal aus. Ich hoffe Dich jetzt in die richtige Richtung geschubst zu haben. mfG GroberKlotz
GroberKlotz schrieb: > Zugleich verwendest Du aber bei der Deklaration von Variablen > > clrf ZeVS > > clrf ZeAd > > die gleichen Namen als Variable. Da meckert der Assembler! Das bemängelt der Assembler überhaupt nicht! Bis auf die vertauschte Groß/Kleinschreibung wird OHNE Fehlermeldung assembliert. Nur in der Praxis liegen seine "ZeVs" usw. auf den gleichen RAM-Adressen die die Variablen d1,..... für die "Delay_100ms". Entweder verwendet man CBLOCK oder #define - das aber Konsequent sonst verliert man total die Übersicht.
Chris B. schrieb: > Das bemängelt der Assembler überhaupt nicht! OK, stimmt, habs jetzt ausprobiert. Na ja, bin aber Gott sei Dank bisher noch nie auf die Idee gekommen #define bzw. cblock zu vermischen... :-) Stimme völlig zu dass das nur Verwirrung stiftet. @ Norbert: Verwendest Du den MPLAB-Simulator? Falls nicht, solltest Du Dich damit unbedingt beschäftigen, dann bemerkst Du sofort wo in nachstehender Zählschleife aus Deinem Programm der Wurm drin ist und diese so nicht funktionieren kann: MainShift movwf ZeVS ;WREG->ZeVS CALL Delay100ms ;dort zigfach movlw... decfsz ZeVS,1 ;ZeVS-1, Ergebnis in ZeVS GOTO MainShift mfG GroberKlotz
@ Chris: Damit kämpfe ich gerade. Chris B. schrieb: > Entweder verwendet man CBLOCK oder #define - das aber Konsequent sonst > verliert man total die Übersicht. Heißt das, dass man in einem Programm entweder nur CBLOCK oder nur #define verwenden soll? Ich versuche es jetzt so: ;VARIABLEN CBLOCK 0x20 ;Variablen ab Adresse 20h anlegen d1,d2,d3 ;Zähler in Sub Delay100ms CBLOCK 0x24 ;Variablen ab Adresse 24h anlegen (damit andere RAM-Adressen benutzt werden) ZeVs ;Zelle zum Zwischenspeicher der Verzögerungsschleife ZeAd ;Zelle zum Zwischenspeichern eines Summanden für ;die Addition mit LEDPORT ENDC ; ;LABELS & KONSTANTEN #define LEDPORT PORTB #define LEDTRIS TRISB Delay equ d'20' ;Delay den Wert "20" zuweisen @ GroberKlotz: Auch daran, dass das der Inhalt vom W-Register vor Call Delay100ms gerettet werden muss, arbeite ich. MPLAB-Simulator? Kenne ich noch nicht.
Norbert Potthoff schrieb: > Heißt das, dass man in einem Programm entweder nur CBLOCK oder nur > > #define verwenden soll? Ich versuche es jetzt so: > > > > ;VARIABLEN > > CBLOCK 0x20 ;Variablen ab Adresse 20h anlegen > d1,d2,d3 ;Zähler in Sub Delay100ms > CBLOCK 0x24 ;Variablen ab Adresse 24h anlegen (damit andere > RAM-Adressen benutzt werden) > ZeVs ;Zelle zum Zwischenspeicher der Verzögerungsschleife > ZeAd ;Zelle zum Zwischenspeichern eines Summanden für > ;die Addition mit LEDPORT > ENDC Ja - entweder oder - ausser du willst dir das Programmieren und Fehlersuchen unnötig schwer machen. CBLOCK 0x20 ;Variablen ab Adresse 20h anlegen d1,d2,d3 ;Zähler in Sub Delay100ms ENDC CBLOCK 0x24 ZeVs ;Zelle zum Zwischenspeicher der Verzögerungsschleife ZeAd ;Zelle zum Zwischenspeichern eines Summanden für ;die Addition mit LEDPORT ENDC (CBLOCK...ENDC gehören zusammen, weiss jetzt nicht ob MPLAB mehrere CBLOCK ohne dazugehörige ENDC "frisst" ;-) )
Norbert Potthoff schrieb: >Auch daran, dass das der Inhalt vom W-Register vor Call Delay100ms >gerettet werden muss, arbeite ich. NEIN! Du mußt die Variable "ZeVs" davor bewahren dass diese durch "movwf" mit dem Inhalt des WREG zu überschrieben wird, nachdem Du den Wert von "ZeVs" mittels "decfsz" um 1 vermindert hast! Denke dabei daran, dass "decfsz ZeVs,1" das Ergebnis ZeVs - 1 in die Variable ZeVs zurückschreibt! > MPLAB-Simulator? Kenne ich noch nicht. Dann gehe mal so vor um MPLAB SIM aktivieren: MPLAB starten, dann nachfolgende Menüs durchgehen 1. Menü [Debugger] - Select Tool - 4. MPLAB SIM [Click) 2. Menü [Debugger] - Settings - [Click] Processor Settings: eintragen z.B. fosc 4MHz Animation / Real Time Updates Haken vor enable real time watch [OK] Watch-Window aktivieren Damit kann man den Inhalt von Registern, also z.B. PORTA, PORTB, Variable und deren Veränderung im Programmlauf beobachten. 1. Menü [View] - Watch [Click] jetzt ist das Watch-Fenster sichtbar. 2. Mausklick auf oberste freien Platz im Fenster setzen und z.B. WREG eintragen. Ist jetzt ein Programm aktiv, ist der Inhalt des W-Registers zu sehen, gleiches mit PORTB, oder der Variablen "Test" natürlich müssen diese Register in Deinem Programm existieren, Variable müssen deklariert sein. 3. Probiere das alles mal aus. Nützliche Literatur zu MPLAB SIM: MPLAB User Guide (englisch) im Verzeichnis von MPLAB Kleine Einführung in die Simulation mittels Microchip MPLAB IDE [http://www.fernando-heitor.de/index.php/downloads/Dokumente/MPLAB-Tutorial/] in Deutsch, runterladen und nicht vergessen: Tante groogle nach weiteren Informationen intensiv befragen! Zu guter Letzt: MPLAB hat eine eingebaute Hilfe mit der man fast alles zum Assembler (Befehle, Labels, Variable usw) erfahren kann, allerdings durchweg in englischer Sprache. mfG GroberKlotz
Chris B. schrieb: > (CBLOCK...ENDC gehören zusammen, weiss jetzt nicht ob MPLAB mehrere > CBLOCK ohne dazugehörige ENDC "frisst" ;-) ) Falsch: cblock 0x20 ;Variablen ab Adresse 20h anlegen d1,d2,d3 ;Zähler in Sub Delay100ms cblock 0x30 BCD0 endc Richtig! Aber nur sinnvoll wenn man weiß zu was so was gut ist! cblock 0x20 ;Variablen ab Adresse 20h anlegen d1,d2,d3 ;Zähler in Sub Delay100ms endc cblock 0x30 ;so können die Register 0x24 bis 0x29 z.B. BCD0 ;für FSR/INDF-Operationen freigehalten werden ENDC mfG GroberKlotz
Besten Dank für eure Hilfe!!! Ich werde eure Tips hoffentlich fehlerfrei umsetzen. Ich melde mich wieder, wenn es läuft. Oder, was ich nicht möchte, wenn es nicht geklappt hat. Nochmals Danke und bis bald. Schöne Grüße aus Münster, Norbert
Ja, dieses Manko bei der Variablendefinition hatte mich schon in den 90ern geärgert - und mich veranlaßt, mir meinen eigenen Assembler zu schreiben, wo ich Segmente (CODE und RAM) und Organisatorisches (ORG, DS, DATA usw) eingeführt habe. Wenn man den häßlichen originalen Assembler von Microchip benutzen will, dann sollte man sich als Denkhilfe ein paar Konventionen ausdenken, an die man sich dann strikt hält. Zum Beispiel: - alle definierten Konstanten mit wf_ beginnen lassen ("Wert Für" etwas). #define wf_PortA B'10110' MOVLW wf_PortA MOVWF PortA - niemals 0 oder 1 bei dem 2. Parameter schreiben, sondern immer W oder F (notfalls selber vorher definieren), also MOVF PortA,W XORWF PortB,F - bei lokalen Marken einen Unterstrich als erstes, und NIEMALS woanders den Unterstrich als erstes benutzen. MOVLW 100 _warten: ADDLW -1 BTFSS Status,Z GOTO _warten Ähem, mal ne andere Frage am Rande: Kann man bie der neuesten Kreation des MPLAB inzwischen einen eigenen Assembler einbinden? W.S.
W.S. schrieb: >...mich veranlaßt, mir meinen eigenen Assembler zu schreiben prinzipiell stimme ich Dir ja zu, aber warum preist Du Deinen selbstgeschriebenen Assembler seit Jahren gebetsmühlenhaft an? Frag mal Opa Guugle nach "W.S. (Gast)" AND "eigenen Assembler" Ich finde übrigens den MPLAB-Assembler gar nicht so schlecht und komme damit schon seit Jahren sehr gut zurecht. Wir wollen hier aber bitte keine Diskussion über den besten Assembler vom Zaune brechen, helfen wir lieber dem Norbert bei der Lösung seiner Probleme. mfG Ottmar
!!!! J U C H U U U U !!!! Es läuft!!! Keine Fehlermeldung beim Assemblieren, alle LEDs schalten nacheinander ein und bleiben auch an!!! @GroberKlotz: Nachdem ich verstanden habe, wie die Zeitschleife "Delay100ms" funktioniert, wusste ich auch was du mit (Zitat): Du mußt die Variable "ZeVs" davor bewahren dass diese durch "movwf" mit dem Inhalt des WREG zu überschrieben wird... gemeint hast. @Chris: Danke für den Hinweis mit der Kollision der Speicherzellen D1, D2, D3, ... Eine Kleinigkeit muss ich noch herausfinden. Die Zeitschleife bei mir ist wesentlich länger als die 100ms, die es bei einem 4MHz-Quarz sein sollen. Noch habe ich keine Idee. Der Quarz auf meiner Testplatine hat 4MHz. Euch allen nochmal ein dickes, fettes D A N K E !!! :-)))
Hallo Norbert, schön, dass es geklappt hat! Wie mißt Du die Dauer der Verzögerungsschleife? Diese Verzögerungsschleife movlw .20 movwf ZeVs MainShift movf ZeVs,W CALL Delay100ms ..... GOTO MainShift macht genau das Richtige, um 2 Sekunden Delay zu erhalten (genau 1.999985 Arbeitszyklen mit 4MHz-Quarz). Es kann nur sein dass ZeVs beim wiederholten Schleifendurchlauf nicht mehr den ursprünglichen WErt von .20 hat! Lass Dir was einfallen! Vielleicht ist es Absicht von Dir dass ZeVs bei jedem Schleifendurchlauf um 1 vermindert wird ??? Diese Dinge bekommst Du mit MPLAB-Sim locker in den Griff, versuch es einfach mal! Ist Dir bekannt dass im Menü "Debugger" eine Stoppuhr vorhanden ist? Allerdings muss dazu wie von mir schon beschrieben der MPLAB-Simulator aktiviert sein. Dann setzt Du im Simulator einfach einen Haltpunkt, ab welchem die Zeit bzw. Zyklenzahl gemessen werden soll und dann noch einen Haltepunkt an dem die Zeitmessung endet. Haltepunkt 1 - Stopwatch auf Null setzen Haltepunkt 2 - Stoppuhr ablesen Wie schon von W.S. erwähnt ist es auf Dauer von Vorteil bei Befehlen welche das Ergebnis im WREG bzw. im File ablegen, nicht die 0 oder 1 zu verwenden sondern eindeutig: movf PORTB,W ;W wie WREG (NICHT: PORTB,0 decfst Variabel,F ;F wie File (NICHT: Variable,1) Das macht Dein Programm auch für andere besser lesbar. Übrigens: Dein Programm kann wesentlich vereinfacht werden. Ohne zu schwindeln, ohne faule Tricks: Bei mir hat "Main" gerade mal 12 Codezeilen und schaltet eine LED nach der anderen im 2 Sekundentakt zu. Zusätzlich ist nur noch die Delay-Routine vorhanden. Wenn Du nicht weiterkommsen solltest, lasse ich Dir (auf Anfrage) das ASM-File gerne zukommen. mfG GroberKlotz
Ottmar K. schrieb: > prinzipiell stimme ich Dir ja zu, aber.. warum so gereizt? Wenn's einen interessiert, ist es gut, wenn nicht dann ist es auch gut. Von Anpreisen kann wohl keine Rede sein, wohl aber davon, daß meine Intimkenntnisse des Microchip-Assemblers eher steinalt sind - aus besagtem Grunde. Würde mich aber trotzdem interessieren, ob es jemand geschafft hat, in MPLAB ein eigenes Übersetzungstool einzubauen - und wenn, wie. W.S.
Hallo GroberKlotz, ich habe das Programm vereinfachen können. Das Problem mit der Schleife ist aber noch immer vorhanden. Statt des Wertes den ich für die Schleife vorgebe, wird immer "irgendein" Wert in d3 geschrieben. Jetzt suche ich noch nach der Ursache. Das arbeiten mit dem Simulator macht die Sache tatsächlich einfacher, selbst für einen Anfänger wie mich, für den Alles neu ist. Über meine Fortschritte halte ich dich auf den laufenden. Danke für deine Unterstützung, bis bald, Norbert
Norbert Potthoff schrieb: > statt des Wertes den ich für die Schleife > vorgebe, wird immer "irgendein" Wert in d3 geschrieben. Na dann ist nur möglich dass beim Aufruf "CALL Delay100ms" nicht der von Dir gewollte Wert im WREG steht. Falls Du den Wert mittels einer Variablen "movf ZeVs, W" ins Wreg geschrieben hast, dann hatte eben die Variable ZeVs den falschen Wert! movf ZeVs,W ;Wert von ZeVs? CALL Delay100ms ..... Delay100ms movwf d3 ;Wert von WREG? ..... RETURN mfG GroberKlotz
Hallo GroberKlotz, 12 ?????????????? Nachdem ich das Programm "vereinfacht" und den Fehler für die falsche Berechnung der Zeit gefunden habe, läuft es mit 24 Befehlen in "Main". Wäre schön, wenn du mir deine Assembler-Datei zukommen lassen würdest, es interessiert mich ja doch, wie du die Aufgabe lösen konntest. Das nächste Übungsprojekt wird das Abfragen von Eingängen, um z.B. auf Taster reagieren zu können. Z.B. die Zeit für die Zeitschleife mit Plus- und Minus-Tasten zu ändern, oder und ein Abschalten der Leds in umgekehrter Reihenfolge zu realisieren. Schöne Grüße, Norbert
Hallo Norbert, hier die Auflösung! mfG GroberKlotz
... oder so! :-))) Danke für diese Lösung. Ich habe in der Zwischenzeit weiter "programmiert" und ausprobiert. Jetzt habe ich es geschafft, per Taster an RA0 eine LED an RB0 ein- und auszuschalten. (siehe ASM-Datei) Dazu habe ich zum Entprellen eine Zeitschleife eingebaut. Nachdem ich versucht habe (und das auch erstmal wieder verworfen), die Dauer des Tastendrucks in das Programm einfließen zu lassen, kamen mir Zweifel auf, ob das der richtige Weg ist. Bei meinen Versuchen wurde das Programm immer länger und größer, nur um die Schaltzustände der Tasten zu überwachen und auszuwerten. Während dessen "steht" das eigentliche Programm (z.B.: Taste 2 Sekunden drücken, dann springe zu...). Das kann nicht richtig sein. In diesem Forum und auch auf anderen Seiten, liest man, dass man das Auswerten von Tasterzuständen mit Hilfe eines Timers und Interrupt lösen sollte. Ist das der richtige Weg? Wird während dessen das eigentliche Programm weiter ausgeführt? Schöne Grüße, Norbert
Hallo Norbert Zum Ein- und Ausschalten einer LED per Taster ist es wohl ausreichend die Entprellung mittels einer Zeitschleife vorzunehmen. Sollen aber auch andere Funktionen parallel ausgeführt werden geht das so nicht. Leider ist die MCU (MicroController Unit) in der Zeitschleife gefangen und kann bis zu deren Ende keine anderen Aufgaben erfüllen. Nimm mal an, dass Du eine Uhr programmiert hast. Dann möchtest Du aus irgendwelchen Gründen per Tastendruck an einem Pin ein LED einschalten, oder eine externe zeit stoppen (kann ja auch noch was anderes sein). Während der Zeitschleife wird Deine Uhr nicht mehr weitergestellt. Nach dem Tastendruck der ja z.B. beliebig lange dauern kann, wird die Uhr nachgehen, denn sie wurde ja nicht mehr weiter gestellt. Es gibt diese Möglichkeiten: Interrupt (Kapitel 14.5 Datenblatt) Tasterabfrage per Interrupt, dessen Zeittakt man festlegen kann. Z.B. 100ms Die ISR (Interrupt-Service- Routine) stellt die Uhr während z.B. jedem 10. Interruptdurchlauf um 1 Sekunde weiter. Alle 1/10 Sekunden werden die Tasten abgefragt. Falls eine Taste gedrückt ist, setzt man ein Flag und verarbeitet dieses Flag im Hauptprogramm weiter. Dabei zählt man auch einen Zähler hoch, der z.B. jede 1/10s incrementiert. Dabei frägt man den Zustand des Tasters ab und erst wenn z.B. 5x hintereinander der gleiche Tasterzustand erkannt wurde, wird die Aktion welche der Taster auslösen soll ausgeführt. Dazu solltest Du Dir mal im Datenblatt das Kapitel zum Interrupt durchlesen und mit Interrupts zu experimentieren beginnen. Wenn es klemmt kannst Du Dir ja hier Rat holen. Compare (Kapitel 9, Datenblatt) Der 16F628 hat ein Compare-Modul. Da legst Du mit einem Register fest, bei welchem Zählerstand der Timer 1 ein Ereignis auslösen soll. Dies wird z.B. durch den Zustand des Flags "CCP1IF" im Register PIR1 angezeigt. Dann kannst Du z.B. die Sub "LED einschalten" so abfragen: Main ...irgendwelcher code btfsc PIR1,CCP1IF Call LED_einschalten ...irgendwelcher code GOTO Main Jetzt wird nur dann die LED eingeschaltet wenn die durch den Timer 1 vorgegebene Zeit abgelaufen ist und das Flag CCPIF den zustand "1" eingenommen hat. So, dass müsste mal fürs erste reichen. Ist ein interessantes Thema und Du musst Dich halt einarbeiten, Im Internet gibt es so wie hier im Forum jede Menge Informationen. mfG Ottmar
Danke Ottmar, Mikrocontroller insgesamt ist ein sehr interessantes Thema. Mir macht es jedenfalls Spaß, besonders jetzt wo ich hin und wieder kleine Erfolgserlebnisse habe. Ich versuche mich jetzt mal an den Interrupts und Timern. Das von mir ausgedruckte Datenblatt des PIC16F628 sieht schon ziemlich gebraucht aus, auch das griffbereit liegende English-Deutsch-Wörterbuch. Ist schon so lange her mit dem English ... :-) Danke nochmal und bis bald, Norbert
Hallo Norbert, mein erstes Datenblatt des 16F628 habe ich mir auch ausgedruckt, zumindest die mich interessierenden Passagen. Insgesamt ist es aber zu aufwendig. Ich hoffe Du weißt dass man das Datenblatt in das Projektfenster von MPLAB ganz einfach per Drag and Drop als Link reinschieben - und von dort aus mit einfachem Mausklick öffnen kann? Dazu habe ich den unglaublich großen Adobe-PDF-Reader abgeschaftt und den kostenlosen Sumatra-PDF installiert [http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader-de.html]. So lässt sich das Datenblatt im PDF-Reader öffnen und wenn ich nach einem Begriff im Datenblatt suche, hilft das Suchen-Fenster im Reader, bzw. die Indexspalte rasch weiter. Aus meinem Code-Vorrat habe ich Dir eine Interrupt-Routine zur Zeitmessung und Tastenabfrage beigefügt. Schau die Code-Schnipsel an, vielleicht verkürzen diese Deinen Lernprozess. mfG Ottmar
Ottmar K. schrieb: > Ich hoffe Du weißt dass man das Datenblatt in das > Projektfenster von MPLAB ganz einfach per Drag and Drop als Link > reinschieben - und von dort aus mit einfachem Mausklick öffnen kann? > mfG Ottmar Hallo Ottmar, jetzt ja. :-) Ich nutze den PDF-XChange-Viewer. Klappt damit auch sehr gut. Hab es gerade ausprobiert. Ich habe aber lieber was zum Blättern in der Hand. Vielen, vielen Dank für die Hilfe und die Tips und natürlich für die Interrupt-Routine. :-))) Schöne Grüße, Norbert
Prima, wenn ich Dir ein wenig weiterhelfen konnte :-)! Noch was: in der ISR hat sich da doch eine Zeile heimlich davon gemacht: FALSCH: movlw d'250' ;Zähler wieder auf 250 setzen call Uhr_Intern ;Interne Uhr 1 Sekunde weiterschalten RICHTIG: movlw d'250' ;Zähler wieder auf 250 setzen movwf cnt4ms ;und wieder bereit zum herunterzählen call Uhr_Intern ;Interne Uhr 1 Sekunde weiterschalten mfG Ottmar
Guten Morgen, nach einer langen PIC-Programmier-Pause, habe ich hoffentlich nur ein kleines Problem. Ich vermute, das ich irgendetwas übersehen habe. Ich habe eine kleine Schaltung mit einem PIC16F628A als SMD, um das Programmieren in einer Schaltung (ICSP) und den internen Oscilator auszubrobieren. Die Aufgabe soll sein, das nach einem Reset ein Ausgang RB0 für eine paar Sekunden einen MOS-FET durchschaltet. Das klappt so weit ganz gut. Nun gibt es folgenden Effekt: Während der Reset-Taster gedrückt wird, läuft das Programm im PIC ungestört weiter. Es startet zwar nach Ablauf der Zeit erneut wenn der Reset-Taster gedrückt wird, aber eben nicht während das Programm läuft. Ich nutze den internen Oscilator und habe alle Pins auf Ausgang gestellt, außer PIN RA5 für den Reset, der ja eh nur die Funktion eines Eingangs bekommen kann. Was habe ich übersehen? Aus dem Datenblatt ist zu entnehmen, das der PIC sofort stoppt, wenn Reset an RA5 ausgelöst wird und solange der Taster gedrückt wird. So kenne ich das auch von meinen anderen Programmier-Versuchen mit externen Oscilator. Schöne Grüße, Norbert
Hallo Norbert, ...so trifft man sich wieder :-). Schau mal in das Datenblatt des 16F628, S.99. Dort ist ein Blockschaltbild zum RESET. Verfolge den Weg der RESET-Leitung und Du wirst sehen, dass diese an einem RS-Flip-Flop endet. Das bedeutet, egal wie lange Du auf dem Resettaster bleibst, beim ersten Tastendruck(Low-Inpuls) am Reseteingang, löst das FlipFlop den internen Chip-Reset aus. Meines Wissens ist das RS-Flip-Flop mit dominantem Rücksetzeingang versehen. Der nächste Oszillatorimpuls des On-Chip-Oszillators setzt den internen Chip-Reset wieder zurück. Das Spielchen hält wohl so lange an, wie Du den Resettaster drückst. Dein Verfahren, den PIC per Reset zu steuern ist gelinde gesagt unüblich. Lass doch den PIC durchlaufen: 1. Tastendruck - wird der FET durchgeschaltet 2. FET wird eingeschaltet 3. Delay 4. FET wird abgeschaltet 5. Warten auf den nächsten Tastendruck 6. Tastendruck 7. Weiter bei 1. mfG Ottmar
Hallo Ottmar, vielen Dank für deine Geduld und die Info. Das Programm habe ich auch für einen "richtigen" Taster geschrieben und es läuft auch. Vielleicht habe ich mich nicht richtig ausgedrückt. Was ich schreiben wollte ist folgendes: Der SMD-Pic P16F628A scheint sich in der gleichen Schaltung anders zu verhalten, wie sein "großer" Bruder in DIL-Bauweise. Letzterer beendet sofort sein Programm sobald ich den Reset-Taster betätige, während der SMD-Baustein munter weiter tobt. Ist bei ihm regulär das Programm beendet, startet das Programm neu, läßt sich während des Ablaufs aber nicht von der Reset-Taste beeindrucken. Ich habe für die SMD-Schaltung eine Platine geätzt, die DIL-Version auf einem Steckbrett zusammen getüddelt. Beide Versionen funktionieren mit dem "richtigen" Taster einwandfrei, nur eben die Reset-Funktion ist eine andere, bzw. hat eine andere Wirkung. Nachdem mir das mit der Reset-Funktion aufgefallen ist, habe ich das Programm geändert und frage mich, ob die SMD-Version sich anders verhält oder ich irgendetwas übersehen habe, oder ich bei ICSP im Brenner noch irgendwo was umstellen muss - oder beides ;-) Ich suche weiter...
Das heißt also dass der PIC auf den Resettaster gar nicht reagiert? Dann bleiben ja nur diese Möglichkeiten: a) Fehler auf der Platine b) Configword fehlerhaft (_MCLRE_OFF ist aktiviert) c) Fehlerhafter Anschluss RA5 (Pull Up nach +5V evtl. C ca. 100nF nach GND?? Ansonsten solltest du diese Frage mal im microchip-forum stellen. mfG Ottmar
Eine Funktion hat der Resettaster. Nach Ablauf des Programmes wird das Programm gestartet, sobald ich die Resettaste betätigt habe. Es startet auch dann, wenn ich die Taste gedrückt halte. - Configword MCLRE_ON ist im Programm eingetragen - Pull-Up-Widerstand ist vorhanden und auch von Pin RA5 gegen UB meßbar (RA5 wird auch bei Betätigung des Taster auf Masse gezogen) - Im Platinen-Layout konnte ich keinen Fehler feststellen. Ich fertige ein komplett neues an und probiere es dann nochmal. Der einzige für mich erkennbare Unterschied zwischen Steckbrett und SMD-Platine ist der, dass ich auf dem Steckbrett einen BC546 und auf der SMD-Platine einen MOS-FET als Schalter nutze. Ich melde mich sobald ich herausbekommen habe, woran es liegt, bzw. lag. Danke für deine Hilfe! Schönen Abend noch, Norbert
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.