Se io ad esempio dovessi far accendere e spegnere un led ogni 250 mS come potrei gestire la situazione?? Ogni volta che si verifica l'interrupt dovrei mettermi ad incrementare un contatore fino ad arrivare a 4880 circa (che equivalgono a circa 250 mS)??
Interrupt da Timer0
Moderatore:
Paolino
16 messaggi
• Pagina 1 di 2 • 1, 2
0
voti
Ciao a tutti ragazzi. Nei miei pochi progettini che ho realizzato finora con i microcontrollori non ho mai utilizzato i timer. Credo sia arrivato il momento di imparare però mi sono trovato di fronte ad un problemino...se devo generare un interrupt ogni 250 mS utilizzando un quarzo da 20 MHz, come dovrei fare?? Eseguendo i classici calcoli ottengo che per eseguire ogni istruzione il PIC impega 0,2 uS e quindi per ottenere l'overflow con conseguente interrupt ci vogliono 51,2 uS. Fin qui tutto corretto?
Se io ad esempio dovessi far accendere e spegnere un led ogni 250 mS come potrei gestire la situazione?? Ogni volta che si verifica l'interrupt dovrei mettermi ad incrementare un contatore fino ad arrivare a 4880 circa (che equivalgono a circa 250 mS)??
Se io ad esempio dovessi far accendere e spegnere un led ogni 250 mS come potrei gestire la situazione?? Ogni volta che si verifica l'interrupt dovrei mettermi ad incrementare un contatore fino ad arrivare a 4880 circa (che equivalgono a circa 250 mS)??
0
voti
dany192 ha scritto:Fin qui tutto corretto?![]()
Ehm, si, cioè andrebbe bene SE:
-SE stai utilizzando un determinato microcontrollore che incrementa il timer ogni 4 cicli di clock
-SE stai utilizzando un timer ad 8bit
-SE non utilizzi il prescaler e lo lasci a 1:1
-SE ad ogni routine di interrupt resetti il valore del timer a zero.
Sono tutti dettagli che non hai specificato, anche se penso che li hai semplicemente ignorati. Potrei pensare ad un PIC 16F ed all'utilizzo del Timer0 ad 8bit... ma meglio se ci dici tutto quanto
dany192 ha scritto:Se io ad esempio dovessi far accendere e spegnere un led ogni 250 mS come potrei gestire la situazione?? Ogni volta che si verifica l'interrupt dovrei mettermi ad incrementare un contatore fino ad arrivare a 4880 circa (che equivalgono a circa 250 mS)??
Se tutte le cose che ho scritto sopra sono vere, allora si, potresti fare una cosa del genere
-

AjKDAP
1.255 2 6 9 - Expert EY

- Messaggi: 796
- Iscritto il: 17 mag 2006, 0:13
- Località: nella coda dei pronti
0
voti
Se ho capito bene ti riferisci ad un PIC visto che 
Tempo fa avevo scritto questo programma per una simulazione Supercar con un PIC16F886, che usa proprio il TMR0 e l'interrupt. Il flag del TMR0 è il T0IF.
Il programma l'ho solo simulato, spero che ti sia utile.

Tempo fa avevo scritto questo programma per una simulazione Supercar con un PIC16F886, che usa proprio il TMR0 e l'interrupt. Il flag del TMR0 è il T0IF.
- Codice: Seleziona tutto
/*
TMR0 INTERRUPT EXAMPLE by gohan
*/
#include <htc.h>
__CONFIG (0x014);
char i, bar, UP, count;
void main(void)
{
PORTC = 0x00;
PORTB = 0x00;
OPTION_REG = 0x87;
INTCON = 0x80;
ANSEL = 0x00;
TRISB = 0x00;
TRISC = 0x00;
count = 0;
i = 0;
bar = 0x01;
UP = 1;
while(1)
{
PORTC = bar;
PORTB = count;
TMR0 = 0x16;
T0IE = 1;
while(!T0IF);
;
}
}
void interrupt ISR(void)
{
if(T0IF)
{
T0IF = 0;
}
if(UP)
{
if(i < 7)
{
bar <<= 1;
i++;
}
else
{
UP = 0;
count++;
}
}
if(!UP)
{
if(i > 0)
{
bar >>= 1;
i--;
}
else
{
UP = 1;
}
}
}
Il programma l'ho solo simulato, spero che ti sia utile.
0
voti
Scusate ragazzi, nella fretta ho dimenticato di specificare alcuni dettagli
Utilizzo un PIC, in particolare il 18F4550 con la gestione dell'USB che ho già implementato. Il prescaler, nel primo esempio che ho scritto non l'ho tenuto in considerazione (1:1) ma dovrei impostarlo facendo un paio di calcoli per vedere cosa mi conviene in termini di riduzione dell'errore per raggiungere i 250 mS. Ad esempio se imposto un 1:32, l'overflow dovrebbe esserci ogni 1,63 mS (con timer ad 8 bit). Ovviamente dopo l'overflow vado a resettare il registro.
in particolare comunque volevo capire se la tecnica che si deve utilizzare per riuscire ad ottenere un intervallo di tempo maggiore dell'overflow, è quella di contare un certo numero di interrupt con una variabile contatore.
in particolare comunque volevo capire se la tecnica che si deve utilizzare per riuscire ad ottenere un intervallo di tempo maggiore dell'overflow, è quella di contare un certo numero di interrupt con una variabile contatore.
0
voti
dany192 ha scritto:in particolare comunque volevo capire se la tecnica che si deve utilizzare per riuscire ad ottenere un intervallo di tempo maggiore dell'overflow, è quella di contare un certo numero di interrupt con una variabile contatore.
Si, per esempio nell'interrupt potresti fare così:
- Codice: Seleziona tutto
if(counter == N)
{
/* Do your job */
}
else
counter++;
0
voti
Perfetto adesso faccio un po' di prove...penso che ne avrò per tutta la nottata
Grazie a tutti
Grazie a tutti

0
voti
Ragazzi sto avendo qualche problemino...la routine di gestione dell'interrupt è sempre la stessa?? Mi spiego meglio, sto lavorando con un HID con la libreria di MikroC ed ho già una routine che si occupa di eseguire la seguente istruzione:
Adesso però devo gestire pure il timer0 ed ho lavorato in questo modo:
Il firmware è molto lungo quindi non riesco nemmeno a postarlo però non mi funziona la parte del timer...nel main controllo la variabile "cnt" e quando arriva a 19 (sono passati circa 250ms) accendo un led però non va.
Ho dimenticato qualcosa nella configurazione dei registri??
- Codice: Seleziona tutto
void interrupt(){
HID_InterruptProc();
}
Adesso però devo gestire pure il timer0 ed ho lavorato in questo modo:
- Codice: Seleziona tutto
void interrupt(){
if(INTCON.TMR0IF){
cnt++; //Incremento il contatore
INTCON.TMR0IF = 0; //Resetto l'overflow
}
else HID_InterruptProc();
}
Il firmware è molto lungo quindi non riesco nemmeno a postarlo però non mi funziona la parte del timer...nel main controllo la variabile "cnt" e quando arriva a 19 (sono passati circa 250ms) accendo un led però non va.
Ho dimenticato qualcosa nella configurazione dei registri??
- Codice: Seleziona tutto
// Configurazione registri interrupt
INTCON = 0b11100000;
INTCON2 = 0xF5;
INTCON3 = 0xC0;
RCON.IPEN = 0; // Disabilito livello di priorità
PIE1 = 0;
PIE2 = 0;
PIR1 = 0;
PIR2 = 0;
// Configurazione Timer - Overflow
T0CON = 0b11000111; //8bit - Prescaler 1:256
0
voti
La prima cosa da fare, prima di qualsiasi cosa, in questo caso è resettare il flag di overflow e di interrupt del TMR0 sennò il micro non farà altro che attendere la richiesta di interruzione. Quindi io cambierei l'ordine delle istruzioni così:
Non so cosa tu stia facendo in HID_InterruptProc(), ma non lo puoi fare all'interno della stessa funzione di interrupt dentro ad un if come fai con il TMR0?
- Codice: Seleziona tutto
void interrupt()
{
if(INTCON.TMR0IF)
{
INTCON.TMR0IF = 0; //Resetto l'overflow
cnt++; //Incremento il contatore
}
else HID_InterruptProc();
}
Non so cosa tu stia facendo in HID_InterruptProc(), ma non lo puoi fare all'interno della stessa funzione di interrupt dentro ad un if come fai con il TMR0?
0
voti
La HID_InterruptProc() è una funzione standard della libreria di gestione dell'USB di MikroC e serve a mantenere la connessione.
Il documento ufficiale dice così: HID_InterruptProc() handles the USB communication and must be called as frequent as possible to maintain a secure connection.
Facendo un paio di prove ho scoperto che il problema stava nel fatto che non riuscivo a intercettare il valore preciso di cnt sul main, che dev'essere 19, ovvero 13107,2 uS x 19 = 249,04 mS . All'interno del main avevo questa situazione:
Ho risolto mettendo un >= sul controllo di cnt.
Il documento ufficiale dice così: HID_InterruptProc() handles the USB communication and must be called as frequent as possible to maintain a secure connection.
Facendo un paio di prove ho scoperto che il problema stava nel fatto che non riuscivo a intercettare il valore preciso di cnt sul main, che dev'essere 19, ovvero 13107,2 uS x 19 = 249,04 mS . All'interno del main avevo questa situazione:
- Codice: Seleziona tutto
//controllo timer
if(cnt==19){
//sono trascorsi 249,04 mS
PORTD.RD2 = ~PORTD.RD2; //lampeggio di un led per verifica
cnt = 0;
};
Ho risolto mettendo un >= sul controllo di cnt.
16 messaggi
• Pagina 1 di 2 • 1, 2
Torna a Firmware e programmazione
Chi c’è in linea
Visitano il forum: Nessuno e 19 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)

