-
        

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

Thema: Probleme mit Programm (LED-Blinklicht)

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2008
    Beiträge
    19

    Probleme mit Programm (LED-Blinklicht)

    Anzeige

    Ich bin Anfänger im Pic-Programmieren und möchte mir deshalb zur Übung erst einmal ein LED-Blinklicht/Lauflicht bauen. Dazu verwende ich einen PIC16F88, den ich nach folgendem Schaltplan angeschlossen habe:



    Es sind allerdings mehrere LEDs an Port A Pins angeschlossen.

    Dazu habe ich folgendes Programm für den PIC16F88 angepasst und mit dem Brenne 8 MiniP von Sprut auf den Chip gebrannt:

    Code:
    #include P16f88.INC
    
    ;*****Set up the Constants**** 
    
    STATUS          equ       03h                              ;Address of the STATUS register
    TRISA           equ       85h                              ;Address of the tristate register for port A
    PORTA           equ       05h                              ;Address of Port A
    COUNT1         	equ       20h                              ;First counter for our delay loops
    COUNT2         	equ       21h                             ;Second counter for our delay loops  
    
    ;****Set up the port**** 
    
    				bsf                STATUS,5       ;Switch to Bank 1
    				movlw              00h            ;Set the Port A pins
    				movwf              TRISA          ;to output.
    				clrf				ANSEL
    				bcf                STATUS,5       ;Switch back to Bank 0 
    
    ;****Turn the LED on**** 
    
    Start            movlw              1Fh             ;Turn the Port A LEDs on by first putting it
                     movwf              PORTA           ;into the w register and then on the port 
    
    ;****Add a delay 
    
              		call                Delay 
    				call				Delay
              	
    
    ;****Delay finished, now turn the LED off****
    
    				movlw              00h                  ;Turn the LEDs off by first putting it
    				movwf              PORTA           ;into the w register and then on the port 
    
    ;****Add another delay**** 
    
    				call                   Delay 
    				call 					Delay
        
    
    ;****Now go back to the start of the program
    
    				goto                 Start                 ;go back to Start and turn LEDs on again 
    
    ;****Here is our Subroutine
    
    Delay
    
    Loop1          decfsz              COUNT1,1    ;This second loop keeps the LEDs
                   goto                  Loop1              ;turned off long enough for us to
                   decfsz              COUNT2,1     ;see it turned off
                   goto                  Loop1             ;
    				return 
    
    ;****End of the program**** 
    
    			end                                              ;Needed by some compilers, and also
                                                     ;just in case we miss the goto instruction.
    Allerdings habe ich jetzt das Problem, dass die LEDs konstant leuchen, anstatt wie zu erwartend zu blinken. Ich vermute, dass ich irgendetwas mit dem Delay falsch gemacht habe, sehe aber nicht was. Könnt ihr mir hier bitte weiterhelfen ?

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    06.07.2007
    Alter
    30
    Beiträge
    81
    Hast du n Oszilloskop?? Dann schau mal deinen Ausgang an, evtl. blinkt deine LED so schnell, dass man s nicht sieht! Mit dem Code kann ich nicht viel anfangen, da AVR Assembler ein bisschen anderst ist, allerdings solltest du etwa so vorgehen:
    -Port umschalten
    -Warten
    -Port umschalten
    -Warten
    -zurück auf Anfang

    MFG Mixxer

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2008
    Beiträge
    19
    Ich gehe im Prinzip so vor wie du beschrieben hast.

    Leider habe ich kein Oszi hier. Wenn ich allerdings mein Multimeter auf Wechselspannung stelle und eine LED messe, dann messe ich so 4V. Wenn ich es auf Gleichspannung stelle, dann so 2V. Also wird es wohl wie vermutet die Delay-Subroutine sein die nicht funktioniert. Was stimmt hier nicht?

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    06.07.2007
    Alter
    30
    Beiträge
    81
    eine Delay-Subroutine in Assembler zählt ein Register hoch oder runter bis es einen bestimmten Wert erreicht, dann springt er wieder aus der Routine. Du musst schauen was das (es können auch mehrere) Register ist und schauen mit was es vorgeladen wird und wie gezählt wird. Dann kannst du über den Takt feststellen, was die Delay-Zeit ist. Wenn diese ca. kleiner wie 20ms ist siehst du von der LED nur noch Dauerlicht.
    Du solltest das Register also so laden dass die Zeit z.B. 0,5s lang ist, dann siehst du ein schönes Blinken!

    So wie es bei dir aussieht heißen die beiden Register für die Delay "COUNT1 und COUNT2". Ich sehe aber weder wo sie vorgeladen werden (muss immer am Anfang von der Subroutine passieren) und wo sie für das weiterspringen mit einem bestimmten Wert geprüft werden. Außer das macht alles der Befehl "decfsz". Wie gesagt, mit PIC ASM kenn ich mich nicht so gut aus!

    MFG Mixxer

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2008
    Beiträge
    19
    decfsz erhöht den Register um 1 und überspringt den Befehl in der nächsten Reihe, wenn das Register "voll" ist.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    06.07.2007
    Alter
    30
    Beiträge
    81
    Dann schau doch mal wie viel Takte der PIC für die Delay-Schleife benötigt und errechne mal mit der Taktzeit vom µC die Verzugszeit!

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    12.09.2008
    Beiträge
    5
    Zitat Zitat von G4nd41f
    decfsz erhöht den Register um 1 und überspringt den Befehl in der nächsten Reihe, wenn das Register "voll" ist.
    Fast richtig. Das wäre incfsz. dec bedeutet decrement. Zählt also abwärts.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    12.09.2008
    Beiträge
    5
    Dein PIC hat keinen Takt. Der RC Oszillator gehört an OSC1 nicht an OSC2. Außerdem empfiehlt das Datenblatt einen R1 von <= 100kOhm.

    Hast du das gefixt ist sicherlich die Delay Routine viel zu lange. Bei Verwendung von 220pF und 100kOhm hast du ganz grob einen Takt von 40kHz. Durch 4 gibt das intern 10kHz Ausführungsgeschwindigkeit. Deine Delay Routine ist eine Doppelt verschachtelte Schleife mit insgesamt
    255*255=65025 Durchläufen. Enthalten sind zwei Befehle. Das ergibt einen Delay von rund 12 Sekunden.

    Außerdem lädst du die Register nicht mit sinnvollen Werten vor. Dadurch ist es beim ersten Durchlauf dem Zufall überlassen was drin steht. Später stehen die dann immer auf Null und springen durch decfsz auf 255.

    Schau mal den modifzierten Code an. Dort sollten die LEDs mit dem Vorgeschlagenen Oszillator grob im 1/2 Sekundentakt blinken.



    Generell:
    ich würde bevorzugt die vordefinierten macros verwenden.
    Statt
    bsf STATUS,5
    besser
    bsf STATUS, RP0
    oder besser gleich
    banksel TRISA

    statt
    decfsz COUNT1,1
    besser
    decfsz COUNT1,f

    macht das ganze lesbarer und weniger fehleranfällig.

    Code:
    #include P16f88.INC
    
    ;*****Set up the Constants****
    
    STATUS          equ       03h                              ;Address of the STATUS register
    TRISA           equ       85h                              ;Address of the tristate register for port A
    PORTA           equ       05h                              ;Address of Port A
    COUNT1            equ       20h                              ;First counter for our delay loops
    COUNT2            equ       21h                             ;Second counter for our delay loops 
    
    ;****Set up the port****
    
                bsf                STATUS,RP0       ;Switch to Bank 1
                movlw              00h            ;Set the Port A pins
                movwf              TRISA          ;to output.
                clrf               ANSEL
                bcf                STATUS,RP0       ;Switch back to Bank 0
    
    ;****Turn the LED on****
    
    Start            movlw              1Fh             ;Turn the Port A LEDs on by first putting it
                     movwf              PORTA           ;into the w register and then on the port
    
    ;****Add a delay
    
                 call            Delay
     
    ;****Delay finished, now turn the LED off****
    
                movlw              00h                  ;Turn the LEDs off by first putting it
                movwf              PORTA           ;into the w register and then on the port
    
    ;****Add another delay****
    
                call                Delay
       
    
    ;****Now go back to the start of the program
    
                goto                 Start                 ;go back to Start and turn LEDs on again
    
    ;****Here is our Subroutine
    
    Delay
    			   movlw			   255
    			   movwf			   COUNT1		;Load count1 with init value
    			   movlw			   10
    			   movwf			   COUNT2		;Load count1 with init value
    			   
    
    Loop1          decfsz              COUNT1,f    ;This second loop keeps the LEDs
                   goto                  Loop1              ;turned off long enough for us to
                   decfsz              COUNT2,f     ;see it turned off
                   goto                  Loop1             ;
                return
    
    ;****End of the program****
    
             end                                              ;Needed by some compilers, and also
                                                     ;just in case we miss the goto instruction.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2008
    Beiträge
    19
    Danke, jetzt gehts

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2008
    Beiträge
    19
    Habe mich wohl zu früh gefreut. Ich habe jetzt mal den Delay ein wenig verkürzt und schon machen die Leds nicht mehr das was ich will. Hier erst mal der Code:

    Code:
    #include P16f88.INC 
    
    ;*****Set up the Constants**** 
    
    STATUS          equ       03h                              ;Address of the STATUS register 
    TRISA           equ       85h                              ;Address of the tristate register for port A 
    PORTA           equ       05h                              ;Address of Port A 
    COUNT1            equ       20h                              ;First counter for our delay loops 
    COUNT2            equ       21h                             ;Second counter for our delay loops 
    
    ;****Set up the port**** 
    
                bsf                STATUS,RP0       ;Switch to Bank 1 
                movlw              00h            ;Set the Port A pins 
                movwf              TRISA          ;to output. 
    
                clrf               ANSEL 
                bcf                STATUS,RP0       ;Switch back to Bank 0 
    
    
    			movlw              00h             ;
                movwf              PORTA 
    
    ;****Turn the 1st LED on**** 
    
    Start            movlw              04h             ;Turn the Port A LEDs on by first putting it 
                     movwf              PORTA           ;into the w register and then on the port 
    
    
    
                 call            Delay 
    ;2nd LED
    
     				movlw              08h             ;Turn the Port A LEDs on by first putting it 
                 	movwf              PORTA           ;into the w register and then on the port
    				call 			Delay
    
      
    ;****Delay finished, now turn the LED off**** 
    
                movlw              00h                  ;Turn the LEDs off by first putting it 
                movwf              PORTA           ;into the w register and then on the port 
    
               call 			Delay
    
    
    ;****Now go back to the start of the program 
    
                goto                 Start                 ;go back to Start and turn LEDs on again 
    
    ;****Here is our Subroutine 
    
    Delay 
                movlw            5
                movwf            COUNT1      ;Load count1 with init value 
                movlw           5
                movwf            COUNT2      ;Load count1 with init value 
                 
    
    Loop1          decfsz              COUNT1,f    ;This second loop keeps the LEDs 
                   goto                  Loop1              ;turned off long enough for us to 
                   decfsz              COUNT2,f     ;see it turned off 
                   goto                  Loop1             ; 
                return 
    
    ;****End of the program**** 
    
             end                                              ;Needed by some compilers, and also 
                                                     ;just in case we miss the goto instruction.
    
    			end                                              ;Needed by some compilers, and also
                                                     ;just in case we miss the goto instruction.
    Es soll folgendes passieren:
    LED1 an->Pause->LED1 aus und LED2 an->Pause->Neustart
    Es passiert aber folgendes:
    LED1 an-> Pause->LED1 aus und LED2 an->Pause->LED2 aus und LED1an> Pause->LED1 aus und LED2 an->lange Pause-> Neustart

    Woher kommt diese lange Pause alle zwei Durchläufe ?

    Wenn ich jetzt den Delay auf deinen ursprünglichen Wert erhöhe, dann
    kommen nur zwei Wechsel anstatt drei vor der langen Pause.

    LED 1 hängt übrigens an RA2 und LED2 an RA3.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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