Come posso fare a generare una onda quadra a 20MHz duty 50% sul pin D5 della scheda Arduino UNO Q? E' possibile? Quali librerie devo usare?
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere solo in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana.
Grazie.
Buonasera e benvenuto nella sezione Italiana del forum,
... cortesemente, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15) e poi, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie
Alex
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione e sistemato il codice come indicato, nel rispetto del regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. ![]()
Sorry, ero convinto di essere nella sezione in lingua italiana.
Come in questi casi dico sempre ... qui, nella sezione Italiana del forum, gli utenti di Arduino Q, con esperienza tale da poter rispondere a quesiti, credo si contino sulle dita di una sola mano ... ![]()
Se si vuole una risposta più sicura ed in tempi più brevi, consiglio sempre di andare a porre la domanda, esclusivamente in lingua Inglese, nall'area internazionale didicata ad Arduino Q.
Poi ... vedi tu ...
Guglielmo
Grazie, io ci ho provato. Provo di sicuro sul forum internazionale.
Claudio
Non ho (ancora) una UNO Q, comunque chiedendo a Gemini, selezionando il motore 3.1 Pro (quello più "esperto" di programmazione, matematica e ragionamenti complessi) mi ha risposto così, vedi se ti può essere utilem, ovviamente ho usato la tua esatta domanda come prompt, e se ti serve il codice ti basta porre anche tu la stessa domanda a Gemini e poi rispondeergli che vuoi vedere un codice di esempio:
Sì, è assolutamente possibile, ma non puoi farlo utilizzando la classica funzione analogWrite().
L'Arduino UNO Q ha un'architettura ibrida di nuova generazione: i pin fisici standard come il D5 sono gestiti dal microcontrollore real-time STM32U585, che viaggia a una frequenza di clock nativa di 160 MHz. Per ottenere una frequenza estrema come 20 MHz, dovrai bypassare i comandi generici di Arduino e agire direttamente sui registri hardware del microcontrollore (utilizzando l'hardware abstraction layer STM32 HAL o il CMSIS).
Ecco come affrontare la configurazione dal punto di vista tecnico:
### 1. La Matematica del Timer
Il pin D5 sull'Arduino UNO Q corrisponde fisicamente al pin PA11 del chip STM32. Questo specifico pin è collegato via hardware al Timer 1, Canale 4 (TIM1_CH4). Poiché il clock di sistema è a 160 MHz, per ottenere 20 MHz esatti devi dividere il clock di base per 8.
** Prescaler (PSC): 0 (nessuna divisione pre-timer, il contatore viaggia a 160 MHz).*
** Auto-Reload Register (ARR): 7 (il timer conta da 0 a 7, per un totale di 8 cicli di clock per ogni periodo dell'onda).*
** Capture/Compare Register (CCR4): 4 (per avere un duty cycle esattamente al 50%, il segnale starà ALTO per 4 cicli e BASSO per 4 cicli).*
### 2. Impostazione dei Registri (L'Approccio)
Poiché l'ambiente di sviluppo della UNO Q gestisce il routing dei pin tramite Zephyr OS / Arduino Core, dovrai scrivere uno sketch che esegua questi passaggi a basso livello:
1. Abilitare il clock periferico per la porta GPIOA e per il TIM1.
2. Configurare il pin PA11 in modalità Alternate Function (AF) e assegnarlo al TIM1.
3. Velocità del Pin (Cruciale): Devi obbligatoriamente impostare il registro OSPEEDR del pin PA11 su Very High Speed. Se ometti questo passaggio, a 20 MHz la capacità parassita del pin trasformerà la tua onda quadra in un'onda simil-sinusoidale con un'ampiezza dimezzata.
4. Inizializzare il TIM1 in modalità PWM, inserendo i valori matematici calcolati sopra e abilitando l'output sul Canale 4.
### 3. Avvertenze Hardware Importanti
** Livello Logico 3.3V: Ricorda che i banchi I/O dell'STM32 sull'header digitale della UNO Q operano a 3.3V (assoluto massimo 3.6V), non a 5V come le vecchie generazioni di UNO R3.*
** Integrità del Segnale: A 20 MHz, i classici cavetti jumper (Dupont) e le breadboard si comportano come antenne e filtri passa-basso. L'induttanza dei cavi distorcerà pesantemente i fronti di salita e discesa dell'onda quadra. Se devi applicare questo segnale a un altro componente, mantieni i collegamenti estremamente corti e verifica il risultato con un oscilloscopio con almeno 100 MHz di banda passante.*
Vuoi che ti butti giù una bozza del codice in C per configurare direttamente i registri STM32 necessari per questo setup?
Ma come mai hai scritto nel forum generico "Programming", e non in quello che ti ha indicato Guglielmo, dedicato esplicitamente a UNO Q?... ;-)
Il post del forum in lingua inglese creato da @berta_64 è qui:
Vabbè, ma se ha preferito così non è un problema... ![]()
Sorry, non avevo fatto caso al link e mi sono un pò incasinato cercando per il forum. Non ho pensato ad andare in Official Hardware.
Claudio
Anche io avevo chiesto a Claude Sonnet 4.6. ma la risposta è stata che con le librerie che ci sono non si riesce.
Infatti NON c'era nulla da cercare, bastava fare click sul link ed andavi nella sezione più opportuna ![]()
Guglielmo
... il problema è che quella che avevo indicato è l'area specifica per quella scheda, dove trova gente preparata che usa quella scheda, l'altra ... è un'area generica ![]()
Guglielmo
Ho visto dalla prima risposta che mi hanno dato. Al momento sto provando a seguire il suggerimento di @docdoc. In caso aprirò una nuova discussione nel posto giusto. Grazie.
Grazie @docdoc della dritta. Ci sono riuscito. Il segnale è un pò distorto ma funziona. Direi che tu sei uno dei pochi di cui @gpb01 parlava. Evidentemente conosci bene i micro della ST.
Mi sembra doveroso condividere il codice:
// start_sqw_d5 – avvia onda quadra 20 MHz su D5 (timer HW)
// Ritorna 1 se avviato, 0 se il BSP non supporta la frequenza richiesta.
// start_sqw_d5 – 20 MHz su PA11 (D5) via TIM1 CH4, accesso diretto ai
// registri STM32U585
// ---------------------------------------------------------------------------
int start_sqw_d5() {
// ── 1. Abilita clock GPIOA e TIM1 ────────────────────────────────────────
RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN; // clock GPIOA
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // clock TIM1
__DSB(); // sincronizza il bus
// ── 2. Configura PA11 in Alternate Function ───────────────────────────────
// MODER: bit [23:22] = 0b10 (Alternate Function)
GPIOA->MODER &= ~(0x3UL << (11 * 2));
GPIOA->MODER |= (0x2UL << (11 * 2));
// OSPEEDR: bit [23:22] = 0b11 (Very High Speed) – OBBLIGATORIO a 20 MHz
GPIOA->OSPEEDR |= (0x3UL << (11 * 2));
// OTYPER: bit 11 = 0 (Push-Pull)
GPIOA->OTYPER &= ~(1UL << 11);
// PUPDR: bit [23:22] = 0b00 (No pull)
GPIOA->PUPDR &= ~(0x3UL << (11 * 2));
// AFR[1] (AFRH): bit [15:12] = AF1 (0x1) per TIM1_CH4 su PA11
GPIOA->AFR[1] &= ~(0xFUL << ((11 - 8) * 4));
GPIOA->AFR[1] |= (0x1UL << ((11 - 8) * 4));
// ── 3. Configura TIM1 ─────────────────────────────────────────────────────
TIM1->CR1 = 0; // disabilita il timer
TIM1->PSC = 0; // prescaler = 0 → clock = 160 MHz
TIM1->ARR = 7; // periodo: 160MHz/(0+1)/(7+1) = 20MHz
TIM1->CCR4 = 4; // duty cycle 50% (4/8)
// CCMR2: OC4M = 0b110 (PWM mode 1) su CH4 (bit [14:12])
TIM1->CCMR2 &= ~(0x7UL << 12);
TIM1->CCMR2 |= (0x6UL << 12); // PWM mode 1
TIM1->CCMR2 |= (1UL << 11); // OC4PE: preload enable
// CCER: CC4E = 1 (abilita output CH4), CC4P = 0 (polarità attiva alta)
TIM1->CCER &= ~(0xFUL << 12);
TIM1->CCER |= (1UL << 12); // CC4E
// BDTR: MOE = 1 (Main Output Enable) – obbligatorio per TIM1 (advanced)
TIM1->BDTR |= TIM_BDTR_MOE;
// EGR: UG = 1 (forza aggiornamento registri shadow)
TIM1->EGR = TIM_EGR_UG;
// ── 4. Avvia il timer ─────────────────────────────────────────────────────
TIM1->CR1 |= TIM_CR1_CEN;
int idx = findIndex("D5");
if (idx >= 0) pinModes_arr[idx] = OUTPUT;
sqw20_active = true;
return 1;
}
// ---------------------------------------------------------------------------
// stop_sqw_d5 – ferma TIM1 e riporta PA11 a GPIO OUTPUT LOW
// ---------------------------------------------------------------------------
void stop_sqw_d5() {
// Ferma il timer e disabilita l'output
TIM1->CR1 &= ~TIM_CR1_CEN;
TIM1->CCER &= ~(1UL << 12); // CC4E = 0
TIM1->BDTR &= ~TIM_BDTR_MOE;
// Riporta PA11 in modalità GPIO OUTPUT
GPIOA->MODER &= ~(0x3UL << (11 * 2));
GPIOA->MODER |= (0x1UL << (11 * 2)); // 0b01 = Output
GPIOA->BSRR = (1UL << (11 + 16)); // reset bit → LOW
sqw20_active = false;
}
Grazie. ![]()
Claudio