Ho sempre usato la funzione di MikroC Delay_ms in tutte le sue forme per gestire, temporalmente, i vari eventi di un programma. Ora però mi chiedo se è possibile controllare, dal punto di vista del tempo, due o più eventi indipendentemente.
Faccio un esempio banale: se volessi mettere in ON e in OFF con una certa frequenza due distinte porte del PIC, ad esempio per far lampeggiare due LED con diversa frequenza, questo sarebbe possibile?
Certo, in questo caso potrei semplicemente usare due PWM con diversa frequenza, ma in generale, sarebbe possibile?
Ovviamente non potrei usare Delay_ms, esiste qualche altro modo?
Gestire più delay indipendentemente
Moderatore:
Paolino
12 messaggi
• Pagina 1 di 2 • 1, 2
1
voti
Devi usare i timer o timers software tramite interrupt ciclica.
I ritardi "hard", nella realtà, non si usano praticamente mai se non per ritardi brevissimi.
I ritardi "hard", nella realtà, non si usano praticamente mai se non per ritardi brevissimi.
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
-

TardoFreak
73,9k 8 12 13 - -EY Legend-

- Messaggi: 15754
- Iscritto il: 16 dic 2009, 11:10
- Località: Torino - 3° pianeta del Sistema Solare
1
voti
@Tricka90,
come già ti hanno consigliato, qualsiasi micro utilizzi, l'unico modo per creare delay pseudo-indipendenti è quello di impiegare i timer presenti sul micro. Chiaramente dovrai abilitare e gstire l'interrupt che sarà scatenato dall'overflow del timer. Sull' handler dell' interrupt potrai incrementare una variabile, eseguire una comparazione con valori diversi e per ogni uguaglianza generare l'evento che ti interessa.
Buone vacanze
come già ti hanno consigliato, qualsiasi micro utilizzi, l'unico modo per creare delay pseudo-indipendenti è quello di impiegare i timer presenti sul micro. Chiaramente dovrai abilitare e gstire l'interrupt che sarà scatenato dall'overflow del timer. Sull' handler dell' interrupt potrai incrementare una variabile, eseguire una comparazione con valori diversi e per ogni uguaglianza generare l'evento che ti interessa.
Buone vacanze
0
voti
Sono riuscito a fare quello che mi avete consigliato! In particolare a far lampeggiare un LED ad una data velocità. Questa velocità la regolo in questo modo, non so se sia molto corretto:
In pratica tramite la variabile 'i' regolo il numero di interrupt che devono accadere, quindi il tempo che deve trascorrere sottoforma di cicli di conteggio del TIMER0, prima che il LED inverta il suo stato.
Ma oltre il TIMER0 nel PIERIN PIC18 esistono davvero altri timer che possono generare un interrupt per overflow? perché sul datasheet, nel registro INTCON trovo solo il Flag relativo al timer0...
Non ho ben capito questa frase, quale variabile mi stai consigliando di incrementare? E che comparazione?
- Codice: Seleziona tutto
void interrupt() {
if(INTCON.B2)
{
i++;
if(i == 2)
{
PORTD.RD6 = ~PORTD.RD6;
i = 0;
}
}
INTCON.B2 = 0;
}
In pratica tramite la variabile 'i' regolo il numero di interrupt che devono accadere, quindi il tempo che deve trascorrere sottoforma di cicli di conteggio del TIMER0, prima che il LED inverta il suo stato.
Ma oltre il TIMER0 nel PIERIN PIC18 esistono davvero altri timer che possono generare un interrupt per overflow? perché sul datasheet, nel registro INTCON trovo solo il Flag relativo al timer0...
cyclone ha scritto:@Tricka90,
Sull' handler dell' interrupt potrai incrementare una variabile, eseguire una comparazione con valori diversi e per ogni uguaglianza generare l'evento che ti interessa.
Non ho ben capito questa frase, quale variabile mi stai consigliando di incrementare? E che comparazione?
0
voti
Si riferisce a quello che tu hai implementato come
Se hai altre temporizzazioni definisci altre variabili oltre a i da incrementare e le confronti con il numero che corrisponde alla relativa temporizzazione.
2 consigli:
Non so bene come si gestiscano le ISR in MikroC ma qui viene spiegato che è buona norma che queste non richiamino altre funzioni ma eseguano tutto il codice interessato al loro interno per evitare il Context Save. In MikroC potrebbe succedere qualcosa di similare, non so... Parliamo di ottimizzazione comunque.
Se non sei strozzato con le tolleranze per il tempo del lampeggio, visto che è anche buona norma stringere al massimo possibile il codice dentro le ISR, potresti incrementare i nella interrupt service routine ma il check lo fai nel loop principale..

- Codice: Seleziona tutto
i++;
if (i == 2)
Se hai altre temporizzazioni definisci altre variabili oltre a i da incrementare e le confronti con il numero che corrisponde alla relativa temporizzazione.
2 consigli:
Non so bene come si gestiscano le ISR in MikroC ma qui viene spiegato che è buona norma che queste non richiamino altre funzioni ma eseguano tutto il codice interessato al loro interno per evitare il Context Save. In MikroC potrebbe succedere qualcosa di similare, non so... Parliamo di ottimizzazione comunque.
Se non sei strozzato con le tolleranze per il tempo del lampeggio, visto che è anche buona norma stringere al massimo possibile il codice dentro le ISR, potresti incrementare i nella interrupt service routine ma il check lo fai nel loop principale..

Anyone who has never made a mistake has never tried anything new
Two things are infinite: universe and human stupidity, and I'm not sure about the former
You did not really understand something unless you can explain it to your grandmother
A. Einstein
Two things are infinite: universe and human stupidity, and I'm not sure about the former
You did not really understand something unless you can explain it to your grandmother
A. Einstein
-

Shockwaver
770 1 5 11 - Expert

- Messaggi: 859
- Iscritto il: 3 mar 2010, 18:56
0
voti
L' articolo che ho scritto sul programma di demo del PIERIN spiega bene come implementare le interrupt cicliche. Ti suggerisco di leggerli, in tutti i miei articoli implemento i timer software.
Li trovi nel mio blog.
Oppure nella sezione "articoli" del sito del PIERIN. Basta cliccare nella mia firma.
Li trovi nel mio blog.
Oppure nella sezione "articoli" del sito del PIERIN. Basta cliccare nella mia firma.
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
-

TardoFreak
73,9k 8 12 13 - -EY Legend-

- Messaggi: 15754
- Iscritto il: 16 dic 2009, 11:10
- Località: Torino - 3° pianeta del Sistema Solare
0
voti
Genericamente si costruisce una base tempi precisa, veloce, dipende dai casi. Utilizzando uno dei timer che generano interrupt, un tick, che poi può essere di un millisecondo o più preciso. Fatto questo si battezza una variabile globale che incrementa di una unità ogni volta che scatta un tick. Nel formato internazionale TIME si usa un doppio intero come contatore di millisecondi, ma ha campi di applicazione specifici.
A questo punto, ad esempio io, ma vedo anche altrove, uso una funzione apposita di questo tipo:
dove tGtime è la variabile globale che conta i singoli tick.
A questo punto basta inserirla nel codice:
A questo punto, ad esempio io, ma vedo anche altrove, uso una funzione apposita di questo tipo:
- Codice: Seleziona tutto
time msec(time from = 0)
time msec(time from)
{
return tGtime - from;
}
dove tGtime è la variabile globale che conta i singoli tick.
A questo punto basta inserirla nel codice:
- Codice: Seleziona tutto
time t1; // timer 1
...
t1 = msec(); // per inizializzarlo
...
if msec(t1) > 1000
{
// dopo un secondo dall'inizializzazione...
}
-

Candy
32,5k 7 10 13 - CRU - Account cancellato su Richiesta utente
- Messaggi: 10123
- Iscritto il: 14 giu 2010, 22:54
0
voti
Mi accodo, anche se per evitare gli overhead di chiamata a funzioni, quando si tratta di una o due istruzioni, uso le macro, in questo caso sarebbe:

- Codice: Seleziona tutto
#define msec(from) (tGtime - from)

Anyone who has never made a mistake has never tried anything new
Two things are infinite: universe and human stupidity, and I'm not sure about the former
You did not really understand something unless you can explain it to your grandmother
A. Einstein
Two things are infinite: universe and human stupidity, and I'm not sure about the former
You did not really understand something unless you can explain it to your grandmother
A. Einstein
-

Shockwaver
770 1 5 11 - Expert

- Messaggi: 859
- Iscritto il: 3 mar 2010, 18:56
12 messaggi
• Pagina 1 di 2 • 1, 2
Torna a Realizzazioni, interfacciamento e nozioni generali.
Chi c’è in linea
Visitano il forum: Nessuno e 3 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)


