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 

LPC2378 in prekinitve
Pojdi na stran 1, 2  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Tor Mar 04, 2008 10:25 pm    Naslov sporočila:  LPC2378 in prekinitve Odgovori s citatom

Živjo

Želel sem narediti timer, ki bi po določenem času izvedel prekinitveno rutino. Delam z KEIL uVision (RealView compiler).

Program ni nič drugega kot LED chaser. Vmes beremo tipke in spreminjamo hitrost utripanja/premikanja diod. Če imam enostavno while zanko v delay funkciji, potem v tem času ne morem brati tipk. Zato sem se odločil, da zadevo rešim s prekinitvijo.
Program sem preizkusil na Borisovi razvojni plošči in LPC2378. Program pride do main, saj se LED prižgejo. Prižgejo se pa samo tiste, ki so nastavljene že na začetku programa (definicija spremenljivk). V prekinitveni rutini, bi se morale aktivne LED spremeniti, pa se ne. Torej program do te rutine sploh ne pride.

Poizkusil tudi sem tudi z debugerjem. Na zacetku vse lepo in prav - pridemo do main funkcije, klicemo ostale funkcije, ko pa pride do prekinitve se mi program "zacikla" v LPC2300.s datoteki. Prebral sem si podobne teme na forumu, vendar nisem našel rešitve.
Ko pride do prekinitve, mi program skoči na vrstico
Koda:
LDR     PC, [PC, #-0x0FF0]

Od tam gre na začetek vektorjev, torej na
Koda:
Vectors         LDR     PC, Reset_Addr

In začne se ponoven startup (ura itd.). Tako da do prekinitvene rutine sploh ne pride! Mislim si, da bi moral popraviti LPC2300.s datoteko, pa ne vem kako. Ob prekinitvi gre na pravo lokacijo v .s datoteki, vendar pa tam ne dobi pravega naslova! Če namesto naslova dam:
Koda:
LDR     PC, IRQ_Addr

pa se ustavi v zanki
Koda:
IRQ_Handler     B       IRQ_Handler



Spodaj so pripeti deli kode LPC2300.s
Koda:

;  Exception Vectors
;  Mapped to Address 0.
;  Absolute addressing mode must be used.
;  Dummy Handlers are implemented as infinite loops which can be modified.

Vectors         LDR     PC, Reset_Addr         
                LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                NOP                            ; Reserved Vector
;               LDR     PC, IRQ_Addr
                LDR     PC, [PC, #-0x0FF0]     ; Vector from VicVectAddr
                LDR     PC, FIQ_Addr

Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                      DCD     0                      ; Reserved Address
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr         DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
IRQ_Handler     B       IRQ_Handler
FIQ_Handler      B       FIQ_Handler


; Reset Handler

                EXPORT  Reset_Handler
Reset_Handler



Moj program:
Koda:
#include <LPC23xx.H>   
void Timer0_ISR(void) __irq;   // Dolocimo naslov prekinitvene rutine

int main(void)

   /* Inicializacija za prekinitve */
   VICIntEnable    |= (1<<4);                         
   VICIntSelect      = 0;                               
   VICVectAddr0    = (unsigned)Timer0_ISR;    // naslov kamor gremo ko pride do prekinitve   
   VICVectPriority0 = 0;             

   /* Inicializacija casovnika TIMER0 */
   T0TCR   = 0;         
   T0PR     = 12000;          // stejemo milisekunde; preipheral clock = 12MHz
   T0TC     = 0;         
   T0MCR  = 0x00000003;    // Vklopimo Interrupt za TIMER0; pri prekinitvi resetiramo TC (T0TC=0)
   T0MR0   = hitrost;         // Do prekinitve pride, ko je TC enak MR0, torej ko mine dolocen cas (hitrost)
   T0TCR    = 1;         

   while(1)       
   {
      FIO2SET = LED;             // vrednost LED postavimo na izhodone pine - prizgemo diode
      hitrost = tipke(hitrost);   // klicemo funkcijo tipke in spreminjamo hitrost
      inc = hitrost/2;              // na vsak pritisk tipke se hitrost za polovico poveca ali zmanjsa
   }   
}


 /* Prekinitven rutina zaradi TIMER0         */
void Timer0_ISR(void) __irq         
 {                                           
   T0TCR   = 0;            // ustavimo timer   
   T0IR   |= (1<<0);     // resetiramo match 0 prekinitev
     
   /* Izvedemo operacije za premikanje/utripanje LED diod */

   /* Preden zapustimo rutino */
   T0MR0      = hitrost;         // "hitrost" lahko spreminjamo in morebiti spremenjeno vrednost zapisemo v match register
   T0TCR       = 1;            // vklopimo timer
   VICVectAddr = 0x00000000;      //koncamo prekinitev
 }

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
alessio
Član
Član



Pridružen-a: Pon 04 Dec 2006 8:39
Prispevkov: 363
Aktiv.: 1.60
Kraj: Ljubljana

PrispevekObjavljeno: Tor Mar 04, 2008 11:02 pm    Naslov sporočila:   Odgovori s citatom

Najprej vrstico
Koda:
                LDR     PC, [PC, #-0x0FF0]     ; Vector from VicVectAddr

zamenjaj z
Koda:
                LDR     PC, [PC, #-0x0120]     ; Vector from VicVectAddr


LPC23xx ima namreč drugačen VIC kot LPC21xx in LPC22xx.

Aleš
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Tor Mar 04, 2008 11:23 pm    Naslov sporočila:   Odgovori s citatom

Hvala za hiter odgovor. Sem pozabil napisat - v originalu je bil 0x0120 Ko pa sem začel eksperimentirat, sem med drugim spremenil tudi ta naslov na 0x0FF0. Zadeva še vedno dela enako oz. ne dela....
_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 06, 2008 12:14 am    Naslov sporočila:   Odgovori s citatom

No, nekaj se premika....

Če v zgornjo vrstico namesto 0x0FF0 ali 0x0120 zapišem 0x0F00, potem prekinitev nekako dela. Zadeva ni stabilna in se, če uporabljam tipke, zopet nekje zacikla. Pri vsem skupaj pa je še najbolj čudno to, da moram uporabit nek določen VICVectAddr. Npr. VICVectAddr0 ne dela, medtem ko VICVectAddr8 "dela".

Ima kdo kako idejo?

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
RokO
Član
Član



Pridružen-a: Čet 23 Nov 2006 11:14
Prispevkov: 120
Aktiv.: 0.53
Kraj: Kranj

PrispevekObjavljeno: Čet Mar 06, 2008 11:34 am    Naslov sporočila:   Odgovori s citatom

Na ZS ti bom poslal kratek uVision program, ki sem ga na hitro spisal. V njem ti preizkušeno deluje Timer0 prekinitev in sicer na vsake 3 sekunde. Vse skupaj teče na LPC2368 in plati MCB2300.
Upam, da ti bo kaj pomagalo...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
smartgsm
Član
Član



Pridružen-a: Sob 10 Apr 2004 11:54
Prispevkov: 364
Aktiv.: 1.53

PrispevekObjavljeno: Čet Mar 06, 2008 5:26 pm    Naslov sporočila:   Odgovori s citatom

RokO je napisal/a:
Na ZS ti bom poslal kratek uVision program, ki sem ga na hitro spisal. V njem ti preizkušeno deluje Timer0 prekinitev in sicer na vsake 3 sekunde. Vse skupaj teče na LPC2368 in plati MCB2300.
Upam, da ti bo kaj pomagalo...


Lahko prilozeš primer?
Jaz imam podoben problem.
S to razliko da jaz dinamično prilagajam hitrost proženja IRQ od cca 100 hz do 50 KHZ. Pri določeni frekvenci enostavno IRQ procedura pade ven in se ne proži. Main procedura pa deluje normalno.

lp
Grega
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 06, 2008 5:45 pm    Naslov sporočila:   Odgovori s citatom

Hvala za pomoč. Mislim da mi je stvar zdaj bolj jasna Confused Gre pa samo za pomankljivo znanje VIC-a (Vectored Interrupt Controller). Nekako sem imel pomešane pojme, kako zadeva deluje. Zdaj mislim, da mi je bolj jasno...

Mislil sem, da za prekinititev samo določiš source (VICIntSelect - posamezen bit vklopi/izklopi interrupt za timerje, uart itd.). Temu pa nato sledi še zapis naslova ISR v VICVectAddr0 do VICVectAddr32. Nekako sem si predstavljal da naslov ISR pač vpisuješ po vrstnem redu v VICVectAddr - torej za eno prekinitev zapišeš v VICVectAddr0, za drugo v VICVectAddr1 itd.

No, stvari ni tako enostavna, hehe Stvar je še bolj enostavna...
Hočeš prekinitev zaradi TIMER0? Pogledaš kateri bit v VICVectSelect moraš postaviti na 1 (v mojem primeru je to bit 4). Nato pa naslov prekinitvene rutine vpišeš pod isto zaporedno mesto v VICVectAddr, torej v VICVectAddr4 Whistle

Kar se tiče pa startup datoteke - 0x0120 je prava vrednost!

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 06, 2008 5:49 pm    Naslov sporočila:   Odgovori s citatom

Zdaj imam pa drugačen problem....
Kot sem rekel gre za LED chaser in programu lahko preko tipk spreminjamo hitrost "premikanja" LEDic.
Prekinitev je narejena tako, da mi šteje milisekunde in v prekinitveni rutini se spreminja samo nek "števec".
V glavnem programu opazujemo ta števec in ko doseže določeno vrednost "čas", se LEDice spremenijo oz. premaknejo. Prav tako se "števec"zopet postavi na 0. Vmes pa tudi opazujemo tipke, s katerimi spreminjamo vrednost "čas".

Če program prevedem in preizkusim na krmilniku mi zadeva dela! Problem je, ko začnem pritiskati tipke, saj mi LEDice zmrznejo!! To je popolnoma naključno - enkrat lahko na tipke pritisnem 1x pa zmrzne, drugič pa 100x...

Ima mogoče za to kdo kako idejo?

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 06, 2008 8:39 pm    Naslov sporočila:   Odgovori s citatom

Sem našel napako tudi za drugi problem - napaka v if stavku. Primerjal sem števec in čas in sicer "števec == čas".
Ko sem čas povečeval ni bilo problema. Če pa sem čas zmanjševal, je bil lahko števec v tistem trenutku že večji od vrednosti čas. Zato se je zadeva ustavila. Ni zmrznila, ampak je štela milisekunde naprej. In ker gre za 32bitni števec, bi moral čakati 2^32 milisekund, da bi števec prišel do konca in zopet začel z nule....

Popravek na "števec >= čas" je popravil program.

Se zahvaljujem vsem za pomoč in opravičujem za temo, ki sem jo očitno odprl zaradi malomarnosti...

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
RokO
Član
Član



Pridružen-a: Čet 23 Nov 2006 11:14
Prispevkov: 120
Aktiv.: 0.53
Kraj: Kranj

PrispevekObjavljeno: Pet Mar 07, 2008 12:12 am    Naslov sporočila:   Odgovori s citatom

Me veseli, da sem pomagal...drugače pa ne bi rekel, da je tema brezvezna. Ko sem se sam začel ukvarjati s programiranjem so mi take "brezvezne teme" še najbolj pomagale... Ko imaš enkrat osnovne pojme razčiščene...potem gre samo še naprej...Smile

PS.

Še primer za ostale uporabnike, ki so želijo stvar ogledati:



MSCB3200.zip
 Opis:

Download
 Ime datoteke:  MSCB3200.zip
 Velikost datoteke:  416.8 KB
 Downloadano:  20 krat

Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
SimonS
Član
Član



Pridružen-a: Čet 01 Jul 2004 11:18
Prispevkov: 4770
Aktiv.: 20.08
Kraj: Kobarid

PrispevekObjavljeno: Čet Mar 20, 2008 12:39 am    Naslov sporočila:   Odgovori s citatom

Pozdrav
Nastavil sem si timer, ki mi vsake 3 minute generira prekinitev.
Hec pa je v tem. Prvic mi res na 3. minute generira. Drugic in vsakik naslednjic pa mi gre v prekinitev na 4. minute. To mi nikakor ni jasno. Primir moje kode
Koda:
   T0PR    = 900000000;      // 1 minuta
     T0MR0   = 3;           // Generiraj na 3. minute
     T0MCR   = 0x00000003;       // On match, raise interrupt and reset T0TC 
     T0TCR    = 0x00000002;       // Reset counter and prescaler
     T0CTCR  &= 0xfffffffc;      // Timer mode
     T0TCR    = 0x00000001;       // Enable timer

prekinitvena rutina pa izgleda tako:
Koda:
   if(VICIRQStatus&0x00000010)         //TIMER 0
   {
      IOSET0 = led_n;
      T0IR = 0x00000001;             //resetiramo prekinitev timer 0

   }

_________________
Lep dan
Simon
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 20, 2008 1:21 am    Naslov sporočila:   Odgovori s citatom

Kako imaš inicializirano prekinitev (registri VICIntEnable, VICIntSelect, VICVectAddr0 itd.)?
Tvoj zapis prekinitvene rutine mi ni znan. "if" stavka za prekinitveno rutino še nisem videl. Je pa res da se s programiranjem ne ukvarjam tako dolgo Cool

Bi poizkusil z (meni) bolj znano obliko:


Koda:
void Timer0_ISR(void) __irq;   // Dolocimo naslov prekinitvene rutine

/* Prekinitven rutina zaradi TIMER0         */
void Timer0_ISR(void) __irq         
 {                                           
   /* Program, ki se naj izvede ob prekinitvi */
   VICVectAddr = 0x00000000;      //koncamo prekinitev
 }

int main(void)
{  /* Inicializacija za prekinitve */
   VICIntEnable    |= (1<<4);                         
   VICIntSelect      = 0;                               
   VICVectAddr0    = (unsigned)Timer0_ISR;    // naslov kamor gremo ko pride do prekinitve   
   VICVectPriority0 = 0;             

   while(1)       
   {
      /* program */
   }   
}

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
RokO
Član
Član



Pridružen-a: Čet 23 Nov 2006 11:14
Prispevkov: 120
Aktiv.: 0.53
Kraj: Kranj

PrispevekObjavljeno: Čet Mar 20, 2008 1:31 am    Naslov sporočila:   Odgovori s citatom

Ne primi me za besedo, vendar mi nekje zadaj odzvanja, da mora biti register MR nastevljen na način (n-1).

Tako, da probaj z
T0MR0 = 2; // Generiraj na 3. minute

V tem premeru bi moralo delati, ker se una "ničla" tudi upošteva...takrat gre pač oni števec na nič ali kako je že...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
SimonS
Član
Član



Pridružen-a: Čet 01 Jul 2004 11:18
Prispevkov: 4770
Aktiv.: 20.08
Kraj: Kobarid

PrispevekObjavljeno: Čet Mar 20, 2008 12:17 pm    Naslov sporočila:   Odgovori s citatom

Olaf
Prekinitvena rutina deluje OK. Pac ne uporabljam FIQ.
RokO
Ja to ze razumem. Samo ce napravim tako, potem mi bo prvo prekinitev se vedno napravilo krajso kot ostale, kar pa ni prav....

_________________
Lep dan
Simon
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Olaf
Član
Član



Pridružen-a: Tor 14 Nov 2006 20:09
Prispevkov: 127
Aktiv.: 0.56
Kraj: Ljubljana

PrispevekObjavljeno: Čet Mar 20, 2008 1:51 pm    Naslov sporočila:   Odgovori s citatom

Sem se malo igral - napaka je v resetiranju števca TC. Čeprav je v MCR zapisano naj ob prekinitvi resetira tudi TC (T0MCR = 0x00000003), se to očitno zgodi šele ob naslednjem povečanju TC-ja. Zakaj je tako pa ne vem...
Če sem v prekinitveni rutini "na roke" resetiral counter (torej T0TC = 0), je zadeva delala tako kot je treba prvi in vsak naslednji krog!

Pri tem je match register je štel od 1 naprej. Torej če imaš T0MR0 = 3, je štel 1-2-3 in ne 0-1-2-3. Vsaj tako je se je izkazalo na praktičnem primeru.

_________________
To mi deli!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2  Naslednja
Stran 1 od 2

 
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: 7 dni


Powered by phpBB © 2001, 2005 phpBB Group