tid på blinkande diod

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Stene
Inlägg: 276
Blev medlem: 13 maj 2008, 19:21:52
Ort: Uppsala

tid på blinkande diod

Inlägg av Stene »

Hej! Sitter o försöker förstå mig på det här med programering av pic. Jag sitter med en pic 16f690 som jag har skrivit av ett program jag hittat på nätet. Det är en diod som ska blinka. Jag är totalt nybörjare så ha förståelse!! Jag har fått det att blinka men jag skulle vilja ändra hur snabt det blinkar. Jag förstår inte hur jag ändrar den.

STATUS equ 0x03
portc equ 0x07
var1 equ 0x20
var2 equ 0x30
trisc equ 0x87
RPO equ 0x05

org 0x00
goto init

Wait movlw 0xff
movwf var2
loop2 movlw 0xff
movwf var1
loop1 decfsz var1,1
goto loop1
decfsz var2,1
goto loop2
return

init clrw
movwf portc
bsf STATUS,RPO
movwf trisc
bcf STATUS,RPO

main bsf portc,0
call Wait
bcf portc,0
call Wait
goto main

end

Någon som kan tipsa mig hur jag kan ändra tiden på den här koden eller är det så att det inte går??
Rocky_AL
Inlägg: 617
Blev medlem: 7 december 2006, 15:14:50
Ort: Stockholm

Inlägg av Rocky_AL »

Du kan kalla på väntloopen två gånger mellan lysdiod av/på

Kod: Markera allt

main bsf portc,0 ;här slås lysdioden på.
call Wait

;Här kan du lägga till fler "call Wait"

bcf portc,0 ;här slås lysdioden av.
call Wait 

;Här kan du lägga till fler "call Wait"

goto main

Vill du ha kortare tid kan du ändra på värdena i funktionen "wait" till något lägre värde.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

ändra var2
var2 equ 0x30 ändra till var2 equ 0x60 -> halva blinktiden

Om du är osäker på hexadecimala tal så
skriv istället var2 equ xxx (xxx är ett tal mellan 0 och 255)

Swech
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kod: Markera allt

 ; Följande radet är BIG NO NO och MYCKET dålig programmeringsstil!
 ; Man använder en include-fil med alla dessa definitioner i! Finns med i MPLAB!
STATUS equ 0x03
portc equ 0x07
var1 equ 0x20
var2 equ 0x30
trisc equ 0x87
RPO equ 0x05
 ; Slut på kassa raderna
org 0x00 ; OK, absolut mode, inte bästa vägen att gå men det får vara just nu

     goto init ; Ganska logisk

Wait ; Detta är en 'label', i detta fall är det namnet på en rutin. Gissa vad den gör... (tips: läs namnet)
     movlw 0xff ; Laddar 0xFF in i W, ändar värdet = ändra hur lång tid Wait tar
     movwf var2 ; Kopierar W till var2 (var2 = 0xFF alltså)
loop2 ; En label
     movlw 0xff ; Ytterligare ett värde som bestämmer tiden
     movwf var1
loop1 ; Också en label
     decfsz var1,1 ; Räkna ner var1
     goto loop1 ; Om var1 = 0 hoppas denna över
     decfsz var2,1 ; Räkna ner var2
     goto loop2 ; Om var2 = 0 hoppas denna över
     return ; OK, klart här, hoppa tillbaka till vem som nu än kallade på detta

init ; Ännu en label
     clrw
     movwf portc
     bsf STATUS,RPO
     movwf trisc
     bcf STATUS,RPO

main ; Och en label mer
     bsf portc,0 ; Slå på PORTC,0
     call Wait ; Vänta en viss tid
     bcf portc,0 ; Slå av PORTC,0
     call Wait Vänta en viss tid
     goto main ; Hoppla, börja om på main... igen och igen och igen
Rätt ska vara rätt, 'Wait'-rutinen är inte speciellt lättläst.

Har försedd med kommentarer som borde ge lite ledtrådar.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Här är en alternativ kod för 16F690.
Den är portad från 16F628A reakt av, testad i MPSIM
men inte kört på riktig hårdvara, men jag tror att det fungerar.

Kod: Markera allt

;**********************************************************************
;   Enkelt blink-a-led, 16F690.                                       *
;**********************************************************************
;   Filer :  P16F690.INC
;            16F690.LNK (läggs till som "linker Script" i projketet
;**********************************************************************

  list      p=16f690
  #include <p16f690.inc>
	
  __CONFIG   _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC

Boot            CODE    0x000     ; processor reset vector
  goto    start             ; go to beginning of program


INT_VECTOR      CODE    0x004     ; interrupt vector location
  goto    isr_routine       ; goto main interrupt service routine.
        

;***************************************************************
MAIN    CODE

start

  banksel ansel
  clrf    ansel             ; Stäng av alla analoga funktioner.

  banksel trisa
  clrf    trisa
  clrf    trisb
  clrf    trisc             ; Alla pinnar = utgångar.

  banksel t1con
  movlw   b'00110001'
  movwf   t1con             ; Se datablad, kap om TMR1...

; Ändra pre-scaler för olika blinkhastighet.
; T.ex b'00100001' ovan.
;          --      = pre-scaler biterna. Se databladet !
        
  banksel pie1
  movlw   b'00000001'
  movwf   pie1              ; Enable avbrott från TMR1.

  banksel intcon	
  bsf     intcon, peie
  bsf     intcon, gie       ; Enable avbrott generellt...

  banksel porta
  clrf    porta             ; Starta med ett känt värde i PORTA...

loop
  goto loop                 ; Vänta på avbrott...
 


;***************************************************************
ISR_ROUTINE  CODE

isr_routine

; OK, Timer1 har "snurrat runt" !

  banksel porta
  comf    porta            ; Blinka med hela PORTA!

; Notera att detta blinkar med alla pinnar i PORTA
; som är vanliga digitala I/O. Så t.ex inte RA3, den är MCLR.

  banksel pir1
  bcf     pir1, tmr1if     ; återställ avbrotts flagga.

; Klart, returnera och vänta på nästa avbrott från Timer1...

  retfie

  end
Stene
Inlägg: 276
Blev medlem: 13 maj 2008, 19:21:52
Ort: Uppsala

Inlägg av Stene »

Hej!
Jag har nu läst era svar och jag har provat att ändra lite som Swech skriver.
Jag provade att ändra Var2 equ 0x30 till 0x60 men jag såg ingen skillnad. Jag provade också att skriva ett tal som han skrev 0-255 men ingen skilnad. Därimot så ändrade jag den till 0x0c och då gick den fortare och 0x0f gick den saktare. Varför fungerade inte den han skrev?? vad är det jag ändrade?? Jag har ju fåt funktionen som jag eftersökte men jag vill ju veta vad jag har gjort för framtida projekt.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Men... VARFÖR ändrar equ?

Att Swech tydligen inte förstår att det bara är VILKEN ram-cell som används är ju beklagligt men har du alls läst andra inlägg?
Stene
Inlägg: 276
Blev medlem: 13 maj 2008, 19:21:52
Ort: Uppsala

Inlägg av Stene »

ok då vad det som jag trode att equ vad en adress. Ja jag har läst inläggen men förstår inte. Om man tittar på den koden jag skrev, vad är det som bestämer tiden på blinkningen där.
Den koden som sodjan skrev, var bestäms tiden där?
Ja jag vet att det är dumma frågor men jag vill lära mig det här.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

ops.. ja där ser man..
läser man för fort och är rostig på pic så kan det bli så.
I AVR världen använder man EQU för konstanter och mycket sällan
för adresser.. därav mitt misstag

Kod: Markera allt

Wait movlw 0xff    - ändrar du här istället till 0.255 så blinkar det snabbare
movwf var2 
loop2 movlw 0xff 
movwf var1 
loop1 decfsz var1,1 
goto loop1 
decfsz var2,1 
goto loop2 
return 
Du kan alltså justera hastigheten genom att ändra 0xff till ett tal mellan
0 och 255.
Det är dock som övriga säger inget vidare bra sätt att programmera på.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Stene: har du ens läst inlägget där jag kommenterade koden?

Det känns som att du skiter i vissa svar.
Stene
Inlägg: 276
Blev medlem: 13 maj 2008, 19:21:52
Ort: Uppsala

Inlägg av Stene »

ja jag har läst allt men tydligen missat det du skrev där.

Förlåt att jag inte fattar bättre!
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Swech skrev:I AVR världen använder man EQU för konstanter och mycket sällan
för adresser.. därav mitt misstag
Ingen som helst skillnad på AVR och PIC i det avseendet. Normalt sett så använder man EQU för fasta adresser och konstanter. Sedan kan man i vissa sammanhang använda EQU även för den konstanta adressen till en variabel, men det finns andra sätt att göra det på.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> läser man för fort och är rostig på pic så kan det bli så.
> I AVR världen använder man EQU för konstanter och mycket sällan
> för adresser..

För PIC så används EQU *enbart* för att definiera symboliska konstanter !
(Sen att dessa konstanter ibland/ofta används som minnesadresser är en helt annan sak...)

> ok då vad det som jag trode att equ vad en adress.

Det är det alltså inte. EQU definier en konstant (som du sen använder som
en adress, men det vet inte EQU ett smack om...)

Tron att EQU definierar/reserverar en minnesadress är ett av de vanligaste
missförstånden bland nybörjare, så ta det inte personligt... :-)

Kommandot som däremot verkligen reserverar minne heter RES.

> Om man tittar på den koden jag skrev, vad är det som bestämer tiden på blinkningen där.

Värdena som laddas till Var2 och Var1 med MOVLW/MOVWF i Wait rutinen.

Ett enklare sätt att skriva Wait är :

Kod: Markera allt

Wait    movlw 0xff    ; Ladda startvärde till Var2
        movwf var2
loop    decfsz var1,1 ; Räkna ner Var1 (alltid 256 varv !)
        goto loop
        decfsz var2,1 ; Räkna ner Var2...
        goto loop     ; Ej 0, kör ett varv till.
        return        ; Klart... 
> Den koden som sodjan skrev, var bestäms tiden där?

Främst inställningen av Timer1 prescaler. Sedan så låter jag Timer1
bara snurra runt (alltså 2**16) steg, så där finns det inte mycket att göra,
men det var inte avsikten heller. Det var därför jag skrev:

Kod: Markera allt

...
; Ändra pre-scaler för olika blinkhastighet.
; T.ex b'00100001' ovan.
;          --      = pre-scaler biterna. Se databladet !
...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Här är en version av din kod som är uppsnyggad, rättad och kommenterad.

Kod: Markera allt

;**********************************************************************
;   Enkelt blink-a-led, 16F690.                                       *
;**********************************************************************
;   Filer :  P16F690.INC
;            16F690.LNK (läggs till som "linker Script" i projektet
;**********************************************************************

  list      p=16f690
  #include <p16f690.inc>
	
  __CONFIG   _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC

;**********************************************************************
; Definition av konstanter och reservera variabler

delay EQU      h'8F'      ; Startvärde för wait loopen.

variabler      UDATA_SHR  ; Lägg variabler i "shared memory"...
var1  RES      1          ; Reservera 2 variabler för Wait loopen.
var2  RES      2          ;  - " -

;**********************************************************************
; Här börjar själva koden.

Boot  CODE     h'0000'    ; Starta allt på adress h'0000'

      clrw                ; Nolla W
      movwf    portc      ; Nolla PORTC
      banksel  trisc      ; Byt bank
      movwf    trisc      ; Nolla TRISC
      banksel  ansel      ; Byt bank igen...
      clrf     ansel      ; Sätt alla pinnar som digitala I/O pinnar.
      banksel  portc      ; Byt tillbaka till bank0 igen...

main_loop
      bsf      portc,0    ; Sätt RC0 = "1"
      call     Wait        
      bcf      portc,0    ; Sätt RC0 = "0"
      call     Wait
      goto     main_loop  ; Å så kör vi en sväng till...


Wait
      movlw    delay      ; Ladda startvärde till Var2
      movwf    var2

wait_loop
      nop                 ; Bara för att få ett bra "blink"...
      nop                 ; - " -
      nop                 ; - " -
      decfsz   var1, f    ; Räkna ner Var1 (alltid 256 varv !)
      goto     wait_loop  ; En gång till tills var1 = 0
      decfsz   var2, f    ; Räkna ner Var2...
      goto     wait_loop  ; Ej 0, kör ett varv till.
      return              ; Klart... 

      end
Stene
Inlägg: 276
Blev medlem: 13 maj 2008, 19:21:52
Ort: Uppsala

Inlägg av Stene »

Ok nu förstår jag lite mera, TACK för alla svar!!
Skriv svar