Halloo Jungs, ich habe ein problem... warum kann ich so keine 2 Ausgänge gleichzeitig auf logisch 1 schalten?? bsf PORTA,0 bsf PORTA,1 call wait3s ; Wartezeit von 3s bcf PORTA,0 bcf PORTA,1 hat jemand eine ide?? PIC 16F628A Assembler Mario
Mario Horvat schrieb: > warum kann ich so keine 2 Ausgänge gleichzeitig auf logisch 1 schalten?? WIe meinst Du das? Was geht denn nicht?
Mario Horvat schrieb: > warum kann ich so keine 2 Ausgänge gleichzeitig auf logisch 1 schalten?? Wer sagt, dass es nicht geht. Bzw-Weise woran machst du fest, dass es nicht geht ? Taktquelle, Stromversorgung, Schaltplan, Layout, kompletter Code, ist PORTA definiert, wie sieht die wait loop aus, Config-Bits ? Es gibt tausende Fehlerquellen - alles was oben steht müssen wir wissen ... Mario Horvat schrieb: > hat jemand eine ide?? um eine Idee zu haben bräuchte man mehr Infos. Dem Fakt, dass du annimmst, dass du keine 2 Ausgänge gleichzeitig auf logisch 1 schalten kannst entnehme ich, dass deine Anwendung nicht funktioniert ?! Oder möchtest du wissen wie du 2 Bits auf einmal setzten kannst ?
alsoo sobald ich auf die taste drücke die mir diese 2 ausänge setzten würden, ist nur auf einem Ausgang logisch 1 und beim 2 bleibt 0..... genau ich kann keine 2 Ausgänge auf logisch 1 schalten.. Schaltplan mitdabei
mit BSF bzw. BCF kann man keine Ausgänge gleichzeitig schalten, da sind 4 Oszillatortakte dazwischen. Es geht aber trotzdem: MOVFW PORTA ; Port A lesen ANDLW B'11111100', W ; Bit 0 und 1 löschen MOVWF PORTA ; Port A zurückschreiben MOVFW PORTA ; Port A lesen IORLW B'00000011',W ; Bit 0 und 1 setzen MOVWF PORTA ; Port A zurückschreiben oder auch MOVLW B'11111100', W ; Bit 0 und 1 sollen gelöscht werden ANDWF PORTA, F ; Port A lesen, ändern und zurückschreiben MOVLW B'00000011', W ; Bit 0 und 1 sollen gesetzt werden IORWF PORTA, F ; Port A lesen, ändern und zurückschreiben
Hi, Mario Horvat schrieb: > Halloo Jungs, > > ich habe ein problem... > > warum kann ich so keine 2 Ausgänge gleichzeitig auf logisch 1 schalten?? > > > bsf PORTA,0 > bsf PORTA,1 > call wait3s ; Wartezeit von 3s > bcf PORTA,0 > bcf PORTA,1 > > hat jemand eine ide?? > > PIC 16F628A > Assembler > Mario Hat da jemand nicht das Datenblatt gelesen... Natürlich kannst du zwei Ausgänge gleichzeitig schalten... Was du nicht kannst ist zwei Pins desselbens Ports extrem KURZ nacheinander schalten wie du es tust. Wenn du mit BSF das Register eines Ports veränderst, dann braucht der Ausgangstreiber einige ns bis die Spannung am Ausgang auch tatsächlich vorhanden ist (Anstiegszeit!) Bei einem zugriff auf Porta (Portb, Portc...) mit bsf, bcf usw. passiert nun folgendes: Als erstes wird der aktuelle Portzustand eingelesen, dann wird das jeweilige Bit gesetzt und dann zurückgeschrieben. Wenn deine Taktfrequenz nun nicht gerade langsam ist passiert bei deiner methode nun das > bsf PORTA,0 ;Das BIT 0 im Register PORTA 0 wird auf 1 gesetzt, Die Spannung am PORTA 0 beginnt zu steigen! > bsf PORTA,1 ; Nun wird PORTA aber als ganzes sofort wieder eingelesen... je nach Takt ist die Spannung an PORTA 0 aber noch gar nicht über die HIGH schwelle gekommen, wird also als LOW gelesen, Das Ergebniss mit dem fälschlich als LOW gelesenen PORTA0 wird nun an Bit 1 auf HIGH gesetzt und mit dem falsch erkannten LOW an PORTA0 (zum Beispiel als 00000010) zurückgeschrieben. Im Ergebniss ist PORTA0 dann wieder LOW, PORTA1 aber High... Abhilfe: Man könnte es so machen: > bsf PORTA,0 > nop > nop > nop > nop > bsf PORTA,1 ich glaube 4 Befehlszyklen waren empfohlen, schaue aber noch mal unter PORTS in DB. Diese Lösung ist aber nicht die Optimale. Wenn du an dieser Stelle des Programms weist wie die anderen BITS von PORTA aussehen kannst du natürlich auch direkt das ganze Byte schreiben: > movlw b'00000011' > movwf PORTA kann der Zustand der anderen PORTAUSGÄNGE verschiedene Zustände zu diesem Zeitpunkt annehmen muss man OR (oder) verknüpfen: > movlw b'00000011' > iorwf PORTA, 1 (setzt nur die beiden Ausgänge PORTA0 &1 auf High, der Rest belibt unverändert) Analog dazu kann man dann mit der AND Verknüpfung auch geziehlt mehrere Ausgänge gleichzeitig löschen: statt: > bcf PORTA,0 > bcf PORTA,1 also > movlw b'11111100' > andwf PORTA, 1 GRuß Carsten
Carsten Sch. schrieb: > Was du nicht kannst ist zwei Pins desselbens Ports extrem KURZ > nacheinander schalten wie du es tust. Uff das hab ich auhc noch nicht gewusst;) Aber ergibt Sinn. Ich hab in der Ausbildung mal einen PIC16F84 mit 4MHz Takt gehabt (Programmtakt 1MHZ) und da hats funktioniert. Ist warscheinlich zu langsam gewesen. Doch egal wie schnell es geht, mit dieser Methode ist es (meiner Meinung nach) am besten gelöst und ist auch wirklich gleichzeitig (oder am gleichzeitigsten;) ) tt4u schrieb: > Es geht aber trotzdem: > > MOVFW PORTA ; Port A lesen > ANDLW B'11111100', W ; Bit 0 und 1 löschen > MOVWF PORTA ; Port A zurückschreiben > > MOVFW PORTA ; Port A lesen > IORLW B'00000011',W ; Bit 0 und 1 setzen > MOVWF PORTA ; Port A zurückschreiben
Es handelt sich vermutlich um das "read-modify-write" Problem. Ein bsf Befehl auf eine Portadresse liest erstmal die anliegenden Daten ein. Dann wird das entsprechende Bit gesetzt und die Daten werden wieder ausgegeben. Beim ersten Mal klappt das auch. Beim zweiten Befehl ist aber das gesetzte Bit des vorhergehenden Befehls noch nicht am Port angekommen (z.B. wegen kapazitiver Belastung) und wird wieder als low eingelesen und dann wieder ausgegeben. Mach mal ein oder wenn das nicht reicht auch zwei nop zwischen die beiden Befehle. Die neueren PICs haben deshalb zwei Register für jeden Port, zum Lesen das PORT und zum Schreiben das LATCH. Grmpf, zu lange getippt ...
Hammer, wusste ich auch nicht, muss gleich mal gucken ob das beim AVR auch so ist ;-) Da wäre mir das bislang noch nicht aufgefallen.
Alsoo beim AVR dürfte das aufgrund des extra Latch Registers PORTn kein Thema sein, aber die Funktionsweise ist wohl auch hier Read-Modify-Write.
Ja. Allerdings wird der Ausgangszustand separat gespeichert. Wobei die Treiber auch nicht so abartig lahm sind, ein paar MHz bekommt man da schon am Pin gewackelt. Mein liebes Beispiel: DDRx = 1, PORTx = 1, dann den Pin außen kurzschließen. PORTx liest 1, PINx liest 0... Hatten die PIC nicht auch irgendwo mal solche 'LAT'-Registersätze?
AD-Wandler abgeschaltet?? Sonst machen die bcf/bsf Befehle auf dem PORTA genau solche blöden Effekte... PIC16F628 hat AD-Wandler, PIC16F84 nicht.
Sven P. schrieb: > DDRx = 1, PORTx = 1, dann den Pin außen kurzschließen. PORTx liest 1, > PINx liest 0... Öhm, wie lange hält er das aus? ;-)
Geist schrieb: > AD-Wandler abgeschaltet?? Sonst machen die bcf/bsf Befehle auf dem PORTA > genau solche blöden Effekte... > PIC16F628 hat AD-Wandler, PIC16F84 nicht. Nööö... Mit den AD Wandlern hat das nichts -aber gar nichts- zu tun... Das wurde oben schon von drei verschiedenen Usern (incl. mir) richtig beantwortet. Siehe auch das Datenblatt zum PIC16F628 PIC16F628 DB - Seite 42 Abschnitt 5.3.1 BI-DIRECTIONAL I/O PORTS > Any instruction which writes, operates internally as a > read followed by a write operation. The BCF and BSF > instructions, for example, read the register into the > CPU, execute the bit operation and write the result > back to the register PIC16F628 DB - Seite 42 Abschnitt 5.3.2 SUCCESSIVE OPERATIONS ON I/O PORTS > The actual write to an I/O port happens at the end of an > instruction cycle, whereas for reading, the data must be > valid at the beginning of the instruction cycle (Figure 5- > 16). Therefore, care must be exercised if a write > followed by a read operation is carried out on the same > I/O port. (Anmerkung: Wie im Zitat von 5.3.1 zu sehen ist, ist ein Write durch BCF/BSF auch eine Read operation! Daher gilt dies also auch für BCF/BSF) > The sequence of instructions should be such > to allow the pin voltage to stabilize (load dependent) > before the next instruction which causes that file to be > read into the CPU is executed. Otherwise, the previous > state of that pin may be read into the CPU rather than > the new state. When in doubt, it is better to separate > these instructions with a NOP or another instruction not > accessing this I/O port. Gruß Carsten
Carsten Sch. schrieb: > Nööö... > Mit den AD Wandlern hat das nichts -aber gar nichts- zu tun... Wir haben beide Recht ;-) Ports, die auf 'analog' stehen, ergeben beim Einlesen über den PORT-Befehl wohl immer eine Null. Was natürlich bei den bcf/bsf (Read-modify-write Befehle!) zu seltsamen verhalten führt. Weil setzen kann man so einen analogen Port, alber bein lesen kommt doch wieder Null zurück. Egal ob AD-Wandler oder Komperator-Eingänge.
Sehr lesenswert in diesem Zusammenhang: http://www.sprut.de/electronic/pic/fallen/fallen.html (das in diesem Thread genannte Problem wird unter "Die in/out-Falle" erläutert)
Hi, Dirk W. schrieb: > Sehr lesenswert in diesem Zusammenhang: > > http://www.sprut.de/electronic/pic/fallen/fallen.html > > (das in diesem Thread genannte Problem wird unter "Die in/out-Falle" > erläutert) guter Link, nur der Unterabschnitt ist nur Fast richtig... Die IN/OUT Falle beschreibt ein anderes "Problem" das aber natürlich die Grundlage in demselben VErhalten hat wie das hier behandelte Problem. Zutreffend ist hier: "Die I/O-Speed-Falle" von derselben Seite. Geist schrieb: > Wir haben beide Recht ;-) Naja, nicht ganz, denn was du hier beschreibst: > Ports, die auf 'analog' stehen, ergeben beim Einlesen über den > PORT-Befehl wohl immer eine Null. Was natürlich bei den bcf/bsf > (Read-modify-write Befehle!) zu seltsamen verhalten führt. Weil setzen > kann man so einen analogen Port, alber bein lesen kommt doch wieder Null > zurück. > > Egal ob AD-Wandler oder Komperator-Eingänge. ist eine Sonderversion der "In / Out Falle" um bei der verlinkten Sprut Seite zu bleiben. Für diesen Thread passt das aber nicht, da ja ein Analogeingang kein Ausgang sein kann und hier ja keine Umschaltung stattfindet! Gruß Carsten
Carsten Sch. schrieb: > Für diesen Thread passt das aber nicht, da ja ein Analogeingang kein > Ausgang sein kann und hier ja keine Umschaltung stattfindet! Oh doch, ist ein undokumentiertes 'Feature' von Microchip. Zumindest bei den 16er PICs, im speziellen der 16F877 (getestet, leider...). Also vermutlich auch der 16F628. Der ist ja so etwa aus der selben Generation.
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.