La prima cosa che verifico su una nuova scheda, sia che usi un oscillatore interno o un cristallo esterno, è che ho impostato correttamente la frequenza di clock. Questo è importante perché molte delle periferiche, come UART, SPI, I2C e timer dipendono da esso.
Il modo in cui lo posso verificare è scrivere un programma con un ciclo breve, sia nel linguaggio assembly in cui posso contare i cicli manualmente, sia in C, purché sia possibile ottenere un elenco di smontaggio e fare la stessa cosa - e accendere un LED e via. Ho impostato un loop in modo che venga eseguito una volta al secondo. Eseguo il codice e controllo che il LED lampeggi 60 volte in un minuto.
Per quanto riguarda le periferiche, il modo migliore per controllarle è utilizzare un oscilloscopio se ne hai uno e guardare la linea RX per UART, CLK, MOSI e le linee di selezione dei chip per SPI e le linee SDA e SCL per I2C e controlla che le linee siano commutabili e che i tempi siano corretti.
Se non si dispone di un oscilloscopio, è possibile posizionare i LED su queste linee e quindi abilitare o disabilitare le periferiche. Se disabilitato, la maggior parte delle linee sarà bassa (LED spento), ma alcune saranno alte, come il cavo RX di UART (LED acceso). Quando la periferica è abilitata, la maggior parte dei LED dovrebbe attenuarsi, poiché le linee si alterneranno. Eseguendo in un ciclo (disabilitato / abilitato) è più facile vedere la differenza tra on o dim.
Per l'UART, è possibile collegare la linea TX alla linea RX come un giro. È inoltre possibile connettersi quindi a un cavo UART-USB e sul PC reale un terminale un programma come RealTerm . Oltre a testare l'interfaccia, questo sarà utile per altri debug in seguito.
Per altri pezzi di codice, utilizzo più LED se necessario per mostrare che vengono eseguiti vari percorsi nel codice. Se l'UART funziona e è collegato a un PC, è possibile cospargere il codice con le chiamate a una subroutine per emettere un messaggio per mostrare quali punti ha raggiunto il programma (oppure usare printf se si dispone delle librerie C standard disponibili). Ma come sottolinea Vladimir Cravero in un commento qui sotto, questo può rallentare un po 'il tuo codice (a 115.200 baud, non troppo, poiché il tempo di un carattere è <10 µs). Ma negli ISR e in altri codici time-critical, basta usare i LED.
Come sottolinea Al Bundy in un commento qui sotto, anche i debugger in-circuit possono essere utili, in particolare se si possono impostare più punti di interruzione e ancora più utili se è possibile interrompere un punto di memoria in una posizione di memoria modificata. Non tutti i debugger hanno questa funzione.
Tuttavia non uso molto i debugger a meno che non sia necessario, ad esempio per guardare i bit in un registro periferico; o per rintracciare un bug che non riesco a trovare dall'ispezione; o all'analisi rudimentale della copertura del codice. Ma in generale mi piace eseguire i programmi alla loro velocità "normale", poiché di solito compaiono molti problemi che potrebbero non verificarsi quando il programma è a singolo passaggio. La maggior parte dei miei programmi usa molto gli interrupt, il che interferisce con l'uso di un debugger.