www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Merilec hitrosti
Pojdi na stran Prejšnja  1, 2, 3, 4  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Microchip PIC
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Sre Avg 05, 2009 9:46 pm    Naslov sporočila:   Odgovori s citatom

Tako kot je napisal snow se bolj gre za primerjave. Hitrosti bodo tukaj med 80 in 90 km/h, kar je med 0,045s in 0,04s. Seveda bo to povprečna hitrost na razdalji enega metra, kjer je a hitrost največja.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Čet Avg 06, 2009 1:44 pm    Naslov sporočila:   Odgovori s citatom

Skoraj sem že končal program. Čaka me še samo izpis izračunane hitrosti. Izračunana hitrost se shrani v registre Desetice, enice, desetinke. Merilec meri hitrosti od 55 km/h do 99,9 km/h. Če bo kdo preizkušal program v simulatorju, naj tam kjer program čaka na prekinitev drugega senzorja v register TMR1 vpiše čas v mi s med 36.000 in 65.530.
Koda:
   list   p=16f628a
   #include   <p16f628a.inc>
   
   __CONFIG   _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON
   
   Cblock   0x20      ; Blok za definicijo konstant
      Deljenec : 2      ; Deljenec (2 bajta)
      Deljitelj : 2      ; Deljitelj (2 bajta)
      Kolicnik : 2      ; Kolicnik (2 bajta)
      Ostanek: 2      ; Ostanek (2 bajta)
      Stevec         ; Stevec za deljenje
      Cas : 2         ; Preracunan cas
      Faktor1 : 2         ; Prvi faktor mnozenja (1 bajt)
      Faktor2         ; Drugi faktor mnozenja (1 bajt)
      Produkt : 3         ; Produkt (3 bajti)
      StevecM         ; Stevec za mnozenje
      Desetice
      Enice
      Desetinke
   endc         ; Konec bloka konstant
   
   org 0x000
   goto zacni
   org 0x004
      
zacni
      BSF STATUS, RP0
   MOVLW   B'00000000'       ;VSI SO IZHODI ZA LED PRIKAZOVALNIK
   MOVWF   TRISB
   MOVLW   B'00110000'       ;RA0,1,2 SO IZHODI ZA TRANZISTORJE RA5 IN 4 SO VHODI ZA SENZORJE
   MOVWF   TRISA

;**********************************nastavitve timerja**********************************
   
   BCF STATUS, RP0
   movlw   b'00000001'
   MOVWF   T1CON
;**********************************Meritev časa***************************************************

cakaj1   BTFSC   PORTA,5         ;ko se prvi senzor prekine, se stevec timerja resetira
   goto   cakaj1
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2   btfsc   PORTA,4         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
   goto   cakaj2   
;**********************************preračunavanje časa za lažje računanje (čas/36)************************   
   
   movf   TMR1H,0         ;
   movwf   Deljenec         ;
   movf   TMR1L, 0         ;  Čas iz timerja kopiramo v registre za deljenje
   movwf   Deljenec+1      ;

    movlw   0x00         ;
   movwf   Deljitelj         ;
   movlw   0x24         ;Delitelj= 36 = 0x0024
   movwf   Deljitelj+1      ;
   call   Deli16         ; Klici deljenje            
   movf   Kolicnik,0
   movwf   Cas
   movf   Kolicnik+1,0
   movwf   Cas+1            
;*******************************izračun hitrosti 'desetice'**************************************************               
   
   
   movlw   0x27         ;Deljenec=10.000
   movwf   Deljenec         ;Delitelj=preračunan čas
   movlw   0x10         
   movwf   Deljenec+1
   movf   Cas,0
   clrf   Deljitelj
   movwf   Deljitelj
   movf   Cas+1,0
   clrf   Deljitelj+1
   Movwf   Deljitelj+1
   call   Deli16
   movf   Kolicnik+1,0
   movwf   Desetice         ;rezultat prenesemo v desetice
            

;*****************************Izračun hitrosti 'enice'********************************************************************************
   call   ostanek         ;ostanek množimo z deset
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Enice         ;Rezultat kopiramo v register enice

;*****************************Izračun hitrosti 'desetinke'*************************************
   call   ostanek
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Desetinke         ;Rezultat kopiramo v register enice   

zanka   goto   zanka
         ; Neskoncna zanka





;***** DELJENJE: Deljenec / Deljitelj = Kolicnik in Ostanek **************

Deli16
   clrf   Kolicnik
   clrf   Kolicnik+1      ; Izbrisemo Kolicnik
   clrf   Ostanek
   clrf   Ostanek+1      ; Izbrisemo ostanek
   movlw   .17
   movwf   Stevec         ; 17 -> Stevec (stevilo ponovitev+1)
Delaj
   decf   Stevec,f      ; Zmanjsamo Stevec
   btfsc   STATUS,Z      ; Ali je stevec ze 0?
   return            ; Da, koncaj deljenje
   rlf   Deljenec+1,f
   rlf   Deljenec,f      ; Pomakni cel Deljenec v levo
   rlf   Ostanek+1,f
   rlf   Ostanek,f      ; Pomakni cel Ostanek v levo s C
   call   Deli         ; Klici pomozni podprogram za Kolicnik
   goto   Delaj         ; Nadaljuj (16x)
   
;********************* POMOZNI PODPROGRAM ZA DELJENJE ********************

Deli
   movf   Deljitelj+1,w      ; Nizji bajt deljitelja -> W
   subwf   Ostanek+1,f      ; Odstej od nizjega bajta ostanka
   movf   Deljitelj,w      ; Visji bajt deljitelja -> W
   btfss   STATUS,C      ; Ali je prislo do prenosa (C=0)?
   incf   Deljitelj,w      ; Da, povecaj deljitelj -> W
   subwf   Ostanek,f      ; Odstej od visjega bajta ostanka
   btfss   STATUS,C      ; Ali je rezultat negativen (C=0)?
   goto   Negativno      ; Da, skoci na Negativno
   bsf   STATUS,C      ; Ne, C=1
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo in LSB=C=1
   return            ; Konec pomoznega podprograma
Negativno
   bcf   STATUS,C      ; C=0
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo, LSB=C=0
   movf   Deljitelj+1,w
   addwf   Ostanek+1,f
   btfsc   STATUS,C
   incf   Ostanek,f
   movf   Deljitelj,w
   addwf   Ostanek,f      ; 16 bitno sestej Kolicnik in Ostanek, da
               ; dobis spet prvoten ostanek (pozitiven)
   return            ; Konec pomoznega podprograma

;**********************Podprogram za množenje***************************************

mnozenje
   clrf   Produkt+0      ;clear result
   clrf   Produkt+1      ;
   clrf   Produkt+2      ;
   movlw   .8      
   movwf   StevecM   ;bit counter set @ number of bits in multiplier

mul_L1               ;main loop here
   rlf   Produkt+2,f         ;rotate result left (*2)
   rlf   Produkt+1,f         ;
   rlf   Produkt+0,f         ;
   bcf   Produkt+2,0         ;clear LSB of result after rotation
   btfss   Faktor2,7         ;test msb of multipier
   goto   dontAdd         ;if bit is clear then dont add
   movfw      Faktor1+1            ;Add the 16 bits of AA to product
   addwf      Produkt+2,f         ;
   skpnc               ;
   incf   Produkt+1,f         ;
   movfw      Faktor1            ;
   addwf      Produkt+1,f         ;
   skpnc               ;
   incf   Produkt+0,f         ;
dontAdd
   rlf   Faktor2,f         ;rotate multiplier left
   decfsz   StevecM,f      ;chk if finished all bits in multiplier
   goto   mul_L1

   return
;******************************Množenje ostanka z deset iz prejšnjega deljenja*******************************   
ostanek
   movf   Ostanek,0
   movwf   Faktor1
   movf   Ostanek+1,0
   movwf   Faktor1+1
   movlw   0x0a
   movwf   Faktor2
   call   mnozenje
   return   
   
   END
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Sob Sep 12, 2009 3:20 pm    Naslov sporočila:   Odgovori s citatom

Dokončal sem program. Imam 2 verziji programa. Vezje že imam na protobrodu. Senzorjev še nimam, zaenkrat jih simuliram z drugim picem. Prva verzija mi dela tako kot mora. Senzorja preverjam z ukazom "BTFSC". V drugi verziji pa za "branje" prvega senzorja uporabljam prekinitev. Ta druga mi ne deluje.
Koda:
list   p=16f628a
   #include   <p16f628a.inc>
   
   
   
   Cblock   0x20      ; Blok za definicijo konstant
      Deljenec : 2      ; Deljenec (2 bajta)
      Deljitelj : 2      ; Deljitelj (2 bajta)
      Kolicnik : 2      ; Kolicnik (2 bajta)
      Ostanek: 2      ; Ostanek (2 bajta)
      Stevec         ; Stevec za deljenje
      Cas : 2         ; Preracunan cas
      Faktor1 : 2         ; Prvi faktor mnozenja (1 bajt)
      Faktor2         ; Drugi faktor mnozenja (1 bajt)
      Produkt : 3         ; Produkt (3 bajti)
      StevecM         ; Stevec za mnozenje
      Desetice
      Enice
      Desetinke
      d1
      d2
      d3
      d4
   endc         ; Konec bloka konstant
   
   org 0x000
   goto zacni
   org 0x004
   goto   zacetek      
zacni
      BSF STATUS, RP0
   MOVLW   B'10000000'       ;RB0 - RB6  SO IZHODI ZA LED PRIKAZOVALNIK, RB7 sproži prekinitev (prvi senzor)
   MOVWF   TRISB
   MOVLW   B'00000001'       ;RA1,2,3 SO IZHODI ZA TRANZISTORJE
   MOVWF   TRISA

;**********************************nastavitve timerja in prekinitve**********************************
   
   BCF STATUS, RP0
   movlw   b'00000001'
   MOVWF   T1CON
   movlw   b'10001000'
   movwf   INTCON
   movlw   0x07
   movwf   CMCON
   movlw   b'00001000'
   movwf   PORTB
   movlw   b'00000010'
   movwf   PORTA
;**********************************Meritev časa***************************************************
ABC   goto   ABC

zacetek
   bcf   INTCON,7
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2   btfsc   PORTA,0         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
   goto   cakaj2   
;**********************************preračunavanje časa za lažje računanje (čas/36)************************   
   
   movf   TMR1H,0         ;
   movwf   Deljenec         ;
   movf   TMR1L, 0         ;  Čas iz timerja kopiramo v registre za deljenje
   movwf   Deljenec+1      ;

    movlw   0x00         ;
   movwf   Deljitelj         ;
   movlw   0x24         ;Delitelj= 36 = 0x0024
   movwf   Deljitelj+1      ;
   call   Deli16         ; Klici deljenje            
   movf   Kolicnik,0
   movwf   Cas
   movf   Kolicnik+1,0
   movwf   Cas+1            
;*******************************izračun hitrosti 'desetice'**************************************************               
   
   
   movlw   0x27         ;Deljenec=10.000
   movwf   Deljenec         ;Delitelj=preračunan čas
   movlw   0x10         
   movwf   Deljenec+1
   movf   Cas,0
   clrf   Deljitelj
   movwf   Deljitelj
   movf   Cas+1,0
   clrf   Deljitelj+1
   Movwf   Deljitelj+1
   call   Deli16
   movf   Kolicnik+1,0
   movwf   Desetice         ;rezultat prenesemo v desetice
            

;*****************************Izračun hitrosti 'enice'********************************************************************************
   call   ostanek         ;ostanek množimo z deset
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Enice         ;Rezultat kopiramo v register enice

;*****************************Izračun hitrosti 'desetinke'*************************************
   call   ostanek
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Desetinke         ;Rezultat kopiramo v register enice   


;*****************************Izpis hitrosti*****************************************************         ; Neskoncna zanka
   bsf   INTCON,7
XXX   movf   Desetice,0
   call   TABELA
   movwf   PORTB
   movlw   b'00000010'
   movwf   PORTA
   call   pavzamux
   bcf   PORTA,1
   movf   Enice,0
   call   TABELA
   movwf   PORTB
   movlw   b'0001000'
   movwf   PORTA
   call   pavzamux
   clrf   PORTA
   movf   Desetinke,0
   call   TABELA
   movwf   PORTB
   bsf   PORTA,2
   call   pavzamux
   goto   XXX





;***** DELJENJE: Deljenec / Deljitelj = Kolicnik in Ostanek **************

Deli16
   clrf   Kolicnik
   clrf   Kolicnik+1      ; Izbrisemo Kolicnik
   clrf   Ostanek
   clrf   Ostanek+1      ; Izbrisemo ostanek
   movlw   .17
   movwf   Stevec         ; 17 -> Stevec (stevilo ponovitev+1)
Delaj
   decf   Stevec,f      ; Zmanjsamo Stevec
   btfsc   STATUS,Z      ; Ali je stevec ze 0?
   return            ; Da, koncaj deljenje
   rlf   Deljenec+1,f
   rlf   Deljenec,f      ; Pomakni cel Deljenec v levo
   rlf   Ostanek+1,f
   rlf   Ostanek,f      ; Pomakni cel Ostanek v levo s C
   call   Deli         ; Klici pomozni podprogram za Kolicnik
   goto   Delaj         ; Nadaljuj (16x)
   
;********************* POMOZNI PODPROGRAM ZA DELJENJE ********************

Deli
   movf   Deljitelj+1,w      ; Nizji bajt deljitelja -> W
   subwf   Ostanek+1,f      ; Odstej od nizjega bajta ostanka
   movf   Deljitelj,w      ; Visji bajt deljitelja -> W
   btfss   STATUS,C      ; Ali je prislo do prenosa (C=0)?
   incf   Deljitelj,w      ; Da, povecaj deljitelj -> W
   subwf   Ostanek,f      ; Odstej od visjega bajta ostanka
   btfss   STATUS,C      ; Ali je rezultat negativen (C=0)?
   goto   Negativno      ; Da, skoci na Negativno
   bsf   STATUS,C      ; Ne, C=1
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo in LSB=C=1
   return            ; Konec pomoznega podprograma
Negativno
   bcf   STATUS,C      ; C=0
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo, LSB=C=0
   movf   Deljitelj+1,w
   addwf   Ostanek+1,f
   btfsc   STATUS,C
   incf   Ostanek,f
   movf   Deljitelj,w
   addwf   Ostanek,f      ; 16 bitno sestej Kolicnik in Ostanek, da
               ; dobis spet prvoten ostanek (pozitiven)
   return            ; Konec pomoznega podprograma

;**********************Podprogram za množenje***************************************

mnozenje
   clrf   Produkt+0      ;clear result
   clrf   Produkt+1      ;
   clrf   Produkt+2      ;
   movlw   .8      
   movwf   StevecM   ;bit counter set @ number of bits in multiplier

mul_L1               ;main loop here
   rlf   Produkt+2,f         ;rotate result left (*2)
   rlf   Produkt+1,f         ;
   rlf   Produkt+0,f         ;
   bcf   Produkt+2,0         ;clear LSB of result after rotation
   btfss   Faktor2,7         ;test msb of multipier
   goto   dontAdd         ;if bit is clear then dont add
   movfw      Faktor1+1            ;Add the 16 bits of AA to product
   addwf      Produkt+2,f         ;
   skpnc               ;
   incf   Produkt+1,f         ;
   movfw      Faktor1            ;
   addwf      Produkt+1,f         ;
   skpnc               ;
   incf   Produkt+0,f         ;
dontAdd
   rlf   Faktor2,f         ;rotate multiplier left
   decfsz   StevecM,f      ;chk if finished all bits in multiplier
   goto   mul_L1

   return
;******************************Množenje ostanka z deset iz prejšnjega deljenja*******************************   
ostanek
   movf   Ostanek,0
   movwf   Faktor1
   movf   Ostanek+1,0
   movwf   Faktor1+1
   movlw   0x0a
   movwf   Faktor2
   call   mnozenje
   return   
   
;*********************TABELA********************

TABELA
   
   addwf PCL,f
   retlw b'01110111'   ;0
   retlw b'01000001'   ;1
   retlw b'00111011'   ;2
   retlw b'01101011'   ;3
   retlw b'01001101'   ;4
   retlw b'01101110'   ;5
   retlw b'01111110'   ;6
   retlw b'01000011'   ;7
   retlw b'01111111'   ;8
   retlw b'01101111'   ;9


;****************pavza za mux************************

pavzamux
         ;993 cycles
   movlw   0xC6
   movwf   d1
   movlw   0x01
   movwf   d2
pavzamux_0
   decfsz   d1, f
   goto   $+2
   decfsz   d2, f
   goto   pavzamux_0

         ;3 cycles
   goto   $+1
   nop

         ;4 cycles (including call)
   return

   END
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
bungee
Član
Član



Pridružen-a: Pon 07 Mar 2005 18:49
Prispevkov: 1479
Aktiv.: 6.24
Kraj: Ljubljana

PrispevekObjavljeno: Sob Sep 12, 2009 10:45 pm    Naslov sporočila:   Odgovori s citatom

Pri interrupt rutini skočiš ven na čakanje.

Če boš vse skupaj reševal z interruptom, kar se seveda da zelo elegantno rešiti imaš par možnosti. Ena bi bila, ta da oba senzorja vežeš na isti vhod. In potem bi interrupt rutina zgledala takole:

1. Preveriš, če je to prvi interrupt, če je potem pobrišeš timer s katerim meriš čas in postaviš zastavico, da se je interrupt že zgodil in skočiš ven iz ISR.

2. Ker se je prvi interrupt že zgodil, shraniš vrednost timerja v spremenljivko in postaviš zastavico, da je v spremenljivki veljaven podatek in počistiš zastavico za prvi interrupt.

To je kar se interrupt rutine tiče to, pa ker sem dobra duša še C primer kode za ISR:

Koda:
#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000)

int1 prvi_interrupt,veljavni_podatki;
int16 merjen_cas;

#int_EXT
void  EXT_isr(void)
{
   if (!prvi_interrupt)
   {
      set_timer1(0);
      prvi_interrupt=1;
      veljavni_podatki=0;
   }   
   else
   {
      merjen_cas=get_timer1();
      prvi_interrupt=0;
      veljavni_podatki=1;
   }   
}



void main()
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); //Resolucija 2us ....
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   
   while (1)
   {
      if(veljavni_podatki)
      {
         //Izpiši podatke ....
         veljavni_podatki=0;
      }   
   }   

}


No, pa da bom še boljša, tole izpljune prevajalnik ven v ASM ... mogoče ti pomaga ... najprej compiler pripravi teren za interrup rutino.... in potem sledi le ta:
Koda:

 004    00FF     MOVWF 0x7f
   005    0E03     SWAPF 0x3, W
   006    0183     CLRF 0x3
   007    00A1     MOVWF 0x21
   008    087F     MOVF 0x7f, W
   009    00A0     MOVWF 0x20
   00A    080A     MOVF 0xa, W
   00B    00A8     MOVWF 0x28
   00C    018A     CLRF 0xa
   00D    0EA0     SWAPF 0x20, F
   00E    0804     MOVF 0x4, W
   00F    00A2     MOVWF 0x22
   010    0877     MOVF 0x77, W
   011    00A3     MOVWF 0x23
   012    0878     MOVF 0x78, W
   013    00A4     MOVWF 0x24
   014    0879     MOVF 0x79, W
   015    00A5     MOVWF 0x25
   016    087A     MOVF 0x7a, W
   017    00A6     MOVWF 0x26
   018    087B     MOVF 0x7b, W
   019    00A7     MOVWF 0x27
   01A    1383     BCF 0x3, 0x7
   01B    1283     BCF 0x3, 0x5
   01C    1E0B     BTFSS 0xb, 0x4
   01D    2820     GOTO 0x20
   01E    188B     BTFSC 0xb, 0x1
   01F    2833     GOTO 0x33
   020    0822     MOVF 0x22, W
   021    0084     MOVWF 0x4
   022    0823     MOVF 0x23, W
   023    00F7     MOVWF 0x77
   024    0824     MOVF 0x24, W
   025    00F8     MOVWF 0x78
   026    0825     MOVF 0x25, W
   027    00F9     MOVWF 0x79
   028    0826     MOVF 0x26, W
   029    00FA     MOVWF 0x7a
   02A    0827     MOVF 0x27, W
   02B    00FB     MOVWF 0x7b
   02C    0828     MOVF 0x28, W
   02D    008A     MOVWF 0xa
   02E    0E21     SWAPF 0x21, W
   02F    0083     MOVWF 0x3
   030    0EFF     SWAPF 0x7f, F
   031    0E7F     SWAPF 0x7f, W
   032    0009     RETFIE


18:                void  EXT_isr(void)
19:                {
20:                   if (!prvi_interrupt)
   033    1829     BTFSC 0x29, 0
   034    283A     GOTO 0x3a
21:                   {
22:                      set_timer1(0);
   035    018F     CLRF 0xf
   036    018E     CLRF 0xe
23:                      prvi_interrupt=1;
   037    1429     BSF 0x29, 0
24:                      veljavni_podatki=0;
   038    10A9     BCF 0x29, 0x1
25:                   }   
26:                   else
   039    2848     GOTO 0x48
27:                   {
28:                      merjen_cas=get_timer1();
   03A    080F     MOVF 0xf, W
   03B    00FA     MOVWF 0x7a
   03C    080E     MOVF 0xe, W
   03D    00F7     MOVWF 0x77
   03E    080F     MOVF 0xf, W
   03F    027A     SUBWF 0x7a, W
   040    1D03     BTFSS 0x3, 0x2
   041    283A     GOTO 0x3a
   042    0877     MOVF 0x77, W
   043    00AA     MOVWF 0x2a
   044    087A     MOVF 0x7a, W
   045    00AB     MOVWF 0x2b
29:                      prvi_interrupt=0;
   046    1029     BCF 0x29, 0
30:                      veljavni_podatki=1;
   047    14A9     BSF 0x29, 0x1
31:                   }   
32:                }
33:               
34:               
35:               
   048    108B     BCF 0xb, 0x1
   049    118A     BCF 0xa, 0x3
   04A    2820     GOTO 0x20


Tole se da še veliko stvari, ki jih ne potrebuješ še ven zmetat..... Wink
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
dkone
Član
Član



Pridružen-a: Sre 07 Mar 2007 18:53
Prispevkov: 2116
Aktiv.: 9.51
Kraj: Krško

PrispevekObjavljeno: Ned Sep 13, 2009 9:02 am    Naslov sporočila:   Odgovori s citatom

igo je napisal/a:
Koda:

;v cblock-u uvedi nove spremenljivke
w_copy ; kopija od W
s_copy  ; STATUS kopija
zastavice
 
;definiraj posamezne zastavice
#define zNovaMer zastavice,0
 
zacetek
Prekin ; sem se pride s prekinitvijo na RB,0 pinu.
  movwf w_copy  ; w kopija
  swapf STATUS, w  ; STATUS kopija
  clrf STATUS ; Banka 0
  movwf s_copy  ; STATUS kopija
   bcf   INTCON,7
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2
; morda bi bilo dobro tule preverjati tudi TMR1H overflow zastavico.
; Če se je zgodila prekinitev na RB,0 , 2. senzor pa se sploh ni aktiviral, se vrneš preko goto PrekinX
;  z novimi spremenljivkami Stotice/Desetice/Enice in izpišeš --- .
   btfsc   PORTA,0         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
   goto   cakaj2   
PrekinOK ; dobra prekinitev
   movf   TMR1H,0         ;
   movwf   Deljenec         ;
   movf   TMR1L, 0         ;  Čas iz timerja kopiramo v registre za deljenje
   movwf   Deljenec+1      ; Pozor ! TMR1L lahko v teh dveh korakih pred shranitvijo prekorači 255
; bi moral 2x decf Deljenec+1,f , preveriti STATUS,C in po potrebi še decf Deljenec,f
  bsf zNovaMe ; Zastavica Nova Meritev
  goto PrekinV ; ven
PrekinX ; slaba prekinitev
  movlw ... ;  -  segment g
  movwf Stotice
  movwf Desetice
  movwf Enice
 ; brez zastavice zNovaMer ne gre v Racun, ampak direkt izpiše ---
PrekinV ; ven
 swapf s_copy,w ; povrne STATUS
 movwf STATUS
 swapf w_copy,f ; Povrne W, skupaj s STATUS zastavicami
 swapf w_copy,w
  retfie  ; prekinitev je podprogram, zato se moraš iz nje vrniti
 
;**********************************preračunavanje časa za lažje računanje (čas/36)************************   
Racun ;
   bcf zNovaMer ; Pobrišeš zastavico
   ;movf   TMR1H,0         ; Tega več ne rabiš, saj že v prekinitvi shraniš TMR1[H/L]
   ;movwf   Deljenec         ;
   ;movf   TMR1L, 0         ;   
   ;movwf   Deljenec+1      ;
...... komplet račun. Prednost ima najprej množenje, nato deljenje, zaradi bistveno manjše napake. Poskusi optimizirati račun.
...
 
zanka ; tukaj se kroži večino časa in izpisuje rezultat
   bsf   INTCON,7
XXX   movf   Desetice,0
   call   TABELA
   movwf   PORTB
   movlw   b'00000010'
... muxanje ...
btfss zNovaMer ; Ali se je zgodila nova meritev?
 goto   XXX ; NE, izpisuj naprej
 goto Racun ; JA, izračunaj novo vrednost za prikaz

LP,
Igor

_________________
Denis
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Ned Sep 13, 2009 10:08 am    Naslov sporočila:   Odgovori s citatom

Super Dancing
Uspelo mi je še s prekinitvijo. Napaka je bila, ker sem takoj po izračunu prehitro nazaj omogočil prekinitve.

Kako pa sedaj "varno" omogočiti prekinitev po izračunu. Kaj sploh sproži novo prekinitev? Timer se po štetju časa ustavi.

Edit: Rešil sem še to. Po meritvi časa ni bilo dovolj samo onemogočiti prekinitve, ampak pobriše se cel INTCON.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Ned Sep 13, 2009 10:49 am    Naslov sporočila:   Odgovori s citatom

Še v celoti delujoč program
Koda:
   list   p=16f628a
   #include   <p16f628a.inc>
   
   
   
   Cblock   0x20      ; Blok za definicijo konstant
      Deljenec : 2      ; Deljenec (2 bajta)
      Deljitelj : 2      ; Deljitelj (2 bajta)
      Kolicnik : 2      ; Kolicnik (2 bajta)
      Ostanek: 2      ; Ostanek (2 bajta)
      Stevec         ; Stevec za deljenje
      Cas : 2         ; Preracunan cas
      Faktor1 : 2         ; Prvi faktor mnozenja (1 bajt)
      Faktor2         ; Drugi faktor mnozenja (1 bajt)
      Produkt : 3         ; Produkt (3 bajti)
      StevecM         ; Stevec za mnozenje
      Desetice
      Enice
      Desetinke
      d1
      d2
      d3
      d4
   endc         ; Konec bloka konstant
   
   org 0x000
   goto zacni
   org 0x004
   bcf   INTCON,7         ;onemogočimo prekinitev   
   btfsc   INTCON,1
   goto   zacetek         ;če je prekinitev sprožil senzor, pojdi na začetek
   
zacni      
   BSF STATUS, RP0
   MOVLW   B'00000001'       ;RB0 - RB6  SO IZHODI ZA LED PRIKAZOVALNIK, RB0 sproži prekinitev (prvi senzor)
   MOVWF   TRISB
   MOVLW   B'00000001'       ;RA1,2,3 SO IZHODI ZA TRANZISTORJE
   MOVWF   TRISA
   movlw   b'10000000'
   movwf   OPTION_REG      ;pull-up off, prekinitev se sproži, ko je RB0 nizek
;**********************************nastavitve timerja in prekinitve**********************************
   
   BCF STATUS, RP0
   movlw   b'00000001'
   MOVWF   T1CON         
   movlw   b'10010000'
   movwf   INTCON         ;omogočimo prekinitve, sproži jih RB0 in overflow timerja
   movlw   0x07
   movwf   CMCON
   movlw   b'00001000'
   movwf   PORTB         ;črtica
   movlw   b'00000010'
   movwf   PORTA
;**********************************Meritev časa***************************************************
ABC   goto   ABC

zacetek
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2   btfsc   PORTA,0         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
    goto   cakaj2   
;**********************************preračunavanje časa za lažje računanje (čas/36)************************   
   clrf   INTCON
   movf   TMR1H,0         ;
   movwf   Deljenec         ;
   movf   TMR1L, 0         ;  Čas iz timerja kopiramo v registre za deljenje
   movwf   Deljenec+1      ;

    movlw   0x00         ;
   movwf   Deljitelj         ;
   movlw   0x24         ;Delitelj= 36 = 0x0024
   movwf   Deljitelj+1      ;
   call   Deli16         ; Klici deljenje            
   movf   Kolicnik,0
   movwf   Cas
   movf   Kolicnik+1,0
   movwf   Cas+1            
;*******************************izračun hitrosti 'desetice'**************************************************               
   
   
   movlw   0x27         ;Deljenec=10.000
   movwf   Deljenec         ;Delitelj=preračunan čas
   movlw   0x10         
   movwf   Deljenec+1
   movf   Cas,0
   clrf   Deljitelj
   movwf   Deljitelj
   movf   Cas+1,0
   clrf   Deljitelj+1
   Movwf   Deljitelj+1
   call   Deli16
   movf   Kolicnik+1,0
   movwf   Desetice         ;rezultat prenesemo v desetice
            

;*****************************Izračun hitrosti 'enice'********************************************************************************
   call   ostanek         ;ostanek množimo z deset
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Enice         ;Rezultat kopiramo v register enice

;*****************************Izračun hitrosti 'desetinke'*************************************
   call   ostanek
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Desetinke         ;Rezultat kopiramo v register enice   


;*****************************Izpis hitrosti*****************************************************         ; Neskoncna zanka
   
   movlw   b'10010000'
   movwf   INTCON   
XXX   movf   Desetice,0
   call   TABELA
   movwf   PORTB
   movlw   b'00000010'
   movwf   PORTA
   call   pavzamux
   bcf   PORTA,1
   movf   Enice,0
   call   TABELA
   movwf   PORTB
   movlw   b'0001000'
   movwf   PORTA
   call   pavzamux
   clrf   PORTA
   movf   Desetinke,0
   call   TABELA
   movwf   PORTB
   bsf   PORTA,2
   call   pavzamux
   goto   XXX





;***** DELJENJE: Deljenec / Deljitelj = Kolicnik in Ostanek **************

Deli16
   clrf   Kolicnik
   clrf   Kolicnik+1      ; Izbrisemo Kolicnik
   clrf   Ostanek
   clrf   Ostanek+1      ; Izbrisemo ostanek
   movlw   .17
   movwf   Stevec         ; 17 -> Stevec (stevilo ponovitev+1)
Delaj
   decf   Stevec,f      ; Zmanjsamo Stevec
   btfsc   STATUS,Z      ; Ali je stevec ze 0?
   return            ; Da, koncaj deljenje
   rlf   Deljenec+1,f
   rlf   Deljenec,f      ; Pomakni cel Deljenec v levo
   rlf   Ostanek+1,f
   rlf   Ostanek,f      ; Pomakni cel Ostanek v levo s C
   call   Deli         ; Klici pomozni podprogram za Kolicnik
   goto   Delaj         ; Nadaljuj (16x)
   
;********************* POMOZNI PODPROGRAM ZA DELJENJE ********************

Deli
   movf   Deljitelj+1,w      ; Nizji bajt deljitelja -> W
   subwf   Ostanek+1,f      ; Odstej od nizjega bajta ostanka
   movf   Deljitelj,w      ; Visji bajt deljitelja -> W
   btfss   STATUS,C      ; Ali je prislo do prenosa (C=0)?
   incf   Deljitelj,w      ; Da, povecaj deljitelj -> W
   subwf   Ostanek,f      ; Odstej od visjega bajta ostanka
   btfss   STATUS,C      ; Ali je rezultat negativen (C=0)?
   goto   Negativno      ; Da, skoci na Negativno
   bsf   STATUS,C      ; Ne, C=1
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo in LSB=C=1
   return            ; Konec pomoznega podprograma
Negativno
   bcf   STATUS,C      ; C=0
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo, LSB=C=0
   movf   Deljitelj+1,w
   addwf   Ostanek+1,f
   btfsc   STATUS,C
   incf   Ostanek,f
   movf   Deljitelj,w
   addwf   Ostanek,f      ; 16 bitno sestej Kolicnik in Ostanek, da
               ; dobis spet prvoten ostanek (pozitiven)
   return            ; Konec pomoznega podprograma

;**********************Podprogram za množenje***************************************

mnozenje
   clrf   Produkt+0      ;clear result
   clrf   Produkt+1      ;
   clrf   Produkt+2      ;
   movlw   .8      
   movwf   StevecM   ;bit counter set @ number of bits in multiplier

mul_L1               ;main loop here
   rlf   Produkt+2,f         ;rotate result left (*2)
   rlf   Produkt+1,f         ;
   rlf   Produkt+0,f         ;
   bcf   Produkt+2,0         ;clear LSB of result after rotation
   btfss   Faktor2,7         ;test msb of multipier
   goto   dontAdd         ;if bit is clear then dont add
   movfw      Faktor1+1            ;Add the 16 bits of AA to product
   addwf      Produkt+2,f         ;
   skpnc               ;
   incf   Produkt+1,f         ;
   movfw      Faktor1            ;
   addwf      Produkt+1,f         ;
   skpnc               ;
   incf   Produkt+0,f         ;
dontAdd
   rlf   Faktor2,f         ;rotate multiplier left
   decfsz   StevecM,f      ;chk if finished all bits in multiplier
   goto   mul_L1

   return
;******************************Množenje ostanka z deset iz prejšnjega deljenja*******************************   
ostanek
   movf   Ostanek,0
   movwf   Faktor1
   movf   Ostanek+1,0
   movwf   Faktor1+1
   movlw   0x0a
   movwf   Faktor2
   call   mnozenje
   return   
   
;*********************TABELA********************

TABELA
   
   addwf PCL,f
   retlw b'11110110'   ;0
   retlw b'11000000'   ;1
   retlw b'10111010'   ;2
   retlw b'11101010'   ;3
   retlw b'11001100'   ;4
   retlw b'01101110'   ;5
   retlw b'01111110'   ;6
   retlw b'11000010'   ;7
   retlw b'11111110'   ;8
   retlw b'11101110'   ;9


;****************pavza za mux************************

pavzamux
         ;993 cycles
   movlw   0xC6
   movwf   d1
   movlw   0x01
   movwf   d2
pavzamux_0
   decfsz   d1, f
   goto   $+2
   decfsz   d2, f
   goto   pavzamux_0

         ;3 cycles
   goto   $+1
   nop

         ;4 cycles (including call)
   return

   END
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
bungee
Član
Član



Pridružen-a: Pon 07 Mar 2005 18:49
Prispevkov: 1479
Aktiv.: 6.24
Kraj: Ljubljana

PrispevekObjavljeno: Ned Sep 13, 2009 11:33 am    Naslov sporočila:   Odgovori s citatom

Vitez, ti še vedno nisi dojel kaj prekinitev sploh pomeni. V tvoji kodi se nikoli ne vrneš iz prekinitvene rutine. Manjka ti shranjevanje vrednosti W registra pa še kakšne pametne stvati, na koncu prekinitve nimaš RETFIE!!!! d'oh! d'oh!

Interrupta ne uporabljaj na tak način, ker ti ne bo delovalo tako kot mora, doživljal boš nepredvidene rezultate. Poglej si kako sem napisal prekinitveno rutino jaz, sicer je res v C-ju, ampak je napisana tako kot mora biti. Čakanje in delay funkcije ne sodijo v interrupt. Exclamation

Če pa potrebuješ kdaj pogovor v živo o prekinitvah, pa se lahko kdaj dobiva, da ti objasnim kakšno vlogo imajo in kako "varno" programirati prekinitvene rutine. Wink
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Ned Sep 13, 2009 2:41 pm    Naslov sporočila:   Odgovori s citatom

Ja vem tole prekinitev sem uporabljel malo po svoje. V bistvu je cel program cel čas ena prekinitev. Drugače pa razumem prekinitve. Je zelo lepo razloženo v knjigi "Programirajmo mikrokontrolerje" Pa najlepša hvala za pomoč
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Ned Sep 13, 2009 7:30 pm    Naslov sporočila:   Odgovori s citatom

Uredil sem to prekinitev tako kot je treba. Predpostavljal sem, da hitrosti ne bodo manjše od 60 km/h. Sedaj pa bi rad, da bi bilo možno meriti manjše hitrosti. Hočem sprožiti prekinitev z overflow-om (BTW, kako se to reče po naše?), a mi ne uspe. Če sem dobro prebral datasheet, moram postaviti bit TMR1IE v registru PIE. Ko se timer overflow-a, se zastavica (PIR<0>) postavi na 1, prekinitev se pa ne sproži Brick wall
Koda:
list   p=16f628a
   #include   <p16f628a.inc>
   
   
   
   Cblock   0x20      ; Blok za definicijo konstant
      Deljenec : 2      ; Deljenec (2 bajta)
      Deljitelj : 2      ; Deljitelj (2 bajta)
      Kolicnik : 2      ; Kolicnik (2 bajta)
      Ostanek: 2      ; Ostanek (2 bajta)
      Stevec         ; Stevec za deljenje
      Cas : 2         ; Preracunan cas
      Faktor1 : 2         ; Prvi faktor mnozenja (1 bajt)
      Faktor2         ; Drugi faktor mnozenja (1 bajt)
      Produkt : 3         ; Produkt (3 bajti)
      StevecM         ; Stevec za mnozenje
      Desetice
      Enice
      Desetinke
      d1
      d2
      d3
      d4
   endc         ; Konec bloka konstant
   
   org 0x000
   goto zacni
   org 0x004
   bcf   INTCON,7         ;onemogočimo prekinitev   
   btfsc   INTCON,1
   goto   zacetek         ;če je prekinitev sprožil senzor, pojdi na začetek
   btfsc   PIR1,0
   nop
   retfie
zacni      
   BSF STATUS, RP0
   MOVLW   B'00000001'       ;RB0 - RB6  SO IZHODI ZA LED PRIKAZOVALNIK, RB0 sproži prekinitev (prvi senzor)
   MOVWF   TRISB
   MOVLW   B'00000001'       ;RA1,2,3 SO IZHODI ZA TRANZISTORJE
   MOVWF   TRISA
   movlw   b'10000000'
   movwf   OPTION_REG      ;pull-up off, prekinitev se sproži, ko je RB0 nizek
;**********************************nastavitve timerja in prekinitve**********************************
   bsf   PIE1,0
   BCF STATUS, RP0
   
   movlw   b'00000001'
   MOVWF   T1CON         
   movlw   b'10010000'
   movwf   INTCON         ;omogočimo prekinitve, sproži jih RB0 in overflow timerja
   movlw   0x07
   movwf   CMCON
   movlw   .10
   movwf   Desetice
   movwf   Enice
   movwf   Desetinke
   goto    IZPIS
;**********************************Meritev časa***************************************************
   
zacetek
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2   btfsc   PORTA,0         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
    goto   cakaj2   
   goto   rac         ;pojdi na računanje



;**********************************preračunavanje časa za lažje računanje (čas/36)************************   
rac   
   clrf   INTCON
   movf   TMR1H,0         ;
   movwf   Deljenec         ;
   movf   TMR1L, 0         ;  Čas iz timerja kopiramo v registre za deljenje
   movwf   Deljenec+1      ;

    movlw   0x00         ;
   movwf   Deljitelj         ;
   movlw   0x24         ;Delitelj= 36 = 0x0024
   movwf   Deljitelj+1      ;
   call   Deli16         ; Klici deljenje            
   movf   Kolicnik,0
   movwf   Cas
   movf   Kolicnik+1,0
   movwf   Cas+1            
;*******************************izračun hitrosti 'desetice'**************************************************               
   
   
   movlw   0x27         ;Deljenec=10.000
   movwf   Deljenec         ;Delitelj=preračunan čas
   movlw   0x10         
   movwf   Deljenec+1
   movf   Cas,0
   clrf   Deljitelj
   movwf   Deljitelj
   movf   Cas+1,0
   clrf   Deljitelj+1
   Movwf   Deljitelj+1
   call   Deli16
   movf   Kolicnik+1,0
   movwf   Desetice         ;rezultat prenesemo v desetice
            

;*****************************Izračun hitrosti 'enice'********************************************************************************
   call   ostanek         ;ostanek množimo z deset
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Enice         ;Rezultat kopiramo v register enice

;*****************************Izračun hitrosti 'desetinke'*************************************
   call   ostanek
   clrf   Deljenec         ;Počistimo registre za deljenje
   clrf   Deljenec+1      ;
   clrf   Deljitelj
   clrf   Deljitelj+1
   movf   Produkt+2,0      ;Nastavimo številke za deljenje
   movwf   Deljenec+1
   movf   Produkt+1,0
   movwf   Deljenec
   movf   Cas,0
   movwf   Deljitelj
   movf   Cas+1,0
   movwf   Deljitelj+1
   call   Deli16         ;Pokličemo deljenje
   movf   Kolicnik+1,0
   movwf   Desetinke         ;Rezultat kopiramo v register enice   
   movlw   b'10010000'
   movwf   INTCON
   retfie

;*****************************Izpis hitrosti*****************************************************         ; Neskoncna zanka
   
   
IZPIS
   
      
XXX   movf   Desetice,0
   call   TABELA
   movwf   PORTB
   movlw   b'00000010'
   movwf   PORTA
   call   pavzamux
   bcf   PORTA,1
   movf   Enice,0
   call   TABELA
   movwf   PORTB
   movlw   b'0001000'
   movwf   PORTA
   call   pavzamux
   clrf   PORTA
   movf   Desetinke,0
   call   TABELA
   movwf   PORTB
   bsf   PORTA,2
   call   pavzamux
   goto   XXX





;***** DELJENJE: Deljenec / Deljitelj = Kolicnik in Ostanek **************

Deli16
   clrf   Kolicnik
   clrf   Kolicnik+1      ; Izbrisemo Kolicnik
   clrf   Ostanek
   clrf   Ostanek+1      ; Izbrisemo ostanek
   movlw   .17
   movwf   Stevec         ; 17 -> Stevec (stevilo ponovitev+1)
Delaj
   decf   Stevec,f      ; Zmanjsamo Stevec
   btfsc   STATUS,Z      ; Ali je stevec ze 0?
   return            ; Da, koncaj deljenje
   rlf   Deljenec+1,f
   rlf   Deljenec,f      ; Pomakni cel Deljenec v levo
   rlf   Ostanek+1,f
   rlf   Ostanek,f      ; Pomakni cel Ostanek v levo s C
   call   Deli         ; Klici pomozni podprogram za Kolicnik
   goto   Delaj         ; Nadaljuj (16x)
   
;********************* POMOZNI PODPROGRAM ZA DELJENJE ********************

Deli
   movf   Deljitelj+1,w      ; Nizji bajt deljitelja -> W
   subwf   Ostanek+1,f      ; Odstej od nizjega bajta ostanka
   movf   Deljitelj,w      ; Visji bajt deljitelja -> W
   btfss   STATUS,C      ; Ali je prislo do prenosa (C=0)?
   incf   Deljitelj,w      ; Da, povecaj deljitelj -> W
   subwf   Ostanek,f      ; Odstej od visjega bajta ostanka
   btfss   STATUS,C      ; Ali je rezultat negativen (C=0)?
   goto   Negativno      ; Da, skoci na Negativno
   bsf   STATUS,C      ; Ne, C=1
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo in LSB=C=1
   return            ; Konec pomoznega podprograma
Negativno
   bcf   STATUS,C      ; C=0
   rlf   Kolicnik+1,f
   rlf   Kolicnik,f      ; Kolicnik pomakni v levo, LSB=C=0
   movf   Deljitelj+1,w
   addwf   Ostanek+1,f
   btfsc   STATUS,C
   incf   Ostanek,f
   movf   Deljitelj,w
   addwf   Ostanek,f      ; 16 bitno sestej Kolicnik in Ostanek, da
               ; dobis spet prvoten ostanek (pozitiven)
   return            ; Konec pomoznega podprograma

;**********************Podprogram za množenje***************************************

mnozenje
   clrf   Produkt+0      ;clear result
   clrf   Produkt+1      ;
   clrf   Produkt+2      ;
   movlw   .8      
   movwf   StevecM   ;bit counter set @ number of bits in multiplier

mul_L1               ;main loop here
   rlf   Produkt+2,f         ;rotate result left (*2)
   rlf   Produkt+1,f         ;
   rlf   Produkt+0,f         ;
   bcf   Produkt+2,0         ;clear LSB of result after rotation
   btfss   Faktor2,7         ;test msb of multipier
   goto   dontAdd         ;if bit is clear then dont add
   movfw      Faktor1+1            ;Add the 16 bits of AA to product
   addwf      Produkt+2,f         ;
   skpnc               ;
   incf   Produkt+1,f         ;
   movfw      Faktor1            ;
   addwf      Produkt+1,f         ;
   skpnc               ;
   incf   Produkt+0,f         ;
dontAdd
   rlf   Faktor2,f         ;rotate multiplier left
   decfsz   StevecM,f      ;chk if finished all bits in multiplier
   goto   mul_L1

   return
;******************************Množenje ostanka z deset iz prejšnjega deljenja*******************************   
ostanek
   movf   Ostanek,0
   movwf   Faktor1
   movf   Ostanek+1,0
   movwf   Faktor1+1
   movlw   0x0a
   movwf   Faktor2
   call   mnozenje
   return   
   
;*********************TABELA********************

TABELA
   
   addwf PCL,f
   retlw b'11110110'   ;0
   retlw b'11000000'   ;1
   retlw b'10111010'   ;2
   retlw b'11101010'   ;3
   retlw b'11001100'   ;4
   retlw b'01101110'   ;5
   retlw b'01111110'   ;6
   retlw b'11000010'   ;7
   retlw b'11111110'   ;8
   retlw b'11101110'   ;9
   retlw b'00001000'   ;-

;****************pavza za mux************************

pavzamux
         ;993 cycles
   movlw   0xC6
   movwf   d1
   movlw   0x01
   movwf   d2
pavzamux_0
   decfsz   d1, f
   goto   $+2
   decfsz   d2, f
   goto   pavzamux_0

         ;3 cycles
   goto   $+1
   nop

         ;4 cycles (including call)
   return

   END
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
dkone
Član
Član



Pridružen-a: Sre 07 Mar 2007 18:53
Prispevkov: 2116
Aktiv.: 9.51
Kraj: Krško

PrispevekObjavljeno: Ned Sep 13, 2009 8:01 pm    Naslov sporočila:   Odgovori s citatom

overflow->prekoračitev vrednosti števca,ki si ga deklariral na začetku.
_________________
Denis
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Ned Sep 13, 2009 8:09 pm    Naslov sporočila:   Odgovori s citatom

Ja torej prekoračitev vrednosti števca TIMER1 mi ne sproži prekinitve. Zakaj? d'oh!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
bungee
Član
Član



Pridružen-a: Pon 07 Mar 2005 18:49
Prispevkov: 1479
Aktiv.: 6.24
Kraj: Ljubljana

PrispevekObjavljeno: Ned Sep 13, 2009 9:41 pm    Naslov sporočila:   Odgovori s citatom

Postavit moraš zastavico za Timer1 interrupt.....

Najprej počistiš TMR1IF, potem pa postaviš še TMR1IE, da omogočiš Timer1 Interrupt.

Interrupt rutino boš moral napisati potem tako, da najprej spraviš W, potem preveriš kateri interrupt se je sprožil in glede na to boš moral izbrat pravo ISR in potem seveda pravilno ven iz interrupta, pa ne pozabit nazaj postavit W.

P.S.: overflow = preliv
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
vitez93
Član
Član



Pridružen-a: Pet 19 Sep 2008 20:00
Prispevkov: 1018
Aktiv.: 5.00
Kraj: Celje- Dobrna

PrispevekObjavljeno: Pon Sep 14, 2009 1:53 pm    Naslov sporočila:   Odgovori s citatom

Še vedno mi ne uspe napravit prekinitve z "prelitjem" timerja.
Koda:
list   p=16f628a
   #include   <p16f628a.inc>
   
   
   
   Cblock   0x20      ; Blok za definicijo konstant
      Deljenec : 2      ; Deljenec (2 bajta)
      Deljitelj : 2      ; Deljitelj (2 bajta)
      Kolicnik : 2      ; Kolicnik (2 bajta)
      Ostanek: 2      ; Ostanek (2 bajta)
      Stevec         ; Stevec za deljenje
      Cas : 2         ; Preracunan cas
      Faktor1 : 2         ; Prvi faktor mnozenja (1 bajt)
      Faktor2         ; Drugi faktor mnozenja (1 bajt)
      Produkt : 3         ; Produkt (3 bajti)
      StevecM         ; Stevec za mnozenje
      Desetice
      Enice
      Desetinke
      d1
      d2
      d3
      d4
      W_copy
   endc         ; Konec bloka konstant
   
   org 0x000
   goto zacni
   org 0x004
   movwf   W_copy
   bcf   INTCON,4         ;onemogočimo prekinitev zaradi senzorja   
   btfsc   INTCON,1
   goto   zacetek         ;če je prekinitev sprožil senzor, pojdi na začetek
   btfsc   PIR1,0
   nop
   retfie
zacni      
   BSF STATUS, RP0
   MOVLW   B'00000001'       ;RB0 - RB6  SO IZHODI ZA LED PRIKAZOVALNIK, RB0 sproži prekinitev (prvi senzor)
   MOVWF   TRISB
   MOVLW   B'00000001'       ;RA1,2,3 SO IZHODI ZA TRANZISTORJE
   MOVWF   TRISA
   movlw   b'10000000'
   movwf   OPTION_REG      ;pull-up off, prekinitev se sproži, ko je RB0 nizek
;**********************************nastavitve timerja in prekinitve**********************************
   bsf   PIE1,0
   BCF STATUS, RP0
   CLRF   PIR1
   movlw   b'00000001'
   MOVWF   T1CON         
   movlw   b'10010000'
   movwf   INTCON         ;omogočimo prekinitve, sproži jih RB0 in overflow timerja
   movlw   0x07
   movwf   CMCON
   movlw   .10
   movwf   Desetice
   movwf   Enice
   movwf   Desetinke
   goto    IZPIS

Podprogrami za računanje



;**********************************Meritev časa***************************************************
   
zacetek
   bcf   INTCON,1
   CLRF   TMR1L
   CLRF   TMR1H
cakaj2   btfsc   PORTA,0         ;ko se prekine 2. senzor se vrednost kopira v registre za deljenje
    goto   cakaj2   
   goto   rac         ;pojdi na računanje



IZPIS
   
      
XXX   movf   Desetice,0
   call   TABELA
   movwf   PORTB
   movlw   b'00000010'
   movwf   PORTA
   call   pavzamux
   bcf   PORTA,1
   movf   Enice,0
   call   TABELA
   movwf   PORTB
   movlw   b'0001000'
   movwf   PORTA
   call   pavzamux
   clrf   PORTA
   movf   Desetinke,0
   call   TABELA
   movwf   PORTB
   bsf   PORTA,2
   call   pavzamux
   goto   XXX
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 18.41

PrispevekObjavljeno: Pon Sep 14, 2009 2:00 pm    Naslov sporočila:   Odgovori s citatom

V prekinitvi shrani tudi STATUS register...
Koda:
MOVWF W_TEMP ;copy W to temp register,
;could be in any bank
SWAPF STATUS,W ;swap status to be saved
;into W
BCF STATUS,RP0 ;change to bank 0
;regardless of current
;bank
MOVWF STATUS_TEMP ;save status to bank 0
;register
:
:(ISR)
:
SWAPF STATUS_TEMP,W;swap STATUS_TEMP
register
;into W, sets bank to
original
;state
MOVWF STATUS ;move W into STATUS
;register
SWAPF W_TEMP,F ;swap W_TEMP
SWAPF W_TEMP,W ;swap W_TEMP into W

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Microchip PIC Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran Prejšnja  1, 2, 3, 4  Naslednja
Stran 2 od 4

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 493 dni


Powered by phpBB © 2001, 2005 phpBB Group