Använda ADC som timer?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Använda ADC som timer?

Inlägg av Korken »

Sitter i leran och har märkt att jag behöver en timer till, då 2 st redan är upptagna och har inga fler.
De som då slog mig är om jag kan använda ADCns ISR som timer? Då jag har 128 i prescaler så borde frekvensen blir FCPU/128.
Eller är det något mer som påverkar frekvensen på ADCns ISR? Vet att beräkna värdet tar 13.5 cykler men de borde få plats pga prescalern.

Samt koden som ska in i ADCn är mycket liten, en variabel som behöver räknas samt en if-sats som tillåter en grej att köras i main-programmet, så det borde få plats.
Och det jag mer gör i ADCn är att ta ut ADC värden, så inget tungt där sen förut.

Kan detta fungera? :humm:
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Använda ADC som timer?

Inlägg av Swech »

Det är en AVR? Vilken modell?
Vad använder du de andra timrarna till då som gör att de är helt upptagna?

Frekvensen blir FCPU/(128*13.5) det går 13.5 cykler oavsett prescalerns värde.

Swech
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: Använda ADC som timer?

Inlägg av dangraf »

Du skulle annars kunna skriva om din kod lite och använda en timer till flera olika grejjer. Såg i din tidigare tråd att du lagt togglingen inne i timer-interruptet. Det finns ett annat alternativ ifall det inte är så tidskritiska grejjer som t.ex att blinka med en lysdiod.

Timer drivrutin: (fattas lite delar som init osv men denna är skriven mest för att du ska förstå prinsipen.

Kod: Markera allt

#define TIMER_INST_PER_MILLISEC		             BOARD_FOSC/(1000*4)
#define U16MS_TO_TICK(time)			(uint16)((TIMER_INST_PER_MILLISEC*time)/(256ull))

uint16 timerRead16(void)
{
                          uint16 tick = 0;
                          INTCONbits.TMR0IE = 0;		// Disable interrupt
	
                          tick = TMR0H;
                          tick <<=8;
                          tick |= TMR0L;

		
                          INTCONbits.TMR0IE = 1;
                          return tick;
}

uint16 timerGetDiff16( uint16 timestamp )
{
	uint16 diff;
	diff = timerRead16();
	diff = diff - timestamp;
	
	return diff;
}
void timerInit(void)
{
      TMR0H = 0;
      TMR0L = 0;

    INTCONbits.TMR0IE = 0;		// Disable interrupt

    // Timer0 on, 16-bit, internal timer, 1:256 prescalar
    T0CON = 0x86;
}
För att använda ovanstående kod på ett bra sätt kan du skriva:

Kod: Markera allt

void blinkLed(void)
{
   static uint16 myTimestamp;

  // LEDPIN är en bitmask för din diod

  if( PORTB & LEDPIN)
  {
       // lysdioden är tänd 
        if( timerGetDiff16( myTimestamp) > U16MS_TO_TICK( 100 )
        {
            // låt den vara tänd i 100 ms därefter släck
            myTimestamp = timerRead16();
            PORTB &= ~LEDPIN;
        }
  }else
  {
        if( timerGetDiff16( myTimestamp) > U16MS_TO_TICK( 20 )
        {
            // låt den vara släckt 20 ms därefter tänd
            myTimestamp = timerRead16();
            PORTB |= LEDPIN;
        }
  }

}
På detta sättet får möjlighet att hålla koll på tiden i flera små applikationer samtidigt. Nackdelen är att du får inte samma exakthet i tidmätningen jämfört med att använda en timer för varje grejj. Detta pga att det finns risk för att en annan applikation gör något som tar lite längre tid, t.ex räknar ut ett värde på en vektor, läser ett SD-kort etc. Men i ditt fall verkar det hur lungt som helst.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Använda ADC som timer?

Inlägg av Korken »

Tackar för tipset!

Det som gör dom upptagna är att ena timer kör som hw PWM och den andra har jag just nu "blink-led" rutinen.
Jag kan trycka in det i den timern, men jag funderade om det gick att använda ADCn då den kör redan i en väldigt bra frekvens för de jag vill köra i main loopen sen, vilket ger mig mindre jobb än att bygga om min ena timer. :)

µC: Just nu för test tiny45, men ska sedan petas in i en tiny24. (hade ingen tiny24 i DIP-kapsel)
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Använda ADC som timer?

Inlägg av jesse »

det ska väl gå bra, du läser av flaggan (alternativt låter ett interrupt sätta en flagga), läser av ADC, och sedan gör du det du ska göra.
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: Använda ADC som timer?

Inlägg av dangraf »

Risken med att använda ADCn jämfört med ett vanligt timer-interrupt är att du startar din timer varje gång du hoppar in i interruptet vilket kan medföra att du får en drift i tid beroende på vart du befinner dig i din kod. låt säga att du får ett ADC interrupt samtidigt(eller lite efter) som du får ett timer interrupt. Då kommer koden köra i timer interruptet och kan inte hoppa till ADC interruptet direkt (antar att du inte ADCn som högsta prioritet).

Om man jämför detta med t.ex ett timer interrupt så gör det inget ifall det blir en liten fördröjning eftersom timern fortsätter att snurra i bakgrunden och behöver inte startas varje gång du hoppar in i interruptet.

Lycka till!
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Använda ADC som timer?

Inlägg av Korken »

Precis, har tänkt på det också.
Som tur är så är inte det jag gör så tidskritiskt, mer så att det blir ungefär lika lång tid (och att det tar tid) mellan varje gång.
För det jag bestämmer är hur ofta jag uppdaterar PWMens Dutycycle. För jag styr en Buck-converter med PWMen och vill inte stiga/sjuka för fort så kondensatorerna inte hinner med.
För nu när jag testar utan att kontrollera hur snabbt de får stiga/sjuka utan bara kontrollerar vart jag vill hamna, så hamnar systemet i svängning, därför jag ändrar lite. :)
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Använda ADC som timer?

Inlägg av bearing »

Jag har för mig att man kan köra ADC i "free running mode", vilket borde göra att ADC-interruptet kommer i jämn takt likt en timer.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Använda ADC som timer?

Inlägg av Korken »

Japp, det är rätt de!
Jag gör just de, för då ska man få frekvensen FCPU/prescaler Hz.

Jag har testat detta lite nu och jag måste säga att det fungerar över förväntningar!
Tog lite tid och tester att hitta hur lång paus jag behövde, men nu fungerar det som det ska.
Från svängningar på ca 3V till mindre än 0.1V, de är godkänt! :D
Skriv svar