- Akku Tests und Balkonkraftwerk Speicher         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Register-Port-Bits direkt ansteuern

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.05.2006
    Alter
    36
    Beiträge
    150

    Register-Port-Bits direkt ansteuern

    Hallo!

    Edit: Programmieren in C und zwar C18 von Microchip

    Ich hab ne Frage bezüglich der Ansteuerung von einzelnen Port-Bits eines Registers. Also ich dachte das geht so ähnlich:

    #define E PORTBbits.RB0
    #define F PORTBbits.RB1

    TRISB = 0x00; //Alle Bits von Port B als Ausgang verwenden

    E = 1; //RB0 auf HIGH setzen -> Leuchtdiode leuchtet
    F = 1; //RB1 auf HIGH setzten -> Leuchtdiode an RB1 leuchtet, Leuchtdiode an RB0 ist dunkel

    Da liegt auch schon das Problem. Ich will das beide leuchten! Wieso leuchtet nach F = 1; nur mehr die an RB1 und die an RB0 nicht mehr? Ich hab ja beide Ausgänge auf HIGH geschalten!!
    Bitte um Hilfe!!

    Anbei noch der gesamte Code.

    Code:
    /** I N C L U D E S **********************************************************/ 
     #include <p18cxxx.h>  
     #include <stdlib.h>                      
     #include <delays.h>
     #include "waits.h"						// für die Warteschleife 
    /** D E C L A R A T I O N S **************************************************/ 
    
    #define LCD_TEST 1
    #define PORT_TEST 1
    #define WAIT_TEST 0
    
    #define TRIS_LCD	TRISB
    #define LCD_PORT	PORTB
    #define LCD_STEUER_PORT PORTD 
    
    #define D0	PORTBbits.RB0    //Dx .... Datenleitung x
    #define D1	PORTBbits.RB1
    #define D2	PORTBbits.RB2
    #define D3	PORTBbits.RB3
    #define D4 	PORTBbits.RB4
    #define D5 	PORTBbits.RB5
    #define D6	PORTBbits.RB6
    #define D7	PORTBbits.RB7
    #define RS      PORTDbits.RD0    //Register Select
    #define RW     PORTDbits.RD1    //Read / Write
    #define E	 PORTDbits.RD2    //Enable 
    
    
     /** Configuration ********************************************************/ 
     #pragma config FOSC = HS 			 	//Externer Takt
     #pragma config PWRT = ON 
     #pragma config BOR = OFF 
     #pragma config WDT = OFF  				//Watchdog Timer 
     #pragma config LVP = ON  				//Low Voltage ICSP 
     #pragma config CPUDIV = OSC1_PLL2		//CPU-Frequenz nicht dividiert, PLL durch 2;		
     #pragma config PLLDIV = 5
     
    #pragma code 
    
    void main(void)
    {
    
    #if WAIT_TEST
    {
      int a=0;
      TRISB = 0x00;
      while(a<5)
      {
        LATB = 0x0F;
        wait_s(1);
        LATB = 0x00;
        wait_s(1);
        a++;   
      }
    }
    #endif
     
    #if PORT_TEST
    {
      int a=0;
      TRISB = 0x00;
      TRISD = 0x00;
      while(a<5)
      {
        D0 = 1;
        E= 1;
        wait_s(1);
        D1 = 1;
        wait_s(1);
        D2 = 1;
        wait_s(1);
        D3 = 1;
        wait_s(1);
        D3=0;
        D2=0;
        D1=0;
        D0=0;
        wait_s(2);
        a++;   
      }
    }
    
    }
    Im Code stecken noch mehr Dinge drinnen. Die wait_s(x); sind in einem anderen C-File, aber funktionieren ganz gut. Also da wartet er x-Sekunden.

    Ja ich hoffe euch fällt dazu was ein.

    lg

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.10.2007
    Ort
    Bayern
    Alter
    35
    Beiträge
    116
    Hi,

    um einezlene Bits zu ändern musst du das mit einem Komma hinter dem Register angeben:

    Code:
    bsf   PORTB,0          ; RB0 wird gesetzt
    bcf  PORTB,7          ; RB7 wird gelöscht
    Mal ein Beispeil:
    Code:
    #define E PORTB,0
    #define F PORTB,1
    
    ; E = 1 geht nicht, das ist Syntax einer Hochsprache. Du musst machen:
    bsf E
    bsf F
    
    ; um es auf 0 z6u setzen:
    bcf E
    bcf F
    Hier eine Befehlsliste


    Edit: Huuups habe nur die ersten paar Zeilen gesehn und dachte daher es sei Assembler, mein Beitrag ist somit hinfällig! Sorry.

    mfg
    Benny

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.05.2006
    Alter
    36
    Beiträge
    150
    Hallo!

    Problem gelöst!

    Ich muss einfach nicht PORTB sondern LATB verwenden.

    also
    #define D0 LATBbits.LATB0
    ...

    Pfu, wäre das mal geschafft. Aber wieso das so ist weiß ich nicht. Falls einen schlauen Programmierer gibt der mir das sagen kann, bitte.

    lg,

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Auf die Falle mit PORTx und LATx bin ich genauso reingefallen.
    Die Erklärung ist leider nicht ganz einfach zu verstehen bzw. zu Beschreiben:
    Das Problem liegt bei den "Read Modify Write" Befehlen.
    Die ersten PICs hatten lediglich PORTx
    Beim Zugriff auf PORTx wird der gerade aktuelle Pegel der Portpins
    gelesen, NICHT das was vorher auf den Port geschrieben wurde.
    Hier kann es passieren, daß man vorher ein beliebiges Ausgangsbit auf
    High gesetzt hatte und beim Lesen ein Low zurückgeliefert wird.
    Dies passiert z.B. dann, wenn der Ausgangspin stärker belastet wird.
    Deshalb trennte man bei Microchip die "Inputs PORT"
    von den "Outputs LAT".

    Bei Bitbefehlen z.B. BSF PORTB,3 wird zunächst der GESAMTE Port,
    also alle 8 Bits vom Prozessor gelesen, dann wird das Bit 3 gesetzt
    und der komplette Port wieder zurückgeschrieben.
    Unterliegt nun ein Ausgangsbit deines Ports einer stärkeren Belastung,
    liest der Prozessor fälschlicherweise ein Low und beim Zurückschreiben
    wird diese Bit dann ebenfalls fasch gesetzt.
    Mit den getrennten Registern kann dies nicht mehr passieren.

    mfg. Siro

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    10.04.2008
    Ort
    Neustrelitz
    Beiträge
    14
    Ich denke, daß mein Problem hierher passt, deshalb setze ich diesen Thread einmal fort...

    Die Aufgabe besteht darin, einen ST6 durch einen PIC 16F685 zu ersetzen. Meine ersten Übungen verlaufen ganz vielversprechend. Doch belibe ich an einem (sicher banalen) Problem hängen.
    Am Port C (0-3) sind 3 LEDs, die ich separat schalten will. Ich dachte mit "BSF PORTC,x" und "BCF PORTC,x" ans Ziel zu kommen. Das stimmt jedoch nur zum Teil.
    Wenn ich ein (beliebiges) Bit setze, werden die anderen auf jeden Fall gelöscht.

    Beispiel 1, LED an RC1 ist an, LED an RC0 jedoch nicht
    Code:
            CALL    LED_RC0_ON
            CALL    LED_RC1_ON
    
    LED_RC0_ON:     
            banksel PORTC
            BSF     PORTC, 0
            RETURN
    
    LED_RC1_ON:     
            banksel PORTC
            BSF     PORTC, 1
            RETURN
    Beispiel 2, LED an RC0 erlischt, obwohl Bit 1 gelöscht wird
    Code:
            CALL    LED_RC0_ON
            CALL    LED_RC1_OFF
    
    LED_RC0_ON:     
            banksel PORTC
            BSF     PORTC, 0
            RETURN
    
    LED_RC1_OFF:    
            banksel PORTC
            BCF     PORTC, 1
            RETURN

    Meine Fragen:
    1. Was mache ich falsch und wie kann ich das Problem lösen.
    2. In einem weiteren Schritt käme noch ein PWM-Signal an RC5 hinzu. Die Schaltung der LEDs darf dies natürlich auch nicht beeinflussen. Die Lösung für (1) muß diesen Punkt also schon berücksichtigen.

    Vielen Dank für die Hilfe

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.10.2007
    Ort
    Bayern
    Alter
    35
    Beiträge
    116
    Hi,

    kannst Du mal etwas mehr Code posten? Zumindest die Initialisierung währe interessant und deine Mainloop.

    mfg
    Benny
    cooming soon...

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    10.04.2008
    Ort
    Neustrelitz
    Beiträge
    14
    Sorry, ich war der Meinung, die wichtigen Snippets gepostet zu haben.
    Code:
      processor  16F685
      #include  <P16F685.INC>
      __config  (_INTOSCIO & _WDT_OFF & _PWRTE_ON)
          
    
            org   0
    
    init:          
            banksel OSCCON
            MOVLW  B'01110001'  
            MOVWF  OSCCON       
    
            MOVLW  B'00000000'        ; Ports C output
            MOVWF  TRISC 
        
            MOVLW  0x3f               ; Pulsweite 255
            MOVWF  PR2
        
            BCF    STATUS, RP0        ; Bank 0
            MOVLW  0x00
            MOVWF  0x70               ; Startwert Pulsweite = 0
            MOVWF  CCPR1L             ; Pulsweite MSB = 0
            MOVLW  B'00001100'        ; Pulsweite LSB = 0
                                      ; Schalte CCP auf PWM
            MOVWF  CCP1CON
            BCF    PIR1, TMR2IF       ; Interruptflag von Timer 2 löschen
            MOVLW  0x04
            MOVWF  T2CON              ; Timer 2 on, Vorteiler = 1
                    
    PROGRAM_LOOP:   
            NOP
            CALL    LED_RC0_ON
            CALL    LED_RC1_ON
            CALL    PAUSE_1_SEK
            CALL    LED_RC0_OFF
            CALL    LED_RC1_OFF
            CALL    PAUSE_1_SEK
            GOTO    PROGRAM_LOOP
    
    
    PAUSE_1_SEK:   
            BSF     STATUS, RP0             ; Bank 1
            BCF     STATUS, RP1
            CLRF    0xa0
            CLRF    0xa1
            MOVLW   0x0f                    ; Zähler 15 mal bis 0xffff
            MOVWF   0xa2
    LOOP_PAUSE_1S:  
            DECFSZ  0xa0, 1
            GOTO    LOOP_PAUSE_1S
            NOP
            DECFSZ  0xa1, 1
            GOTO    LOOP_PAUSE_1S
            DECFSZ  0xa2, 1
            GOTO LOOP_PAUSE_1S
            RETURN                
    
    
    LED_RC0_ON:     
            banksel PORTC
            BSF     PORTC, 0
            RETURN
    LED_RC1_ON:     
            banksel PORTC
            BSF     PORTC, 1
            RETURN
    LED_RC0_OFF:    
            banksel PORTC
            BCF     PORTC, 0
            RETURN
    LED_RC1_OFF:    
            banksel PORTC
            BCF     PORTC, 1
            RETURN
            
            end

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    10.04.2008
    Ort
    Neustrelitz
    Beiträge
    14
    Ich habe noch ein wenig experimentiert. Wenn ich alle Bits in TRISC setze, leuchten (wie zu erwarten) erst einmal alle LEDs. Wenn ich dann in der Programmschleife dann 2 (beliebige) Bits (0-7) ein- und auschalte, erlöschen alle. Nur nicht Bit 4 und 5, diese beiden leuchten weiter.
    Bit 4 und 5 sind also die einzigen zwei, die sich nicht gegenseitig beinflussen. (Beschränke ich mein Testprogramm also auf die Bits 4 und 5, funktioniert es.)
    Bit 4 und 5 sind die beiden einzigen von Port C, die nicht als Analogeingang benutzt werden können.
    Obwohl das das Data Sheet sagt, ANSEL (ANSELH) würde die Ports bei Digital-Out nicht beinflussen, habe ich testweise beide Register mit "00" gefüllt, weil die als Resetvorgabe gestzte Bits haben sollen. Allerdings hat es auch nichts gebracht.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    10.04.2008
    Ort
    Neustrelitz
    Beiträge
    14
    Ich habe folgendes gefunden: https://www.roboternetz.de/phpBB2/ze...t=15449#161798
    Das würde letztendlich bedeuten, daß man einzelne Pins der Portregister nicht sinnvoll ansprechen kann.
    Nach dem lesen des obigen Beitrags versteht man den knapp gehaltenen Hinweis 1 (Data Sheet PIC16F631/677/685/689/690, Seite 21 doch etwas besser.

    Die Quitessenz ist also, daß man das LAT-Register selbst im RAM nachbilden muß und stets dieses "LAT" komplett in den Port schreiben muß.
    Doch wie verhält es sich dann mit als (Analog-) Eingang programmierten Pins? Ich brauche, wie gesagt RC5 als PWM-Ausgang. Da ist doch sicher zu erwarten, daß das Schreiben eines kompletten Bytes auch RC5 und damit dessen Signal beinflusst.
    Und last but not least wären da noch die Analogeingänge (außer 4/5), deren Portbits wohl auch nicht auf einen Schreibzugriff scharf sind.

  10. #10
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    72
    Beiträge
    11.077
    Hallo!

    @ Maulwurf

    Um einzelne Bits in einem Register zu setzen benutzt man "OR" ("iorlw") und zu löschen "AND" ("andlw"). Dabei werden die andere Bits nicht beeinflüsst.

    MfG

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress