-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Anfänger erbittet Hilfe(2)

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    68
    Beiträge
    1.133
    Blog-Einträge
    1

    Anfänger erbittet Hilfe(2)

    Anzeige

    Hallo Freunde !

    Nachdem ich mich einigermaßen, Dank Eurer Mithilfe !!!, in die PIC- Programmierung einarbeiten konnte, habe ich doch noch offene Grundfragen.
    Ich Programmiere ja fast ausschließlich in C/C++. Fast 80%, wenn nicht noch mehr, der PIC -Anleitungen sind in ASSR gehalten, die C-Beispiele fast alle in Micro-C gehalten.
    Nicht das ich es erst mal nicht verstehe damit umzugehen, aber das Ansprechen der I/O Ports macht mir noch große Sorgen und ist damit bei meinen Programm oft eine Fehlerquelle.

    Das von Microchip als PDF verfasste I/O Referendum, ist auch fast nur in ASSR gehalten.
    Nun steht vor mir die Frage wie spreche ich I/O-Ports/Pins in MPLABX XC-8 an , da lese ich was ConbitsXX und LATxx,
    aber so richtig kann ich mich damit nicht darüber Klar werden, wie ich es bewerkstelligen kann, einzelne Port-Pins zu setzen, lesen usw...

    Code:
    void init()
    {
        TRISD = 0b00001111; // D0..D3 INPUT D4..D7 OUTPUT
        PORTD = 0b00001111; // PULLUP D0...D3
    }
    
    void main(void) {
        init();
        while(1){//Endlosschleife
       /// RD4 = 1;  // geht LED4 ON
        RD4 = RD0; // RD4(LED4 ON ) = HIGH wenn RD0 = HIGH  Geht nicht ?????
    }   
        return;
    }
    Wer hätte denn mal die Freundlichkeit an Hand von einem 3..4 Zeilen Beispiel, mir das aufzuzeigen , wie das richtig zu bewerkstelligen ist ??

    Ich danke schon mal im Voraus

    Mit Gruss
    Gerhard
    Geändert von oderlachs (29.03.2017 um 14:41 Uhr)
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  2. #2
    RN-Premium User Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    47
    Beiträge
    511
    Blog-Einträge
    17
    Die Konfiguration der Portpins ist leider nicht allgemeingültig für alle PICs, da ist das Datenblatt dein A&O für I/O
    Der PIC16F877A z.B. hat keine Pullups am PortD. Also müssen Pullups extern angeschlossen oder auf dem Entwicklungsboard gejumpert werden. Auch hat der 877 keine LAT Register, man gibt also direkt auf PORT aus.

    Die Pullups der Ports, die welche haben werden über Flags in den SFR (special function register) aktiviert. Z.B. um die Pullups am PortB des PIC16F877A zu aktivieren wird das Flag nRBPU im Register OPTION_REG gelöscht. Der XC8 bringt für alle Register Definitionen und Strukturen mit Bitfeldern mit und so gibt es diverse Möglichkeiten auf die Register und auf die Flags zuzugreifen. Um das nRBPU Flas im OPTION _REG zu löschen fallen mir drei gleichwertige ein:
    Code:
        OPTION_REG &= ~(1 << _OPTION_REG_nRBPU_POSN);
        OPTION_REG &= ~_OPTION_REG_nRBPU_MASK;
        OPTION_REGbits.nRBPU = 0;
        nRBPU = 0;
    Auch beim Zugriff auf die I/O Pins gibt es diverse Möglichkeiten. Ich definiere mir meistens Labels für die Hardwarezuordnung und nutze die von XC8 fürs PORTD definierte Struktur PORTDbits mit Bitfeldern. Für die meisten Register definiert XC8 solche Strukturen mit ABCbits im Namen. Um nah an deinem Beispiel zu bleiben würde ich die Pins für Taster und LED mit Labeln benennen und so sähe das bei mir vielleicht aus
    Code:
    #include <xc.h>
    #define TasterLEDan PORTDbits.RD0
    #define TasterLEDaus PORTDbits.RD1
    #define LED4 PORTDbits.RD4
    
    void main(void) {
        TRISD = 0b00001111; // D0..D3 INPUT D4..D7 OUTPUT
        while(1){
            if(TasterLEDan == 0){
                LED4 = 1;
            }
            if(TasterLEDaus == 0){
                LED4 = 0;
            }
        }
    }
    Hier noch ein paar deutschsprachige Tutorials, die das Thema Benutzung der I/O Pins in C beleuchten:
    https://pic-projekte.de/blog/pic-c-t...ziell-fur-pic/
    http://www.hs-ulm.de/users/vschilli/.../uCquick-X.pdf -> s. Kapitel 3
    http://www.sprut.de/electronic/pic/c...isches.html#io

    *******
    Noch ein Nachtrag. Um nachzusehen, welche Definitionen für ein bestimmtes Register im XC8 vorliegen, schaue ich im entspr. Header nach. Dafür reicht ein STRG+Klick auf den Registernamen. Gebe z.B. im Quelltext PORTD ein, mach ein STRG+Klick drauf und schwups bist du z.B. im pic16f877a.h an der Stelle der für PORTD relevanten Definitionen. Nur die Bitdefinitionen wie RD0 und RD4 findet man an etwas anderer Stelle in der Headerdatei. Ob man in C PORTDbits.RD4 = 0 hinschreibt oder RD4 = 0 ist letztendlich Geschmacksache. Aus beidem wird im Assembler das gleiche BCF PORTD, 0x4

    Gruß
    witkatz
    Geändert von witkatz (29.03.2017 um 23:07 Uhr)

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.491
    Ok, also erst mal ein paar grundsätzlich Dinge:

    Die I/O Pins sind in Ports organisiert. Diese belegen eine Position im Speicher und sind (theoretisch) so breit, wie der Datenbus des Rechners. Bei den PIC12, PIC16 und PIC18 also 8Bit ( dazu der XC8 ), bei den PIC24 und den dsPIC33 16Bit ( dazu der XC16 ) usw. Das "theoretisch" soll sagen, daß nicht in jedem Port alle Bits vorhanden sind.

    Die Ports heißen PORTA, PORTB ... und können so direkt angesprochen werden.

    PORTA = 0b101010;

    Wenn man beim Projekt den richtigen Prozessor eingestellt hat, zieht xc.h die passenden Headerfiles an, damit PORTA auch an der Adresse landet, die zum Prozessor passt.

    Eigentlich will man meist nicht einen Port sondern nur ein Bit in einem Port ansprechen. Auch dafür gibts Unterstützung in den Headerfile. Für jeden Port wie auch für jedes Special Function Register ist ein Bitfeld definiert, über das man Bits einzeln ansprechen kann. Bitfelder in C sind Structuren und werden wie solche angesprochen. Den Namen haben die Microchip-Leute so konstruiert: zuerst der Portname (oder das SFR) dann (kleingeschrieben) bits. Das ist der Structurname, danach folgt ein Punkt, wie in C üblich, und dann der Name des Bits oder Bitfelds.

    Das klingt jetzt bestimmt sehr trocken, daher ein paar Beispiele:

    PORTA = 0b10101010; // ganzen Port setzen

    Wobei, es gibt Gründe, die ich jetzt hier nicht vertiefen will, nicht auf den Port sondern auf das Portlatch zu schreiben. Also

    LATA = 0b10101010;

    Und jetzt einzelne Bits:

    LATAbits.LATA0 = 1; // Bit 0 von Porta bzw RA0 auf 1
    TRISAbits.TRISA0 = 1; // RA0 auf Input
    if ( PORTAbits.RA0 == 1) {....}

    So läßt sich jedes Portbit einzeln steuern. Und die Headerfiles sorgen dafür, daß man nicht vorhandene Bits eines Ports garnicht erst ansprechen kann.

    Damit man den Code besser mit der Hardware in Zusammenhang bringt, definiere ich mir meisst passende Namen.

    #define LED_RED LATBbits.LATB3

    Wenn jetzt noch die LED vom Port nach GND geht, kann ich im Programm einfach schreiben:

    LED_RED = 1;

    und sie geht an.

    Diese Definition der Bitfelder gibt es für alle Register der PICs. Daher sind die Headerfile recht lang. Selbst für den simplen PIC16F1825 sind es über 7000 Zeilen, bei den großen wesentlich mehr. Hier noch ein Beispiel für ein Bitfeld mit Felder größer als ein Bit. CCP1CON ist ein Register aus dem PWM Controller

    CCP1CONbits.CCP1M ist 4 Bits breit, CCP1CONbits.DC1B und CCP1CONbits.P1M jeweils 2 Bit. Die Bezeichnung CCP1CON und CCP1M findet man genauso im Datenblatt.

    Man kann also schreiben

    CCP1CONbits.CCP1M = 0b0100; // Capture mode: every falling edge

    exakt wie es im Datenblatt steht.

    Sorry, wenn das etwas lang geworden ist. Ich hoffe aber, es ist verständlich.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.491
    Zitat Zitat von witkatz Beitrag anzeigen
    . Ob man in C PORTDbits.RD4 = 0 hinschreibt oder RD4 = 0 ist letztendlich Geschmacksache
    Ist schon richtig, RD4 ist ja auch nur ein #define auf PORTDbits.RD4. Ist aber wohl nicht überall durchgehalten worden, bin damit schon mal auf die Nase gefallen. Ich mach mir daher immer eigene die ich auf die generische lange Bezeichnung beziehe, selbst wenn sie nur AUX1, AUX2 oder DEBUGBIT heißen. Die gleichen Labels trag ich dann auch bei meinem saleae LA ein, dann kann ich direkt Source und LA vergleichen und wenn alles Gute zusammenkommt, steht im Schaltplan auch noch der gleiche Name.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  5. #5
    RN-Premium User Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    47
    Beiträge
    511
    Blog-Einträge
    17
    Zitat Zitat von Klebwax Beitrag anzeigen
    RD4 ist ja auch nur ein #define auf PORTDbits.RD4.
    Nein, ist es nicht. Die SFR Bit Definitions sind absolut adressierte Bitvariablen und haben in der Definition keinen Bezug zu den Bitfeldstrukturen. Das RD4 des PIC16F877a ist definiert als:
    Code:
    extern volatile __bit  RD4 @ (((unsigned) &PORTD)*8) + 4;

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.491
    Zitat Zitat von witkatz Beitrag anzeigen
    Nein, ist es nicht. Die SFR Bit Definitions sind absolut adressierte Bitvariablen und haben in der Definition keinen Bezug zu den Bitfeldstrukturen. Das RD4 des PIC16F877a ist definiert als:
    Code:
    extern volatile __bit  RD4 @ (((unsigned) &PORTD)*8) + 4;
    Hast recht. Hab das mit den 16 Bittern durcheinandergebracht. Da sind die kurzen Bezeichnungen nur #defines. Und da haben diese auch ein Underline vorne.

    #define _RA4 PORTAbits.RA4

    Das mit dem Underline ist wohl auch der Grund, warum ich mir die "kurzen" Namen abgewöhnt habe. Da muß man beim Wechseln zwischen 8 und 16 Bittern immer umdenken.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    RN-Premium User Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    47
    Beiträge
    511
    Blog-Einträge
    17
    Zitat Zitat von Klebwax Beitrag anzeigen
    der Grund, warum ich mir die "kurzen" Namen abgewöhnt habe.
    Ich benutze auch die Bitfeldstrukturen und Definitionen die ich im Header nach STRG+Click auf den Registernamen sehe, die sehe ich dann sofort. Die kurzen Namen stehen im Header verstreut und man muss schon wissen, wonach man sucht. Für I/O Pins mag das evtl. praktikabel sein, nicht aber für SFR Flags.
    In den Bitfeldern der SFR gibt es oft Subsets, wie das von dir genannte 4 Bit Große CCP1CONbits.CCP1M. Das geht mit Bitdefinitions schon mal nicht.

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    68
    Beiträge
    1.133
    Blog-Einträge
    1
    Hallo Freunde....
    recht , recht herzlichen Dank das hat mich ein ganzes Stück weitergebracht und ich habe aus Euren Antworten mehr Wissen entnehmen können, als wie aus dem "Grossem PIC Micro Handbuch" vom Franzi'sVerlag u.a.m.
    Wenn man da nur rein schaut, kann man zwar ganze " C/C++ Bibeln" schreiben, mit Strukturen und Klassen von Katzen,Hunden, Autos und was weiss ich, aber nicht einen Port abfragen oder einen Port setzen...
    Leider merkt man erst nach dem Kauf , für was für "literarischen Schrott" man sein gutes Geld ausgegeben hat
    Vielleicht mache ich meine Fehler auch noch deswegen, da ich ja bislang nur AVR Chips programmierte und das so im Hinterkopf noch habe. Nun ich habe ja auch erst 3Monate die PIC Schule besucht

    Gruss und Dank

    Gerhard

    Nachtrag : Habe jetzt so recht und schlecht ein Input/Output Code fertig gebracht der auch geht, aber "begriffe" mit "LATxx" will mein CX8 Compiler gar nicht...wahrscheinlich bin ich wirklich für die PIC s zu blöde...

    - - - Aktualisiert - - -

    Zitat Zitat von Klebwax Beitrag anzeigen



    Wobei, es gibt Gründe, die ich jetzt hier nicht vertiefen will, nicht auf den Port sondern auf das Portlatch zu schreiben. Also

    LATA = 0b10101010;

    Und jetzt einzelne Bits:

    LATAbits.LATA0 = 1; // Bit 0 von Porta bzw RA0 auf 1
    TRISAbits.TRISA0 = 1; // RA0 auf Input
    if ( PORTAbits.RA0 == 1) {....}

    So läßt sich jedes Portbit einzeln steuern. Und die Headerfiles sorgen dafür, daß man nicht vorhandene Bits eines Ports garnicht erst ansprechen kann.

    Damit man den Code besser mit der Hardware in Zusammenhang bringt, definiere ich mir meisst passende Namen.

    #define LED_RED LATBbits.LATB3

    Wenn jetzt noch die LED vom Port nach GND geht, kann ich im Programm einfach schreiben:

    LED_RED = 1; und sie geht an.

    MfG Klebwax
    Kann es sein das mit meinem CHIP :"PIC16F877A" gar keine "LATxx-Programmierung" geht und ich deshalb immer Fehlermeldungen bekomme ???
    Geändert von oderlachs (30.03.2017 um 10:39 Uhr)
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  9. #9
    RN-Premium User Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    47
    Beiträge
    511
    Blog-Einträge
    17
    Vielleicht wusste Klebwachs nicht um welchen PIC es sich handelt bzw. hat allgemein geantwortet. Den Blick ins Datenblatt wird dir leider keiner abnehmen.
    Zitat Zitat von oderlachs Beitrag anzeigen
    Kann es sein das mit meinem CHIP :"PIC16F877A" gar keine "LATxx-Programmierung" geht und ich deshalb immer Fehlermeldungen bekomme ???
    Zitat Zitat von witkatz Beitrag anzeigen
    Auch hat der 877 keine LAT Register, man gibt also direkt auf PORT aus.

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    68
    Beiträge
    1.133
    Blog-Einträge
    1
    Lach Witkatz...als ich gepostet hatte und nochmals alles gelesen hatte da wusste ich es, das ich es in Deinem Posting überlesen hatte.
    Den Blick ins Datenblatt soll mir auch eigentlich keiner abnehmen, wenn ich mich auch mit English sehr sehr schwer tue...nur als Einsteiger sei mir mal solch Unwissenheit noch mal verziehen werden können....

    Zum grossen (UN-)Glück fiel jetzt noch einen 8 polige Stiftleiste aus dem Entwicklerbord, nur Klebelötung...
    Ich dachte eigentlich das das Nachlöten von Nah und Fernost-Leiterplatten der Vergangenheit angehört, aber wurde des besseren belehrt.
    Ich kenne das vom Beruf her, von 10 def. Funkgeräten der CB Funk-Branche waren bestimmt von 8 nur Leiterplatten nur nach zulöten um wieder zu funktionieren...
    Wer weiss welche Überraschungen ich noch erlebe, aber alle Wege zum Erfolge sind nun mal mit Stolpersteinen gepflastert...

    Gerhard
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] PIC Neueinsteiger erbittet Hilfe
    Von oderlachs im Forum PIC Controller
    Antworten: 22
    Letzter Beitrag: 20.04.2016, 17:07
  2. hilfe Anfänger braucht hilfe beim start
    Von thomas3 im Forum Robby RP6
    Antworten: 26
    Letzter Beitrag: 20.09.2010, 21:07
  3. Anfänger Hilfe?
    Von Chimaira im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 2
    Letzter Beitrag: 15.01.2007, 16:50
  4. Hilfe für Anfänger :o)
    Von Sascha600xt im Forum C-Control II
    Antworten: 7
    Letzter Beitrag: 25.04.2006, 15:42
  5. AVR anfänger HILFE !!!
    Von khazad im Forum AVR Hardwarethemen
    Antworten: 3
    Letzter Beitrag: 17.11.2004, 20:44

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •