Hi! Seit etwa einer Woche beschäftige ich mich mit PICs, z.Z. eigentlich nur mit dem 18F1220 (weil ich lieber in C schreiben möchte). Ich benutze MPLAB X und PICkit3. Soweit so gut! Bis jetzt habe ich es geschafft Ports ein und auzuschalten (LED blinken lassen), den Wert eines Potis mit ADC zu bestimmen und ein LCD zu initialisieren (mehr oder weniger gut). Nun wollte ich wegen dem LCD die Busy-Flag abfragen können und da viel mir auf, dass ich bis dahin noch nie ein High-Low Signal an einem Pin abgefragt habe. Doch genau das bekomm ich einfach nicht gebacken und weiß nun einfach nicht mehr weiter... :( Also, ich habe mir einen PIN vom PORTB (RB4 - Pin 11) als Eingang deklariert: TRISB = 0b00001000; oder TRISB=0x08; (da 1 = Input) PORTB = 0x00; Laut Datenblatt ist PORTB prinzipell auf TTL geschaltet. Ich frage RB4 ab: if (PORTB & 0b00001000) { LED_blink(); } Wenn ich 5V auf RB4 lege passiert aber nichts! -Warum? Was mache ich falsch? (die if-Abfrage wird natürlich permanent abgefragt) Würde mich wirklich freuen, wenn mir jemand hier unter die Arme greifen könnte! :)
Gerrit schrieb: > Ich frage RB4 ab: > > if (PORTB & 0b00001000) { LED_blink(); } Kann es sein, dass du Bit 3 abfragst? Zähliung gebinnt ja mit 0. (Kenne mich aber nicht mit PICs aus !)
funktioniert "LED_blink();" alleine? falls nein, liegt da der hund begraben. ps: busy-flag (pin) abfragen, macht eigentlich niemand; warte lieber ein bischen, wie alle anderen auch ;-)
Das war nur ein Tippfehler. Ich frage so natürlich RB3 ab. Aber genau an dem "arbeite" ich auch... :(
ja, wenn ich die if-Abfrage mit irgend einem Mist auf 1 setze, läuft das Unterprogramm.
Gerrit schrieb: > Also, ich habe mir einen PIN vom PORTB (RB4 - Pin 11) als Eingang > deklariert: > > TRISB = 0b00001000; oder TRISB=0x08; (da 1 = Input) > PORTB = 0x00; soweit gut. Die Zuweisung PORTB = 0x00;? Die läuft doch hoffentlich nicht in der Endlosschleife oder? In PORTx wird NIE NIE NIE NIE geschrieben. Wenn ich schreiben möchte (nur bei Output) dann schreibt man in LATx. In PORTx wird nur gelesen. Gerrit schrieb: > Ich frage RB4 ab: > > if (PORTB & 0b00001000) { LED_blink(); } Auch das ist soweit strukturtechnisch richtig. Du frägst Bit3 ab. Also RB3 und nicht wie von dir gewünscht RB4. Da hat mein Vorredner vollständig recht.
also, ich habs jetzt geändert... ich pack jetzt mal das gesamte programm hier rein. im moment läuft das programm so ab: eien led blinkt in anhängigkeit eines potis. dann die besagte abfrage. WENN LED_blink läuft, blink es nur noch sehr sehr langsam. nur komm ich da so nie hin... --------------------------------- #include <stdio.h> #include <stdlib.h> #include <p18f1220.h> #include "delays.h" #include <adc.h> #pragma config OSC = HS #pragma config WDT = OFF #pragma config LVP = OFF int speicher = 0, i = 0; void LED_blink(void); void main(void) { INTCON = 0X00; ADCON0 = 0b00000100; ADCON1 = 0b00000000; ADCON2 = 0b10000011; TRISA = 0xFE; LATA = 0x00; TRISB = 0b00010000; LATB = 0x00; while (1) { ADCON0bits.ADON = 1; ADCON0bits.GO_DONE = 1; while(ADCON0bits.GO_DONE) { speicher = ADRES; } if (i>speicher) { LATA=0x00; } if (i<speicher) { LATA=0x01; } if (i==1024) { i=0; } i++; if (PORTB & 0b00010000) { LED_blink(); } } } void LED_blink(void) { PORTA=0x00; Delay1KTCYx(1000); PORTA=0x01; Delay1KTCYx(1000); }
Jetzt versteh ich garnicht mehr... Ich schreibe nun PORTB ständig in eine Variable und mach ein break bei write. Habe PORTB komplett als Eingang deklariert und dann alle Pins mal auf 5V gelegt. Ergebnis. RB4 funktioniert nicht!!! Habs jetzt auf RB5 umgestellt un nun klappt alles wie gewünscht! Dabei habe ich festgestellt, dass die "1" auch noch kurz nachdem das Kabel gezogen wurde noch steht. Daher hab ich nun RB5 über einen Widerstand an GND gelegt, damit der Pin sofort wieder auf 0 fällt. Kann es sein, dass ich mir den RB4 PIN zerstört habe, weil ich keinen Widerstand verwendet habe???
Gerrit schrieb: > if (PORTB & 0b00010000) { Du kannst auch schreiben: if (PORTBbits.RB4) { Genauso gibts: LATBbits.LATBx PORTBbits.RBx TRISBbits.TRISBx (x zwischen 0 und 7) Das gibt auch für die anderen Ports. Das ist vielleicht übersichtlicher. Und LATAbits.LATA0=1; funktioniert natürlich auch. fchk
Gerrit schrieb: > Kann es sein, dass ich mir den RB4 PIN zerstört habe, weil ich keinen > Widerstand verwendet habe??? Wahrscheinlicher ist, dass Du in die Analogpin-Falle getappt bist. Schau mal, welche Funktionen noch auf dem Pin liegen. Siehst Du das AN6? Bei den PICs ist es so, dass alle Pins mit Analogfunktionen auf Analog stehen. Du musst die Pins, erst auf digital umschalten. Das machst Du mit dem Register ADCON1 (falls die Familie nur max 8 Analogpins hat) oder ADCONx (x=1...n, je nachdem, wie viele Analogpins da sind, siehe Datenblatt). Wenn Du keine Analogfunktionen nutzt, mach einfach ein ADCON1=0xff; und dann geht das. PS: Da fällt jeder mal drauf rein. fchk
VIELEN, VIELEN, VIELEN DANK!!! -Das scheint es gewesen zu sein! Jetzt klappt´s an allen Pins! Das einzige, was mich noch ein wenig stuzig macht ist aber, dass an manchen Pins ohne Widerstand zu GND die Spannung recht lange gehalten wird! Das scheint so aber normal zu sein, oder? Nochmals danke!
Lehrmann Michael schrieb: > In PORTx wird NIE NIE NIE NIE geschrieben. Wenn ich schreiben möchte > (nur bei Output) dann schreibt man in LATx. In PORTx wird nur gelesen. Ich hab das schon öfter gelesen und gehört. Doch im Datenblatt steht ja: "Reading the PORTA register reads the status of the pins, whereas writing to it will write to the port latch. The Data Latch register (LATA) is also memory mapped. Read-modify-write operations on the LATA register read and write the latched output value for PORTA." ... "EXAMPLE 10-1: INITIALIZING PORTA:
1 | CLRF PORTA ; Initialize PORTA by |
2 | ; clearing output |
3 | ; data latches |
4 | CLRF LATA ; Alternate method |
5 | ; to clear output |
6 | ; data latches |
-> ALTERNATE, also Alternative Methode. Ich frag nur aus einem Grund: Ich hab mit PIC-Programmierung auf einem 16F84A angefangen und dieser hat wie manch andere alte PICs kein LATx Register. Deshalb ist bei mir drinne in PORTx zu schreiben und zu lesen. Und auch bei den neueren PICs, die ein LATx Register haben, funktioniert es auch mit PORTx. Warum MUSS/SOLL man UNBEDINGT das LATx-Register benutzen? Frank K. schrieb: > PS: Da fällt jeder mal drauf rein. Das stimmt;) Gerrit schrieb: > Das einzige, was mich noch ein wenig stuzig macht ist aber, dass an > manchen Pins ohne Widerstand zu GND die Spannung recht lange gehalten > wird! Das scheint so aber normal zu sein, oder? Welche denn genau? Vielleicht hängt es mit einem Internem Modul zusammen. Eine Kapazität hast du aber nicht dran, oder?
Gerrit schrieb: > Dabei habe ich > festgestellt, dass die "1" auch noch kurz nachdem das Kabel gezogen > wurde noch steht. Daher hab ich nun RB5 über einen Widerstand an GND > gelegt, damit der Pin sofort wieder auf 0 fällt. Welches Kabel ziehst du denn? Wenn es das Kabel vom Netzteil ist, dann ist es klar, wobei es bei allen PINs sein sollte. Im Netzteil ist ein Kondensator drin, der erstmal entladen werden muss. Wie beim Fernseher, wo die Standby-LED auch langsam ausgeht.
ne ne... nur das kabel, was ich auf RB4 gelegt hab... das meine ich mit "ziehen".
Gerrit schrieb: > Das einzige, was mich noch ein wenig stuzig macht ist aber, dass an > manchen Pins ohne Widerstand zu GND die Spannung recht lange gehalten > wird! Das scheint so aber normal zu sein, oder? Als Eingänge sind µC Ports sehr hochohmig, Sie halten die Ladung lange und wenn nichts dranhängt ist der Wert Zufall.
Der Rächer der Transistormorde schrieb: >> Das einzige, was mich noch ein wenig stuzig macht ist aber, dass an >> manchen Pins ohne Widerstand zu GND die Spannung recht lange gehalten >> wird! Das scheint so aber normal zu sein, oder? > > Als Eingänge sind µC Ports sehr hochohmig, Sie halten die Ladung lange > und wenn nichts dranhängt ist der Wert Zufall. perfekt! habs mir aber schin iwie gedacht... ;) danke euch allen!
Michael Skropski schrieb: > Ich frag nur aus einem Grund: > Ich hab mit PIC-Programmierung auf einem 16F84A angefangen und dieser > hat wie manch andere alte PICs kein LATx Register. Deshalb ist bei mir > drinne in PORTx zu schreiben und zu lesen. Und auch bei den neueren > PICs, die ein LATx Register haben, funktioniert es auch mit PORTx. Warum > MUSS/SOLL man UNBEDINGT das LATx-Register benutzen? Read-Modify-Write-Zyklen. PORTA|=0x01; heißt: PORTA lesen Bit setzen LATA(!!!) schreiben (PORTA ist ja read-only, Schreibzugriffe auf PORTA landen tatsächlich in LATA) Heißt: LATA wird abhängig von externen Zuständen modifiziert. Das kann dazu führen, dass bei der obigen Anweisung nicht nur Bit 0 in LATA geändert wird, sondern auch andere Bits, was aber beim Anblick der Programmzeile so nicht auf dem ersten Blick klar ist. Das garantiert viele Stunden Spaß bei der Fehlersuche insbesondere bei Open-Collector-Schaltungen. Bei LATA|=0x01; heißt das: LATA lesen Bit setzen LATA schreiben. Heißt also: In LATA wird unter Garantie nur Bit 0 geändert, sonst nichts. Das ist auch das Verhalten, das ich erwarte. fchk
Frank K. schrieb: > Heißt: LATA wird abhängig von externen Zuständen modifiziert. Das kann > dazu führen, dass bei der obigen Anweisung nicht nur Bit 0 in LATA > geändert wird, sondern auch andere Bits, was aber beim Anblick der > Programmzeile so nicht auf dem ersten Blick klar ist. Das garantiert > viele Stunden Spaß bei der Fehlersuche insbesondere bei > Open-Collector-Schaltungen. Versteh mich nich falsch, ich glaub dir ja und will keinen auf trozig machen, nur will ich es verstehen. Bei "PORTA|=0x01;" ließt er die Pegel am PORT, setzt das bit und schreibt es wieder ins Latch (da WR PORT und WR LAT gleich sind, Siehe Datenblatt Seite 88 [PDF 90], http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf ). Bei "LATA|=0x01;" ließt er die Latches, also die Soll-Pegel, und setzt dort das Bit und schreibt es ins Latch. Doch die Soll-Pegel sind doch dann am PORT. Zumindest bei den als Ausgang definierten Pins, doch die sind ja auch nur die von interesse. So wie ich das im Moment verstehe, ist es so, dass es nur einen Unterschied macht, wenn der Sollwert nicht am Pin anliegt. Und dies wäre ja nur, wenn von außen ein Pegel erzwungen wird was einem Kurzschluss gleichkommt. Danach kann man den Pin sowieso vergessen. Kleines Beispiel:
1 | TRISB = 0xF0; // An RB4..7 sind Pulldown-R's, RB0..3 ist Ausgang |
2 | |
3 | PORTB |= 0x01; // RB0 soll auf High gesetzt werden |
4 | // 1. Schritt: PORTB lesen -> 00000000
|
5 | // 2. Schritt: bit setzen -> 00000001
|
6 | // 3. Schritt: PORTB bzw LATB schreiben -> 00000001
|
7 | // Ausgang ist auf High, dass Latch wird ja geschaltet und der MOSFET schaltet den Ausgang
|
8 | |
9 | PORTB |= 0x02; // RB1 soll auf High gesetzt werden |
10 | // 1. Schritt: PORTB lesen -> 00000001
|
11 | // 2. Schritt: bit setzen -> 00000011
|
12 | // 3. Schritt: PORTB bzw LATB schreiben -> 00000011
|
13 | // Ausgang ist auf High, dass Latch wird ja geschaltet und der MOSFET schaltet den Ausgang
|
Frank K. schrieb: > Heißt also: In LATA wird unter Garantie nur Bit 0 geändert, sonst > nichts. Das ist auch das Verhalten, das ich erwarte. Das ergibt Sinn, nur frag ich mich eben, warum das im anderen Fall nicht so ist. Das Latch schaltet ja den Ausgang auf den gewünschten Zustand und den liest man dann mit PORTB ein. Im Blockdiagramm für RB2 sieht man das ganz gut. Das D-FF wird gesetzt, es geht durch den (durch TRISB) "angeschalteten" Buffer zum Ausgang. Wenn man dann ließt, ließt man genau das, was man vorne reingegeben hat.
Michael Skropski schrieb: > So wie ich das im Moment verstehe, ist es so, dass es nur einen > Unterschied macht, wenn der Sollwert nicht am Pin anliegt. Und dies wäre > ja nur, wenn von außen ein Pegel erzwungen wird was einem Kurzschluss > gleichkommt. Danach kann man den Pin sowieso vergessen. Nicht unbedingt. Du könntest z.B. den Pin mit dem ODCx Register auf Open Drain schalten.(*) Dann kann der Pin nur noch gegen Ground ziehen, gegen VDD wird er durch einen Pullup gezogen. Wenn der Pin extern auf Ground gezogen wird, willst Du es garantiert nicht, dass Du dann den zufällig auch auf Ground ziehst, nur weil Du irgendeinen anderen Pin änderst. Das würde garantiert Ärger mit dem Protokoll geben, bei 1-Wire z.B. (*) Schau, ob Dein PIC das kann. Wenn ja, dann gibts nicht nur ein TRISB, LATB und PORTB, sondern auch ein ODCB. Manche können auch nur spezielle Pins auf Open Drain schalten. Dann gibts mehrere ODCONx-Register. Blöd wird es auch, wenn Du bidirektional arbeitest und die Datenrichtung mittendrin umkehrst. Dann musst Du auch darauf achten, wie Dein LAT vor dem Umschalten steht. Das sind nur zwei Beispiele, die mir gerade so einfallen. Es ist auf jeden Fall sauberer. fchk PS: Das ganze gilt nicht nur für PIC18, sondern genauso für PIC24/dsPIC und PIC32. Da isses genauso.
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.