La risposta accettata di jfpoilpret è scritta molto bene, perfettamente valida e nel 99% dei casi farò esattamente quello che spiega. Le sue soluzioni rientrano nei parametri definiti, quindi dovrebbero funzionare molto bene. Ma cosa c'è di meglio di " molto bene "? Perfezione! Dopotutto, la domanda riguarda la generazione di un valore esatto. Come detto abbastanza vicino è buono nella maggior parte dei casi (probabilmente tutti), e anche quando hai a che fare con qualcosa come un orologio quando 1 secondo deve essere 1 secondo, devi ancora subire le imperfezioni delle parti ereditate.
Quello che suggerirò non è sempre possibile. In alcuni casi, è possibile, ma con molta più seccatura e fatica di questo caso. Vale la pena dipendere caso per caso. Il mio obiettivo è principalmente quello di mostrare un'alternativa per riferimenti futuri che sia migliore in casi piuttosto marginali. Questo è scritto pensando agli utenti principianti di Arduino che non hanno una vasta esperienza nell'elettronica.
Per le persone più avanzate questo probabilmente sembrerà troppo dettagliato e stupito. Ma credo che quelle stesse persone probabilmente lo sappiano già e non abbiano bisogno di questa risposta. Ciò è applicabile anche a tutti i microcontrollori, a tutti i produttori e alle architetture. Ma per altri microcontrollori dovrai consultare la scheda tecnica corretta per scoprire registri e nomi e valori di rivendita adeguati.
Nel tuo caso, hai bisogno di una frequenza specifica e la cosa bella è che è possibile ottenere esattamente 56 kHz in modo molto semplice (senza contare le imperfezioni pratiche delle parti). Quindi anche questo è un esempio perfetto.
La generazione di un segnale dipende dai timer e dalla sorgente di clock del microcontrollore, come spiegato bene da jfpoilpret. La sua risposta affronta il problema di un solo punto di vista e che sta armeggiando con i timer. Ma puoi giocherellare anche con la sorgente di clock, o ancora meglio con entrambi per sinergia e risultati fantastici. Modificando i parametri dell'ambiente, in questo caso hackerando il sistema e sostituendo l'origine del clock, possiamo affrontare un problema specifico con molta, molta più facilità e semplicità.
In primo luogo ricordare, a causa della commutazione dello stato del pin, è necessario eseguire l'ISR due volte più della frequenza del segnale. Questo è 112.000 volte al secondo. 56.000 e 16.000.000 non si sommano molto bene come già sottolineato. Dobbiamo cambiare la frequenza del segnale o la frequenza di tatto. Affrontiamo per ora una frequenza del segnale immutabile e troviamo una migliore velocità di clock.
Sarebbe molto semplice scegliere un orologio con un ordine di grandezza maggiore di 56 kHz (o 112 kHz, ma è praticamente lo stesso), poiché aggiungi solo zeri e questo tipo di matematica è più semplice per la maggior parte delle persone. Purtroppo tutto in questo mondo è una sorta di compromesso con qualcosa. Non tutti i valori funzioneranno.
Il primo esempio è con una velocità del generatore di tatto troppo bassa.
Se scegli un orologio a 56.000 Hz non sarai in grado di fare nulla poiché dovrai chiamare l'ISR ad ogni ciclo e non puoi fare nient'altro. È assolutamente inutile. Se scegli una velocità 10 volte più veloce (560 kHz), avrai 9 (10 cicli affinché il timer raggiunga il suo valore massimo - un ciclo per chiamare la funzione ISR) cicli di microcontrollore per fare il tuo lavoro e questo abbastanza possibile non può essere sufficiente. Spesso semplicemente hai bisogno di più potere computazionale.
Se si sceglie un valore troppo grande, d'altra parte, come 56 MHz il microcontrollore semplicemente non può funzionare con esso. È troppo veloce. Quindi, semplicemente scegliendo il valore più grande nel negozio non lo taglierà neanche.
Arduino Uno R3 originale ha un clock di serie a 16 MHz, quindi tutto ciò che è più lento è garantito per funzionare. Il valore successivo che è un ordine di grandezza maggiore di 56 e inferiore a 16 MHz è 5,6 MHz. Ciò porterà a poter chiamare l'ISR ogni 50 cicli e creerà la frequenza del timer perfetta di 112.000 Hz. E il tuo segnale sarà esattamente 56 kHz. Avrai 49 cicli MCU per eseguire il tuo programma tra le chiamate ISR, ma è ancora circa 1/3 della velocità dell'orologio originale. Si può usare il 112 come base e usare un clock a 11.2 MHz e questo darà circa 2/3 del risonatore a 16 MHz di serie. La funzione ISR verrà chiamata ogni 100 cicli e genererà comunque un segnale perfetto a 56 kHz.
Tuttavia esistono due problemi principali con questi valori.
Il primo problema dipende fortemente dalle tue esigenze: sacrifichi circa 1/3 (con 11,2 MHz) della tua massima potenza computazionale per ottenere la frequenza esatta del segnale che utilizza un valore di registro facile da trovare (OCR iirc ). Potresti star bene o no.
Il secondo problema è un duro spettacolo : è molto facile trovare valori, ma molto spesso semplicemente non esistono come una sorgente di clock prodotta. Questa è la pagina web del risonatore di Farnell che manca semplicemente di 5,6 MHz e 11,2 MHz.
Per aggirare questo, possiamo esaminare i valori di risonatore disponibili e scoprire qualcos'altro che può essere usato per generare esattamente i valori desiderati. Se dividiamo 56 per 4 otteniamo 14 e per fortuna c'è un risonatore a 14 MHz. Questo ci offre una velocità molto più elevata e una maggiore potenza e un valore di registro altrettanto facile da trovare. Per chiamare l'ISR 112.000 volte al secondo, dobbiamo inserire il valore decimale 124 o 0x7C esadecimale nel registro OCR, quindi con il conteggio di 124 cicli + 1 per chiamare l'ISR, otteniamo il valore desiderato desiderato.
NB
- ISR - routine di servizio di interrupt (questo è il codice che viene eseguito solo su interrupt generati)
- Quanto può essere grande il tuo programma dipende dalla dimensione della memoria! Non ha nulla a che fare con la velocità di clock e non ha nulla a che fare con la frequenza con cui si chiama ISR.
Quando il microcontrollore si avvia con il comando di programma, viene incrementato un contatore. Se viene generato un interrupt, viene chiamato l'ISR e questo valore viene memorizzato in un registro speciale. Al termine del codice ISR, il valore del contatore del programma viene ripristinato da questo registro speciale e il programma continua da dove era stato interrotto come se non fosse mai accaduto.
Farò un esempio estremamente stupito. Se sei un purista, ti avverto: possono verificarsi sanguinamento del naso e degli occhi.
Immagina di dover camminare da qualche parte a qualche parte. Le istruzioni dettagliate sul percorso sono il tuo programma principale e i suoi comandi. La velocità con cui cammini o corri, dipende dalla tua "velocità di clock", ma non dalle istruzioni del percorso (30 passi avanti, 1 giro 90 gradi a sinistra, 10 passi avanti, 45 gradi a destra, ecc.) Sono sempre gli stessi . Ora immagina un bambino o un avido politico locale corrotto che ti scioglie le scarpe di tanto in tanto. Questo è l'evento che genera un interrupt. Quindi ti fermi dopo l'ultimo passo, ti inginocchi e leghi di nuovo la scarpa. Questo è il tuo programma ISR.
Quindi prosegui dal punto in cui ti sei fermato; non inizi dall'inizio. Quando cammini senza preoccupazioni nel mondo e con tutto il tempo, non ti importa nemmeno se devi allacciarti le scarpe ogni altro passo. Se invece lo fai con vincoli di tempo, come correre a 100 metri alle Olimpiadi (o correre da un predatore affamato che mangia carne), fermarsi e allacciarsi le scarpe può avere conseguenze terribili. Lo stesso vale per i microcontrollori. Anche se esegui solo una riga di codice, il tuo programma continuerà, anche se lentamente. Se non ti interessa affatto la velocità, non sarà un problema. Se devi fare un po 'di tempo, come usare altre azioni dipendenti dal timer, l'interferenza può essere molto indesiderata e problematica.
Meno è meglio! Un orologio più veloce non è sempre migliore. I dispositivi con clock più lento consumano molta meno energia. Questo può essere un punto cruciale in un dispositivo a batteria.
I cicli necessari sono derivati da queste formule:
(velocità di clock / (valore prescaler * frequenza di chiamata ISR necessaria)) - 1