Priority bits van een Pic

Hallo allemaal,

Ik zit al een tijdje met het volgend probleem te kijken en ik kom er maar niet uit ...
Ik wil graag 4 timers/counters gebruiken en 1 keer de portb interrupt.
Omdat de poortb ingang gebruikt wordt voor een encoder systeem (trigger wheel) is het belangrijk dat er nooit een puls wordt overgeslagen.
Dus wanneer ik de priority bit van poort-b op 1 zet,verwacht ik dat wanneer een timer-overflow bezig is, de interrupt van poort-b direct erna volgt...
Ik heb dit allemaal getest met de volgende code:

code:


include 18f45k80
pragma target clock 64_000_000      -- oscillator frequency
pragma target OSC       INTOSC_NOCLKOUT                      -- crystal or resonator
pragma target PLLEN    enabled
pragma target WDT      DISABLED                  -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target MCLR     internal                  -- external reset
--

OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled
pragma target SOSCSEL dig
--
--



enable_digital_io()                       -- all pins digital
include delay



const serial_hw2_baudrate = 19200
include serial_hardware2
serial_hw2_iniT()

const serial_hw_baudrate = 19200
include serial_hardware
serial_hw_init()


include print                       -- output library


t0con = 0b_1000_0000
t1con = 0b_0111_0001
t3con = 0b_0111_1101
t2con = 0b_0000_1000
t4con = 0b_0000_0111


intcon  = 0b_1110_0000
intcon2 = 0b_1000_0100
intcon3 = 0b_1001_0000
rcon_IPEN = 1
intcon2_INTEDG2 = 1
ipr1_TMR1IP = 0
ipr2_TMR3IP = 0
intcon2_TMR0IP = 0
intcon3_int2ip = 1


pie2_tmr3ie = 1
intcon_tmr0ie = 1
intcon3_int2ie = 1
pie1_tmr1ie = 1
pie1_tmr2ie = 0
pie4_tmr4ie =1




procedure INT5 is
pragma interrupt
if pir1_tmr1if == 1 then
pir1_tmr1if = 0
DELAY_1S(2)
serial_hw2_write("1")
end if
end procedure


procedure INT4 is
pragma interrupt
if intcon_tmr0if == 1 then
intcon_tmr0if = 0
DELAY_1S(2)
serial_hw2_write("2")
end if
end procedure


procedure INT3 is
pragma interrupt
if pir2_tmr3if == 1 then
pir2_tmr3if = 0
DELAY_1S(2)
serial_hw2_write("3")
end if
end procedure


procedure INT2 is
pragma interrupt
if pir4_Tmr4IF == 1  then
pir4_tmr4if = 0
DELAY_1S(2)
serial_hw2_write("4")
 end if
end procedure



procedure INT1 is
pragma interrupt
if intcon3_int2if == 1     then
intcon3_int2if = 0
DELAY_1S(2)
serial_hw2_write("5")
end if
end procedure






FOREVER LOOP


END LOOP

Dus wanneer ik mijn poort-b trigger met een drukknop zou er een 5 moeten volgen,maar er volgen eerst alle andere nummers en dan pas een 5....
Ik gebruikt Jal V2.4 als compiler.
Ik heb al van alles geprobeerd,maar niets geeft volle prioriteit aan poort b, kan iemand me vertellen wat ik fout doe ?

Arco

Special Member

Wat is dat voor brakke code? Delays in een interrupt is absoluut een no-no... (nooit doen!)
En waarom heb je in hemelsnaam 5 timers nodig??? (het meeste wat ik een een complex programma ooit heb nodig gehad zijn 3 timers...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

De delays zijn natuurlijk bedoelt om te kunnen zien welke interrupt als eerste aan de beurt is... Ik gebruik de delays niet in een echt programma.
Ik heb 5 timers nodig voor pwm uitgangen en om een overflow te genereren als het trigger wheel bv. 354 graden behaald heeft.

Arco

Special Member

Zet dan een led aan, maar geen delay. Dat geeft allerlei ongewenste neveneffecten. Zo kun je geen voorspellingen doen wat er werkelijk gebeurt.
En waarom een eigen interrupt voor die port pin? Check die in een van de pwm interrupts, dat zal toch snel genoeg zijn?

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Dat is geen optie de pulsen komen om de 20us binnen.een led die tegen die frequency loopt kan ik niet volgen en een timer loopt te ver achter

Een interrupt elke 20 microseconden en 5 software PWM's bijhouden, dat wordt krap op 20 MHz. De PIC18 heeft toch een paar hardware PWM kanalen?

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com

Maakt de hardware pwm geen gebruik van de timers? Daarnaast heb ik nog steeds min. 2timers nodig. Maar kan iemand me uitleggen hoe de prioriteit precies werkt van een Pic?

Arco

Special Member

Bij de 18F serie zijn er twee interruptnivo's waar je voor kunt kiezen: hoge of lage prioriteit. Je hebt inderdaad (een) timer(s) nodig.
(bij de 24f serie heb je veel meer interruptnivo's, en ook gescheiden. Tevens hebben de pwm's daar een eigen timer, onafhankelijk van de GP timers)
Als de PWM's enige verhouding tot elkaar hebben, kun je alles wellicht ook in minder interrupts afhandelen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Minder timers is misschien wel mogelijk,maar dan zit ik nog steeds met mijn prioriteit van poortb .
Waarom werkt het niet zoals ik verwacht ? is er misschien iets in Jal wat de prioriteit afneemt ?
De poortb functie heeft andere flag-bits als de timer interrupts, heeft het hier iets mee te maken ?

Hoe weet JAL dat jouw poort B interrupt de routine INT1 moet gebruiken? Dus waar bepaal jij dat welke interrupt welke routine aanspreekt? Dat is me niet duidelijk.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Arco

Special Member

Ik begrij[p ook niet hoe je aan 5 interrupt procedures komt, de pic heeft er maar 2 maximaal...
Ik zie inderdaad ook niet dat je ergens de priority levels instelt (IPRx regsters)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

De "int1, int2, int3,..." ) zijn enkel procedure namen (die ik zelf verzonnen heb). De "intcon3_int2if" is de interrupt van poortb.

Arco

Special Member

Nogmaals, hoe weet de pic welke irq routines wanneer te gebruiken? (als het goed is worden er 3 nooit gebruikt)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op 26 maart 2017 12:34:14 schreef Arco:
Ik begrij[p ook niet hoe je aan 5 interrupt procedures komt, de pic heeft er maar 2 maximaal...
Ik zie inderdaad ook niet dat je ergens de priority levels instelt (IPRx regsters)

In het begin van het programma staat intcon3_int2ip = 1, deze geeft aan dat poortb prioritwit krijgt
Rcon_ipen is de priority enable bit

Wat bedoel je precies met"de pic heeft maar 2 interrupt procedures"?

Arco

Special Member

De 18Fxxx pics hebben zoals reeds gezegd 2 interrupt routines als je priority instelt (anders maar 1).
In de IPRx registers geef je aan naar welke van de 2 routines een bepaald interrupt toe gaat.
In de interruptroutine zelf test je dan de interruptflags, om te zien waar het interrupt door veroorzaakt is.

[Bericht gewijzigd door Arco op zondag 26 maart 2017 13:00:45 (11%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Ok, ik heb wat ge-googled en ik lees op verschillende websites dat Jal geen interrupt priority ondersteund.

Dan zou je aan Wouter van Ooijen misschien wat tips kunnen vragen. Hij is hier forumlid, onder zijn echte naam.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com

Ik heb het probleem opgelost door in iedere timer-interrupt eerst te vragen of de flag-bit van poort-b "1" is.
Als die 1 is zal hij eerst de procedure van poort-b moeten uitvoeren.

code:




procedure timeroverflow is
pragma interrupt
if pir1_tmr1if == 1 then        //--als timer over loopt
ifintcon3_int2if == 1 then      //-- eerst kijken voor poort-b interrupt
poort-b                         //-- voer procedure uit van poort-b
end if                          //---gaat na de procedure weer verder 
pir1_tmr1if = 0
end if
--
end procedure


procedure poort-b is
pragma interrupt
if intcon3_int2if == 1     then
intcon3_int2if = 0
end if
end procedure





Niet ideaal, maar het is een oplossing...

Maar nu heb je geen prioriteit (de poort B interrupt kan de timer interrupts niet onderbreken), en poort B wordt ook pas bekeken nadat er een timer interrupt is geweest. Dus alles behalve ideaal.

Ik ben niet erg bekend met de syntax van JAL, maar dit is korter, en geeft in ieder geval een snellere respons op de poort B pin:

code:


procedure all_interrupts is
pragma interrupt
ifintcon3_int2if == 1 then      //-- eerst kijken voor poort-b interrupt
poort-b                         //-- voer procedure uit van poort-b
intcon3_int2if = 0
end if                          //---gaat na de procedure weer verder 
if pir1_tmr1if == 1 then        //--als timer over loopt
pir1_tmr1if = 0
end if
--
end procedure


procedure poort-b is
> poort B interrupt afhandelen
end procedure
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com