Forum: Mikrocontroller und Digitale Elektronik Probleme mit I/O-Zuordnung bei PIC 12F509


von Jonathan B. (jonathan_berndt)


Lesenswert?

Hallo zusammen,

ich habe lange gesucht, gelesen und komme nicht weiter, daher jetzt 
meine Frage hier:
Ich werkel schon seit etwas längerer Zeit an einfachen Programmen mit 
verschiedenen 8-Bit PICs, gerne mit den 12F509ern.
Ich habe unten angehängtes Testprogramm mit CCS geschrieben und mit dem 
ICD 3 via MPLAB IPE auf den Chip gebrannt.
Es funktioniert auch alles einwandfrei außer:
GP2 (PIN_B2) hängt dauerhaft auf ca. 3,5V unveränderlich, die 
Versorgungsspannung der Platine liegt bei 5V.
Ich habe die IO-Konfiguration jetzt schon etwa 100 Mal angesehen und 
überprüft, ich komme einfach nicht weiter.
Vielleicht hat ja jemand eine zündende Idee, wo der (wahrscheinlich 
ziemlich dösige) Fehler liegt.
Danke!
Gruß
Jonathan
1
#include <12F509.h>
2
#fuses NOWDT,INTRC,NOMCLR,NOPROTECT
3
#use delay(clock=4000000)
4
#byte GPIO = 0b00001000
5
void main ()
6
{
7
for(;;)
8
{
9
set_tris_b(0b00001000);
10
output_high (PIN_B0);
11
output_high (PIN_B1);
12
output_high (PIN_B2);
13
output_high (PIN_B4);
14
output_high (PIN_B5);
15
delay_ms (500);
16
output_low (PIN_B0);
17
output_low (PIN_B1);
18
output_low (PIN_B2);
19
output_low (PIN_B4);
20
output_low (PIN_B5);
21
delay_ms (500);
22
}
23
}

von Gerhard O. (gerhard_)


Lesenswert?

Jonathan B. schrieb:
> GP2 (PIN_B2) hängt dauerhaft auf ca. 3,5V unveränderlich, die
> Versorgungsspannung der Platine liegt bei 5V.

Hallo Jonathan,

Das ist leicht zu erklären:

Dem Datenblatt nach wird die Funktion des GP2 Pins vom Option Register 
bit T0CS bestimmt und nicht vom TRIS. Für GPIO an GP2 muss dieses Bit 
Low sein weil sonst der Timer Eingang das Vorrecht über die TRIS 
Register Einstellung hat.

Mysteriöserweise ist der Power-Up Default im OPTION Register als Default 
so gesetzt daß der GP2 Pin immer als T0CKI funktioniert und nicht von 
den Werten des TRIS Register beeinflußbar ist. Also muß das T0CS Bit 
dort auf Null gesetzt werden.

Programmiere das Option Register also explizit mit T0CS Bit = 0.

(Siehe auch Seite 24 im Datenblatt unter 4.5)

Schau mal im 12C509 Header File nach wegen der Definition des Option 
Register Register Namen und füge das Folgende in der Main() ein:

OPTION = 0b11011111; // oder 0xdf, set T0CS als GPIO, timer internal 
clock

(da ich gerade mit dem iPad arbeite kann ich nicht den CCS Header File 
ansehen. Die SFR Register Namen sollten dort definiert sein und heißt in 
dem Fall möglicherweise einfach nur "OPTION".)

Versuch das mal.

Gerhard

: Bearbeitet durch User
von Gerhard O. (gerhard_)


Lesenswert?

Gibt's was Neues? Hat es funktioniert? Berichte mal.

von Jonathan B. (jonathan_berndt)


Lesenswert?

Hallo Gerhard,

den Timer hatte ich ja so garnicht auf dem Schirm...
Da das Option-Register nicht im Header gelistet ist (oder ich es nicht 
gefunden habe), habe ich es mit dem Assembler-Schnipsel
1
   #ASM
2
   MOVLW 0b11011111
3
   OPTION
4
   #ENDASM
in Main() probiert und es funktioniert.

Vielen Dank für den super Hinweis und die Hilfe!
Schönes Restwochenende noch!
Jonathan

Beitrag #5312407 wurde vom Autor gelöscht.
von Gerhard O. (gerhard_)


Lesenswert?

Jonathan B. schrieb:
> Hallo Gerhard,
>
> den Timer hatte ich ja so garnicht auf dem Schirm...
> Da das Option-Register nicht im Header gelistet ist (oder ich es nicht
> gefunden habe), habe ich es mit dem Assembler-Schnipsel   #ASM
>    MOVLW 0b11011111
>    OPTION
>    #ENDASM
> in Main() probiert und es funktioniert.
>
> Vielen Dank für den super Hinweis und die Hilfe!
> Schönes Restwochenende noch!
> Jonathan

Danke für die Rückmeldung und die gute Nachricht.

Gerhard

von Gerhard O. (gerhard_)


Lesenswert?

Hallo Jonathan,

ich habe mir mittlerweile den CCS 12C509 Header File angesehen. Das 
Option Register ist wie Du schon erwähntest nicht darin enthalten. Um 
den Timer0 intern um zu schalten damit GP2 als GPIO funktioniert, kann 
man das folgende auch ohne Assembler machen:

SETUP_TIMER_0(T0_INTERNAL);    // Release T0 Eingang vom GP2 Pin
SETUP_TIMER_0(T0_INTERNAL, T0_DIV_16);   // Takt über 16:1 Prescaler


das hat den gleichen Effekt wie was Du gemacht hattest. Der Timer0 wird 
nun intern getaktet.

Versuch das mal bei Gelegenheit. Es sollte auch funktionieren.

Gerhard

: Bearbeitet durch User
von Jonathan B. (jonathan_berndt)


Lesenswert?

Hallo Gerhard,

klar, so geht es natürlich auch. In den letzten Projekten war der Timer 
immer aktiv und auf Intern geschaltet... dann funktioniert GP2 natürlich 
als Output. Da hatte ich wohl ein ziemliches Brett vor dem Kopf.

Vielen Dank für die Hilfe!
Gruß
Jonathan

von Gerhard O. (gerhard_)


Lesenswert?

Jonathan B. schrieb:
> Hallo Gerhard,
>
> klar, so geht es natürlich auch. In den letzten Projekten war der Timer
> immer aktiv und auf Intern geschaltet... dann funktioniert GP2 natürlich
> als Output. Da hatte ich wohl ein ziemliches Brett vor dem Kopf.
>
> Vielen Dank für die Hilfe!
> Gruß
> Jonathan

Jonathan,

danke für Deinen Update. Freut mich, dass ich Dir etwas helfen konnte.

Gerhard

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
Noch kein Account? Hier anmelden.