Forum: Mikrocontroller und Digitale Elektronik PIC16F627 Problem beim lesen von Eingängen mit Velleman k8048


von Martin B. (martin_16f627)


Angehängte Dateien:

Lesenswert?

Guten Tag,

Ich besitze ein Velleman K8048 Board. Mit diesem bin ich gerade dabei 
die PIC- Programmierung auf "C" zu lernen [kein Assembler]. Ich hatte 
bereits im
dritten Semester den C8051F020 von Sylabs, der nur in C- Programmiert 
wurde.

Mein Problem ist momentan ein ganz einfaches:

Ich möchte die Taste RA0 vom PORTA einlesen. Ist diese gedrückt wird die 
LED
LD1 vom PORTB RB1 gesetzt und leuchtet.
Dem Schaltplan entnehme ich, dass die Taste im gedrückten Zustand +5V 
liefert (also eine `1`)

Wenn ich das Programm auf dem PIC brenne, funktioniert allerdings die 
Tastenabfrage nicht - keine led leuchtet.

#######################################################################

#include <pic16f627.h>

void main(void)
{        TRISB = 0x00; //Initialisieren des Port B als Ausgang
        PORTB = 0x00; //alle LED auf Anfangszustand "aus"
        TRISA = 0xFF; //`1`auf Eingang schreiben, damit Latch 
geschlossen


  while(1)
  {
            if((PORTA & 0x01) == 1)
            {
            PORTB |= 0x01;
            }
            else
            {
            PORTB &= 0xFE;
            }
         }
}

#######################################################################

Ich würde mich sehr um ein paar verständliche Antworten freuen.

von Chris B. (dekatz)


Lesenswert?

PORTA ist beim 16F62x nach einem Reset mit ANALOG-Funktionen belegt 
(AD-Wandler, Comperator, Vref....).
Du musst die entsprechenden Pins erst auf DIGITAL umstellen.
Datenblatt Kapitel 5 !!
Also zuerst Comperator abschalten mit:
CMCON = 0x07
und dann weiter mit TRISA = .......

von TK (Gast)


Lesenswert?

Was sagt denn das Datenblatt zu den Special-Function-Register 
Initialisierungswerten für diesen Typ?
Ohne eine vernünftige INIT (auch in C) wird das so nichts.
Schau mal ins CMCON-Register und vor allem in die Initialisierung nach 
einem Reset.
Manchmal ist es doch besser - vor allem bei diesen kleinen Controllern, 
und speziell beim PIC - erst mal mit Assembler zu beginnen. Da findet 
man die Stolpersteine nämlich recht schnell!

Gruß
TK

von Martin B. (martin_16f627)


Angehängte Dateien:

Lesenswert?

Vielen Dank, es funktioniert!
Sry, für meine absoluten Anfänger fragen, hierauf wäre ich trotz der 
Erklärung selbst nicht gekommen...

Laut der Assozierungstabelle ist bei dem 16f627 mit Port A der 
Comperator
CMCON und VRCON [disablen mit VRCON = 0x08] verbunden.
Warum wirkt sich nun Vref nicht weiter auf die Funktion aus? [bzw. warum 
reicht es dann nur den Comperator zu disablen]

ich würde mich noch mal sehr um eine Antwort von dir freuen :)

Viele Grüße!

von Martin B. (martin_16f627)


Lesenswert?

@TK
Vielen Dank für deine Antwort.
Ich selbst habe erst C, dann C auf dem µC von Sylabs gelernt. Hierbei 
wurde ein Zusatztool benutzt [Config 2], mit dem man eine 
Initialisierungfile erstellen konnte, durch einfache Auswahl in einem 
übersichtlichen Menü - Mann musste sich also nicht selbst um lästige 
Initialisierungen kümmern.

Nun bin ich dabei mir das Programmieren auf einen PIC µC beizubringen.
Hierbei bin ich schon auf mehrere [wie von dir beschrieben] 
Stolpersteine gestoßen.

Bis jetzt
Habe ich LED, Timer 0 und ab heute Taster programmiert.
Als nächstes kommen [mit einem "größeren" PIC18F...] ADC/DAC, weitere 
Timer, UART´s (will ich mit Docklight dann testen), Frequenzmessung und 
PWM.

Naja... dauert noch ein bisschen, bin auch erst seit gestern drann.
Bevor ich mit dem Vellemann Board überhaupt programmieren konnte, musste 
ich es zusammenlöten, meinen alten PC mit einer COM Karte aufrüsten, 
alles einrichten, eine geeignete IDE und Compiler finden. Aber nun läuft 
alles Tipp- Topp - endlich programmieren :)...


Vielen Dank für eure Antworten.
Ich freue mich sehr, wenn ich solch kompetente Hilfe bekomme!

von Chris B. (dekatz)


Lesenswert?

Martin B. schrieb:
> Warum wirkt sich nun Vref nicht weiter auf die Funktion aus? [bzw. warum
>
> reicht es dann nur den Comperator zu disablen]

Nach einem Reset ist VRCON = 0, also Vref abgeschaltet UND nicht mit RA2 
verbunden.
Aber sauberer ist es natürlich wenn man VRCON = 0x00 bei der 
Initialiserung mitzieht ;-)

von Martin B. (martin_16f627)


Lesenswert?

Vielen Dank dekatz!

Mein C-Programm habe ich bereits um eine Init_Device c-file erweitert.
Hier werde ich von nun an meinen µC übersichtlicher initialisieren!

von Martin B. (martin_16f627)


Lesenswert?

Hallo ich habe nochmal eine Rückfrage.
Ich habe nun die Comperatoren, sowie Vref deaktiviert.
Weiterhin möchte ich mit Schalter 2 die LED 2, mit Schalter 3 die LED 3,
mit Schalter 4 die LED 4 einschalten.

Allerdings funktioniert das nach wie vor nicht, obwohl die analoge 
Peripherie deaktiviert ist. Könnt ihr mir noch mal kurz auf die Sprünge 
helfen?

Anbei mein Programm:
##############################################################
//Main Programm - C.File

#include <pic16f627.h>

void Init_Device(void);

void main(void)
{
        Init_Device();  //µC Initialisieren
  while(1)
  {
            if((PORTA & 0x01) ==1)
            {
                PORTB |= 0x01;
            }
            else
            {
                PORTB &= 0xFE;
            }

            if((PORTA & 0x02) ==1)
            {
                PORTB |= 0x02;
            }
            else
            {
                PORTB &= 0xFD;
            }

            if ((PORTA & 0x04)==1)
            {
                PORTB |= 0x04;
            }
            else
            {
                PORTB &= 0xFB;
            }

            if ((PORTA & 0x08) ==1)
            {
                PORTB |= 0x08;
            }
            else
            {
                PORTB &= 0xF7;
            }
         }
}

##############################################################
//Initialisierungs - C.File

#include <pic16f627.h>

void Init_Device(void)
{       TRISB = 0x00; //Initialisieren des Port B als Ausgang
        PORTB = 0x00; //LED alle aus
        //CMCON = 0x07; //Comperator 1 und 2 abschalten
        CM0 = 1;    //Wenn CM0 - CM2 auf 0, dann alle Comp. aus!
        CM1 = 1;
        CM2 = 1;
        VREN = 0; //Vref disablen
        TRISA = 0xFF; //`1`auf Eingang schreiben, damit Latch 
geschlossen

}

##############################################################

von hagi (Gast)


Lesenswert?

Bei dieser Abfrage
1
 if((PORTA & 0x02) ==1)
solltest du auf "== 02" prüfen.
Ebenso bei den nächsten zwei Abfragen mit 0x04 und 0x08.

von Martin B. (martin_16f627)


Lesenswert?

@hagi,

ich habe nun
.
.
if((PORTA & 0x02) ==02)
.
.
if ((PORTA & 0x04)==04)
.
.
if ((PORTA & 0x08) ==??) //08 geht nicht


die 1te, 2te und 3te LED funktioniert.
die 4te nicht. Was gehört hier rein?

kannst du mir erklären wieso die Abfrage auf dem Taster so lauten muss?
Das ist mir nicht verständlich! Der Taster zieht ja im geschlossenen 
Zustand
die Spannung auf +5V und daher liegt ja eine logische 1 an oder, die 
abgefragt werden kann. wieso muss man hier 2,4 und ?? verwenden?


ich würde mich sehr um eine kurze Erklärung freuen :)

von Martin B. (martin_16f627)


Lesenswert?

hab rausgefunden, dass hier anstatt 08 nur 8 geht.
aber wieso muss ich hier nicht auf 1 sondern auf 1,2,4,8 abfragen?

von Erich (Gast)


Lesenswert?

>hab rausgefunden, dass hier anstatt 08 nur 8 geht.
Ja, weil "08" oktal bedeutet. Du muss 0x08 schreiben.

Warum muss man 1, 2, 4, 8 und verwenden ?
Naja, weil deine Taster am Parallelport PORTA dranhängen.
Und weil jede einzelne Leitung (Bit) eben die entsprechende Wertigkeit 
hat.
Evtl. wird das klaren, wenn du die binäre Schreibweise nutzt mit "0b" 
Prefix (die allerdings nicht alle Compiler verstehen):

// Bit   76543210   das ist nur Kommentar
       0b00000001
       0b00000010
       0b00000100
       0b00001000
       0b00010000
       0b00100000
       0b01000000
       0b10000000

Also statt
>if ((PORTA & 0x08) ==??) //08 geht nicht
erstmal
 if ((PORTA & 0x08) == 0x08) // 0x08 jetzt hoffentlich
oder eben
 if ((PORTA & 0b00001000) == 0b00001000) // so sollte es auch gehen

Und eigentlich kannste die Prüfung auf den "Sollwert" auch weglassen,
weil C ja die if Abfrage auswertet nach "true" oder "false",
und somit kannst kürzer schreiben
  if ((PORTA & 0b00001000)  // prüfe ob dieses Bit gesetzt ist

Gruss

von Erich (Gast)


Lesenswert?

Kleine Nachkorrektur, es braucht jetzt natürlich nur noch eine Klammer

>  if ((PORTA & 0b00001000)  // prüfe ob dieses Bit gesetzt ist
   if  (PORTA & 0b00001000)  // prüfe ob dieses Bit gesetzt ist

von TK (Gast)


Lesenswert?

Und wichtig ist auch, Dir den PORT_A mal genauer anzusehen. Da gibt es 
nämlich auch einen Stolperstein, wenn Du PORT_A,4 (oder war's doch 
PORT_A,5?) als Ausgang benutzen möchtest.
Ist zwar im oben getätigten Projekt nicht geplant, aber wer weiss??

Gruß
TK

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.