Sida 1 av 7

PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 13:16:39
av Magnus_K
Hej hej,

Sitter här med en PIC18F25K22 och klurar lite på hur jag ska räkna på Timer1 för att få overflowflaggan vid den frekvens jag önskar - ca 100 Hz.
IDE:t är mikroC PRO for PIC.

Tänker jag rätt så här?:
  • - Om systemklockan sätts till 16 MHz men PLL aktiverat blir systemklockan 64 MHz. (Anledningen till den höga frekvensen är pga andra applikationer är i behov av detta)
    - Genom att välja att Timer1 ska följa instruktionsklockan istället för systemklockan så hamnar vi på 12 Mhz, dvs 64 MHz / 4.
    - Med en prescaler med förhållandet 1:2 så är vi nere på 6 MHz.
    - Då jag kan välja om Timer1 ska vara 8 eller 16 bitar så väljer jag 16 bitar. Detta leder till 6 Mhz / 65535 = 91,5 Hz
Är det så här man räknar? Lite osäker på just det där med 8 eller 16 bitars-timer.

Har fler frågor men det är nog bättre att reda ut en sak i taget.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 13:41:09
av sodjan
Det du beskriver verkar vettigt. Om det också
går att göra just så vet jag inte utan att (också)
läsa databladet... :-)

Det är alltså inte så kritiskt vilken tid det blir.
90 eller 100 Hz spelar ingen större roll...

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 13:47:59
av Magnus_K
Låter lovande. Fick inte till urklippen från databladet men det räcker för stunden att jag tänkt rätt med valet av antal bitar på timern.

Just det, frekvensen är inte så kritisk. Den ska bara användas till en knappavstuds (eller vad det kallas), så 90 Hz kommer gå bra.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 16:56:42
av lillahuset
Sist jag kollade var 64/4=16. Men det kanske inte gäller längre. :)

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 17:37:24
av Magnus_K
Hehe, vet inte vilken räknare du använder men ok då, kan likaväl räkna på ditt sätt :)

Skämt åsido, återkommer med lite kod och annat. Som det är nu mäter jag interruptet till 500 kHz men förväntar mig lite över 120 Hz, ditt sätt räknat...

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 19:52:15
av Icecap
Och jag har testat en hel del, just med knappar.

Helt utan debounce räcker det att polla knappsatsen med 10 Hz, det fångar alla. Jag har testat att påverka brytaren så kort som möjligt med det blir alltid fångad vid 10 Hz.

Men jag vill oftast ha en säkerhet mot störningar varför jag gör avläsningar dubbelt så ofta och bara när en ny avläsning är identisk med den förre accepteras avläsningen.

Detta betyder att jag kör med 20 Hz som lägsta frekvens. Sen kan man ju ha andra saker som ska hänga med i den interrupt varför man kan höja frekvensen men det är en annan sak.

100 Hz för att bara kolla knappar är spill av resurser, 25 Hz räcker långt.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 20:10:33
av lillahuset
Avstudsning brukar jag göra med ett "skiftregister" som uppdateras med lagom frekvens. Om värdet (8 bit) är 0x00 sätter jag värdet på variabeln till 0, om värdet är 0xff sätter jag värdet till 1. Fungerar perfekt. Det enda man behöver tänka på är att 8 sample tar längre tid än kontaktstudsarna.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 21:34:47
av Magnus_K
@Icecap:
Ska prova lite olika. Det finns mycket matnyttigt att läsa bland EF:s trådar. Tänkte testa lite olika och i mitt fall kommer inte resurser vara något problem då µC:n kommer vara väldigt överdimensionerad. Å andra sidan är det aldrig fel att tänka effektivt ändå.

@lillahuset:
Det här var också intressant! Du skiftar alltså in portstatusen (på vald ingång) i en byte med lagom intervall. Har du då bara en if (skiftregister == 0xff) { Button_Status = 1; } som körs vid varje skiftning?
Ursäkta den låga nivån men jag vet tyvärr inte bättre. Korvspadet är grumligt.

Mycket bra tips och det som jag tänkte prova först var en variant som Swech tipsade om i en annan tråd där man helt enkelt räknar upp/ner beroende på portstatus. När man nått önskat värde så är knappen tryckt.
Vi får se vart det slutar men jag tyckte verkligen lillahuset:s metod var enkel.

Nåja, inget av detta är värt att prata om så länge man inte kan hantera interrupts.
Nedan är den lilla kodsnutt jag provat med nu och när jag mäter med skopet på RC4:an så kommer pulserna med ganska exakt 30 Hz, vilket inte stämmer alls med uträkningen.

Vet inte hur jag ska göra för att verkligen bekräfta att systemklockan går i 64 MHz...

Kod: Markera allt

void init()
     {
     INTCON.TMR0IE = 1;              // Enable TMR0 overflow interrupt
     PIE1.TMR1IE = 1;                // Enable TMR1 overflow interrupt
     
     RCON.IPEN = 1;                  // Enable interrupt priority
     INTCON.GIE = 1;                 // Enable global and high prio interrupts
     INTCON.PEIE = 1;                // Enable peripheral and low prio interrupts

     INTCON2.TMR0IP = 1;             // Timer0 overflow interrupt has high prio
     IPR1.TMR1IP = 0;                // Timer1 overflow interrupt has low prio
     
     OSCCON = 0b01110010;            // 16 MHz, PLL config bit enable = 64 MHz
     T1CON = 0b00010001;             // Use instruction clock, 1:2 prescaler, 8-bit timer
     
     ANSELC = 0;
     TRISC = 0;
     LATC.B4 = 0;
}

// SKRIV TILL LAT, LÄS PORT

void interrupt(void)
 {
     if (PIR1.TMR1IF)
         {
          LATC.B4 = 1;
          LATC.B4 = 0;

          PIR1.TMR1IF = 0;
           }
}


void main() {

     init();
     
     while(OSCCON.HFIOFS)            // While clock is stable
     {}
}

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 21:56:32
av lillahuset
@lillahuset:
Det här var också intressant! Du skiftar alltså in portstatusen (på vald ingång) i en byte med lagom intervall. Har du då bara en if (skiftregister == 0xff) { Button_Status = 1; } som körs vid varje skiftning?
Ursäkta den låga nivån men jag vet tyvärr inte bättre. Korvspadet är grumligt.
Korvspad som inte är grumligt tyder på dålig korv.
Jo du har fattat rätt, men du ska lägga till en test på 0x00 också. Om det är en blandning av ettor och nollor avvaktar man.

Edit: Ett bra sätt att verifiera en klockfrekvens är att "vifta" med en pinne och se om man får förväntad period. Det har avslöjat många klantigheter i min karriär, både egna och framförallt andras.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 22:00:58
av Magnus_K
Ja just det. Kanon, det ska jag testa! :tumupp:

EDIT: Jag viftar på. Tror jag är det på spåret. Återkommer!

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 22:32:57
av ecenier
Jag har inte förstått varför man behöver kolla portstatus ett förutbestämt antal gånger. Visst, det kan vara bra om man inte har en aning om hur lång knappstudsen kommer att kunna vara, men man kan väl anta att den oftast är under 10ms, och att den inte varierar så mycket på samma knapp från ett knapptryck till ett annat?

Om det är <10ms, och om man har en signal som är normalt låg. Kan man inte göra så här då,
1. ställa in så att man triggar på positiv flank
2. Vid positiv flank, Vänta 10ms
3. Läs portstatus
4. Är den fortfarande är hög -> Knappen intryckt.

Eller missar jag något? Algoritmen ovan har jag använt utan problem på Reed-switch och mikrobrytare.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 19 september 2015, 23:02:32
av lillahuset
Flanker är ofta förrädiska. Ofta bättre att titta på nivåer.

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 20 september 2015, 01:00:10
av ecenier
Men på vilket sätt är flankerna förrädiska?

Tänk att man har en ingång med pull-down-motstånd som du ska lyssna på efter en knapptryckning. Mellan ingången och Vdd har man en knapp med 2-5ms knappstuds.
Varför skulle min algoritm ovan inte fungera? Jag menar, kommer det en flank, så sker ett interrupt. Om signalen ff är hög efter 10ms så är det ju en knapptryckning.
Eller menar du att t.ex. en PIC kan missa en flank? eller kan en flank detekteras utan att knappen trycks ner även med en pull-down?

Eftersom jag inte sett så många exempel på min alogritm på övriga nätet så gissar jag att den inte är helt vattentät :), men jag vill gärna veta varför.
En dålig sak som jag kan komma på direkt är att det är ganska fult med en delay inne i en interruptrutin. Men om man tittar på funktionen så borde den väl var OK?

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 20 september 2015, 01:18:20
av Magnus_K
Har funderat lite ecenier och frågan är om inte detta också är en väldigt bra metod.
Det man skulle kunna göra är ju att faktiskt nyttja Interrupt on change på den porten och går den hög så använder man inte en delay utan istället använder sig av antingen en redan rullande timer eller en dedikerad "debounce"-timer och justerar dess intervall på 10ms, eller vad man vill ha.
På så sätt borde processorn kunna jobba fritt medans väntetiden tickar på.
Nej jag vet inte bättre än att lyssna på er men oavsett, avstudsningen ser jag inte som ett direkt stort problem. Just nu är det att få systemklockan att snurra som jag vill.

Vad jag nyss upptäckte var att oavsett om jag aktiverade/deaktiverade 4 x PLL så sker interruptet ändå med ~30 Hz.
Om jag, med detta, förutsätter att 4 x PLL -funktionen inte fungerar så snurrar bara klockan med 16 MHz och detta gör att allt stämmer.
Dvs:
- Systemklocka 16 MHz
- Instruktionsklocka 4 MHz
- 1:2 prescaler på Timer1 = 2 MHz
- 16 bitars Timer1 = 2'000'000 / 65535 = 30,5 Hz

Jahopp, nu blir det till att reda ut vart det går fel med 4 x PLL

Re: PIC18F25K22 - Timer, Nested interrupts och annat

Postat: 20 september 2015, 01:34:20
av TomasL
Jahopp, nu blir det till att reda ut vart det går fel med 4 x PLL
Hur gör du för att slå på PLLen?