Ho sperimentato tramite il simulatore wokwi la possibilità di scalare la frequenza di clock di arduino nano (ATmega328). In effetti scala almeno fino al divisore x64, cioè 16MHz / 64. Oltre la IRREMOTE non ha sufficiente clock per lavorare (credo). La cosa interessante almeno con il simulatore che non è necessario riconfigurare la seriale.
Ne è nata la seguente piccola funzione:
void divideClockSystem(uint16_t div) {
if (div > 256)
div = 256;
div = log(div) * M_LOG2E;
Serial.println(div);
cli(); // disabilita gli interrupt
CLKPR = _BV(CLKPCE);
CLKPR = (uint8_t)div;
sei(); // enable global interrupt
}
Da chiamare con:
divideClockSystem(div); // div 1,2,4,8,16,32,64,128,256
PS:c'era un post di un utente che chiedeva come ridurre il consumo di un
allarme fatto con arduino, direi che questa funzione può tornare utile per ridurre il consumo con o senza sleep mode.
Credo invece che la seriale lavori sempre con il clock fornito dal quarzo, cioè 16MHz, mentre timer ecc vengono influenzati. Sembra anche così leggendo il datasheet, che dice:
9.11
System Clock Prescaler
The ATmega48A/PA/88A/PA/168A/PA/328/P has a system clock prescaler, and the system clock can be
divided by setting the ”CLKPR – Clock Prescale Register” on page 46. This feature can be used to decrease the
system clock frequency and the power consumption when the requirement for processing power is low. This can
be used with all clock source options, and it will affect the clock frequency of the CPU and all synchronous
peripherals. clk I/O , clk ADC , clk CPU , and clk FLASH are divided by a factor as shown in Table 29-11 on page 314.
Ma infatti sto cercando di capire la differenza tra asincrono e sincrono, la USART la usiamo in modo Asincrono, vorrei capire da dove prende il clock.
In ogni caso basta provare sull'hardware e verificare cosa succede alla seriale. Con RP2040 devo riconfigurare la seriale quando cambio il clock.
Da clock distribution sembra che il prescaler influenzi tutto.
div>>=1? Dove l'ho scritto?...
Ah! Devo correggere div>>1 in div>>=1, come se fosse x+=1!
E' vero! Adesso ho capito. Mi sto arrugginendo un po'...
Grazie!
Non so se ti stai arrugginendo, anzi io penso proprio di no, ciò che ti rovina è la sintassi: div spazio 3 caratteri per l'operatore >>= e uno spazio a cui segue l'operando. Lo si vede a colpo d'occhio che non sono tre caratteri per cui qualcuno mi deve essere rimasto nella tastiera.
Ora dammi un buon motivo per usare la tua sintassi tutto attaccato senza spazi, perché io ci trovo solo svantaggi.
PS: non avevano la nano, ma la 2560 mini a 15€, ovviamente gliel'ho lasciata.
Ciao.
Se abbiamo la necessità di avviare la nostra scheda (basata su ATmega328P) con un clock sottomultiplo del clock che abbiamo, possiamo inserire, in testa al nostro programma, il seguente codice (i valori riportati nel codice sono per un prescaler che divide per 2 ... comodo per portare il classico clock da 16 MHz a 8MHz così da poter far funzionare, in sicurezza, la MCU a 3.3v):
La funzione NON deve essere richiamata ... viene automaticamente messa in esecuzione PRIMA del main() e delle chiamate a setup() e loop(), facendoci quindi trovare, all'avvio del nostro programma, il clock già impostato come vogliamo.
Ah, per chi fosse interessato ad approfondire, il significato delle "section" in cui si può definire che un codice vada, è documentato QUI ed in particolare, quella utilizzata (.init3) la si trova dove parla delle "The .initN Sections".
Per completezza, le funzioni contrassegnate con __attribute__((used)) sono contrassegnate nel file oggetto per evitare la rimozione della sezione (che può apparire inutilizzata) da parte del linker.