Le S3C2440 opère avec les fréquances d'horloge suivantes : MCLK à 405 MHz, HCLK à 135 MHz et PCLK à 67.5 MHz. La fréquence d'horloge du timer est PCLK divisé par 8, soit environ 8.4375 MHz.
Exemple avec le Timer 0
#include <stdint.h>
// Hypothèse : S3C2440PCLK est défini comme 67500000 (67.5 MHz)
#define S3C2440PCLK 67500000
// Délai en microsecondes en utilisant le timer 0
void micro_delai_timer0(uint16_t duree)
{
// Configuration du diviseur pour le timer 0 (1/8 de PCLK)
rTCFG1 = (rTCFG1 & ~0x0F) | 0x02;
// Calcul de la valeur de comptage pour 1 microseconde
rTCNTB0 = (S3C2440PCLK / 8) / 1000000;
// Mise à jour manuelle, démarrage du timer en mode auto-reload
rTCON = (rTCON & ~0x0F) | (1 << 3) | (1 << 1) | (1 << 0);
rTCON &= ~(1 << 1); // Effacer le bit de mise à jour manuelle
while (duree--) {
// Attendre que le compteur atteigne la valeur cible
while (rTCNTO0 != (rTCNTB0 - 1)) {
// Boucle d'attente active
}
}
// Arrêter le timer 0
rTCON &= ~(1 << 0);
}
// Délai en millisecondes en utilisant le timer 0
void milli_delai_timer0(uint16_t duree)
{
rTCFG1 = (rTCFG1 & ~0x0F) | 0x02;
// Calcul pour 1 milliseconde
rTCNTB0 = (S3C2440PCLK / 8) / 1000;
rTCON = (rTCON & ~0x0F) | (1 << 3) | (1 << 1) | (1 << 0);
rTCON &= ~(1 << 1);
while (duree--) {
while (rTCNTO0 != (rTCNTB0 - 1)) {
// Boucle d'attente
}
}
rTCON &= ~(1 << 0);
}
Exemple avec le Timer 1
// Délai en microsecondes en utilisant le timer 1
void micro_delai_timer1(uint16_t duree)
{
// Configuration du diviseur pour le timer 1 (décalage de 4 bits)
rTCFG1 = (rTCFG1 & ~(0x0F << 4)) | (0x02 << 4);
rTCNTB1 = (S3C2440PCLK / 8) / 1000000;
// Activation : auto-reload, mise à jour manuelle, démarrage
rTCON = (rTCON & ~(0x0F << 8)) | (1 << 11) | (1 << 9) | (1 << 8);
rTCON &= ~(1 << 9);
while (duree--) {
while (rTCNTO1 != (rTCNTB1 - 1)) {
// Attendre la fin du cycle
}
}
rTCON &= ~(1 << 8);
}
// Délai en millisecondes en utilisant le timer 1
void milli_delai_timer1(uint16_t duree)
{
rTCFG1 = (rTCFG1 & ~(0x0F << 4)) | (0x02 << 4);
rTCNTB1 = (S3C2440PCLK / 8) / 1000;
rTCON = (rTCON & ~(0x0F << 8)) | (1 << 11) | (1 << 9) | (1 << 8);
rTCON &= ~(1 << 9);
while (duree--) {
while (rTCNTO1 != (rTCNTB1 - 1)) {
// Boucle d'attente
}
}
rTCON &= ~(1 << 8);
}
Remarque importante : le registre de comptage actuel rTCNTOn et le registre de buffer rTCNTBn sont liés. Pendant le fonctionnement, rTCNTOn décrémente à chaque période d'horloge et est automatiquemetn rechargé à partir de rTCNTB0 lorsque la valeur zéro est atteinte (en mode auto-reload). La condition de boucle while vérifie que rTCNTOn n'a pas encore atteint la valeur cible pour garantir la précision du délai.