terça-feira, dezembro 25, 2012

JY-MCU Minimum AVR System Board - Conferindo o Clock

O objetivo do nosso segundo programa é confirmar o clock do microcontrolador. Lembrando, a placa vem com um cristal de 16MHz e um ATmega32L8AU de 8MHz.

Existem várias formas de testar o clock, mas optei por algo bem direto: usar o timer1 para contar um segundo.

O timer1 do ATmega32 é alimentado pelo clock do processador dividido por um estágio de prescaler. Supondo o pior caso, que o clock seja realmente de 16MHz, para que a contagem caiba em 16 bits precisamos fazer a divisão por 256. Em um segundo teremos 62500 contagens.

O timer1 pode operar em vários modos, usei o CTC (Clear Timer on Comparer). O contador do timer começa em zero e vai contando a cada pulso do clock. Quando atinge o valor definido em um registrador de limite (no meu caso o OCR1A) é ligado o bit OCF1A no registrador de identificação de interrupções (TIFR) e o contador é zerado. O bit OCF1A poderia corresponder a uma interrupção, mas no meu caso vou simplesmente testá-lo no meu loop principal. A forma de desligar este bit não é muito óbvia: é necessário escrever em TIFR um valor com este bit ativo.

A descrição acima pode ser longa (e o texto no Manual de Referência do ATmega32 pode ser complexo), mas bastam duas linhas de C para programar o timer e outras duas linhas para fazer o teste e zerar a indicação de passagem de 1 segundo.

Para podermos acompanhar visualmente a passagem de tempo, a cada 1 segundo incrementamos o valor em um byte e o escrevemos nos LEDs. Obtemos assim um contador binário de segundos.

O código completo fica:
// Programa principal
int main(void)
{
    uint8_t cont = 0;
    
    // Inicia as direçoes dos pinos de conexão dos LEDs
    LED_DDR |= 0xFF;
    
    // LEDs Apagados
    LED_PORT = 0x00;

    // Liga pullup das teclas
    TEC_DDR &= ~(TEC1|TEC2|TEC3|TEC4);
    TEC_PORT |= TEC1|TEC2|TEC3|TEC4;

    // Preparar o timer 1 operar no modo CTC com 16MHz / 256
    // contando até 62500 (1 segundo)
    OCR1A = 62500;
    TCCR1B = _BV(WGM12) | _BV(CS12);
    
    for (;;)
    {
        if (TIFR & _BV(OCF1A ))
        {
            TIFR = _BV(OCF1A );         // Limpa indicação do timer
            LED_PORT = ++cont;
        }
    }
}
Agora é só compilar, gravar na placa e conferir os tempos indicados pelos LEDs com um relógio. E realmente o ATmega32 está sofrendo overclocking e funcionando alegremente no dobro da velocidade garantida pelo fabricante.

O projeto completo está nos arquivos do blog, em jymega32_teste2.zip.

Nenhum comentário: