Pages: [1]   Go Down
Author Topic: [risolto] dubbio su delayMicroseconds  (Read 662 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 8
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

buondì a tutti..
qualcuno sa dirmi se posso usare questa funzione all'interno di una funzione richiamata da interrupt?
so che il delay non funziona in questo caso,ma la delayMicroseconds?

grazie per le risposte smiley
« Last Edit: August 09, 2012, 09:53:15 am by m_ri » Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 104
Posts: 6622
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il codice è:
Code:
/* Delay for the given number of microseconds.  Assumes a 8 or 16 MHz clock. */
void delayMicroseconds(unsigned int us)
{
// calling avrlib's delay_us() function with low values (e.g. 1 or
// 2 microseconds) gives delays longer than desired.
//delay_us(us);
#if F_CPU >= 20000000L
// for the 20 MHz clock on rare Arduino boards

// for a one-microsecond delay, simply wait 2 cycle and return. The overhead
// of the function call yields a delay of exactly a one microsecond.
__asm__ __volatile__ (
"nop" "\n\t"
"nop"); //just waiting 2 cycle
if (--us == 0)
return;

// the following loop takes a 1/5 of a microsecond (4 cycles)
// per iteration, so execute it five times for each microsecond of
// delay requested.
us = (us<<2) + us; // x5 us

// account for the time taken in the preceeding commands.
us -= 2;

#elif F_CPU >= 16000000L
// for the 16 MHz clock on most Arduino boards

// for a one-microsecond delay, simply return.  the overhead
// of the function call yields a delay of approximately 1 1/8 us.
if (--us == 0)
return;

// the following loop takes a quarter of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2;

// account for the time taken in the preceeding commands.
us -= 2;
#else
// for the 8 MHz internal clock on the ATmega168

// for a one- or two-microsecond delay, simply return.  the overhead of
// the function calls takes more than two microseconds.  can't just
// subtract two, since us is unsigned; we'd overflow.
if (--us == 0)
return;
if (--us == 0)
return;

// the following loop takes half of a microsecond (4 cycles)
// per iteration, so execute it twice for each microsecond of
// delay requested.
us <<= 1;
   
// partially compensate for the time taken by the preceeding commands.
// we can't subtract any more than this or we'd overflow w/ small delays.
us--;
#endif

// busy wait
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t" // 2 cycles
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
);
}

secondo me si.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10113
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

la delaymillisecond funziona perchè non si basa su interrupt ma su di un ciclo. è comunque un grave errore usare un qualsiasi tipo di delay all'interno di un interrupt, quindi la risposta è NO!
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
God Member
*****
Karma: 8
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

quell'interrupt che mi richiama la funzione è un serialevent..vorrei leggere un pin quando mi viene richiesto,quindi farei un po' di letture distanziate di pochissimo tempo,per evitare disturbi & co..
non mi sembra gravissimo smiley

grazie a entrambi!!
Logged

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10113
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
non mi sembra gravissimo
ed invece lo è, sopratutto considerando che non solo stai bloccando gli interrupt, ma persino la seriale; non so come si comporta sotto, ma se si blocca il circuito HW della seriale in attesa della tua funzione puoi ben capire che la sincronizzazione col pc protrebbe andare a pallino, anche se solo per un carattere.

la soluzione è attivare una flag, e poi da loop verificarla, se attiva la disattivi subito (in modo da ricevere una seconda verifica successiva a quella che sai completando) fai le tue belle misure con tutti i delay che vuoi, e poi via verso altri lidi.  smiley-mr-green
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
God Member
*****
Karma: 8
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vedi, io ricevo pacchetti di dimensione fissa..alla fine della ricezione,elaboro ed evenualmente mi blocco per pochi ms..tra un pacchetto e l'altro passano come minimo 100 ms,ma probabilmente 500ms..è per questo motovi che non è grave,a mio parere..in altri contesti t'avrei dato ragione..
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Se parliamo di ns o di us è un conto, ma bloccare per 100-500 ms, millisecondi, una ISR non è  salutare. Sono troppi.
Puoi rovesciare la cosa, ossia crearti una funzione ISR agganciata ad un interrupt PCINT (cambio di stato) con il quale leggi i segnali sul pin e poi inserisci il dato in un buffer. Dal loop principale elabori i dati ricevuti.

Replichi in buona sostanza ciò che fa la seriale.
Logged


0
Online Online
Shannon Member
****
Karma: 117
Posts: 10113
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no leo, si parla di ms tra una richiesta seriale e l'altra, non tra le letture. Quindi in questo caso direi che l'idea di m_ri può funzionare senza problemi.
Ovvio, che però tutte le dalay e le millis() saranno sfalseranno molto il loro valore, a cui puoi rimediare facendo il conto degli interrupt elaborati nel frattempo, moltiplicare per la durata della funzione (diciamo che del delay basta) e sottrarre il tutto alla delay/millis().

@leo: Tra l'altro questo è uno dei motivi per cui la swRTC sfasa; se si riuscisse ad escludere gli altri interrupt il più possibile, avtresti dei valori molto più reali.
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@lesto:
non è possibile isolare una routine di interrupt dalle altre, per il semplice motivo che tutte le ISR sono definite atomiche per default dal compilatore.
Ciò significa che quando viene attivata una routine ISR questa non può essere interrotta da un'altra ISR.
Quindi quando l'ISR della swRTC sta lavorando essa non è interrompibile da nulla ma ciò vale anche nei confronti delle altre ISR relativamente alla swRTC: cioè che essa non può interrompere le altre ISR, perdendo quindi in precisione.

L'unico modo per avere una swRTC molto precisa è modificare il core di Arduino rendendo tutte le altre ISR interrompibili. Il problema però si ritorce poi contro nel senso che dopo sono tutte le altre ISR a diventare inesatte per cui ad esempio una ricezione seriale fa a farsi friggere dato che i tempi saltano e la comunicazione può andar fuori sincronizzazione.

Logged


0
Online Online
Shannon Member
****
Karma: 117
Posts: 10113
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

con "escludere" intendo -disattivare- tutti gli interrut possibli e immaginabili, e lasciare solo il minimo indispensabile. per esempio la vecchia SoftwareSerial NON usava interrutp; potresti riesumarla...
certo però che come dici in pratica si sta pensando di riscrivere il core..
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@lesto:
Sì ma diventa un cane che si morde la coda perché gli interrupt vengono generati da un sacco di cose differenti.
Ad esempio, la ricezione di un dato tramite I2C attiva un interrupt, non solo la seriale.

@m_ri:
la SoftwareSerial non usava gli interrupt però si bloccava nei cicli di trasmissione e ricezione, dato che monitorava le operazioni tramite codice.
Logged


Pages: [1]   Go Up
Jump to: