Timers do DSP TMS320F2812

Este post faz parte da série DSP TMS320F2812

Nos artigos anteriores foram apresentados os principais módulos do DSP, registradores e os módulos GPIO. Neste artigo serão apresentados o timers do DSP e as configurações necessárias para gerar interrupções periódicas. É importante lembrar que o DSP possui timers de propósito geral nos módulos EVA e EVB que podem ser utilizados para gerar sinais PWM, contador de pulsos, entre outras aplicações.

Operação dos Timers do DSP TMS320F2812

O DSP possui três timers de 32 bits. Os timers 1 e 2 são geralmente utilizados pela Texas para aplicações de tempo real. Já o timer 0 pode ser utilizado para propósitos gerais. Na Figura 1 é mostrado o diagrama de registradores e sinais utilizados nesses módulos.

CPU Timers do DSP TMS320F2812.
Figura 1: CPU Timers do DSP TMS320F2812.

É importante destacar que os timers são habilitados após o reset. Esses módulos têm como clock o sinal SYSCLKOUT, isto é, o clock da CPU. A cada pulso de clock o registrador contador é decrementado. Além dos contadores de 32 bits, é possível, via configuração, dividir o clock de entrada, alterando o comportamento do módulo em função dos pulsos de clock. Outra função é o carregamento automático do registrador contador após um estouro.

Interrupções

Os três timers podem gerar sinais de interrupção. O timer 0 tem o sinal de interrupção conectado ao bloco PIE, enquanto os outros 2 são conectados aos canais INT13 e INT14. Isso é ilustrado na Figura 2.

CPU Timers e seus respectivos sinais de interrupção.
Figura 2: CPU Timers e seus respectivos sinais de interrupção.

Para o timer 0 é necessário especificar a fonte de interrupção selecionada para o sinal INT1. Isso é realizado no registrador PIEIER1. Como mostrado na Figura 3, o Timer 0 corresponde à fonte de interrupção 7 (bit 6) de INT1.

Tabela de interrupções do PIE.
Figura 3: Tabela de interrupções do PIE.

Registradores de controle

A operação do timer é controlada pelo registrador TIMERxTCR (Figura 4). Para desativar o timer é necessário alterar o bit TSS, definindo seu valor igual a 1. O bit TRB é responsável por ativar o recarregamento automático do registrador TIMERxTPR e TIMERxPRD. Além disso, o bit TIE habilita a geração de sinal de interrupção quando o contador é decrementado até zero. A flag que indica a ocorrência desse evento é denominada TIF. Os bits FREE e SOFT determinam o comportamento do timer quando o mesmo está em depuração.

Registrador de controle TCR
Figura 4: Registrador de controle TCR

O registrador TIMERxTPR é dividido em duas partes: PSC (bits 15~8, CPU-Timer Prescale Counter) e TDDR (bits 7~0, CPU-Timer Divide-Down). O TDDR contém a quantidade de pulsos de clock necessários para que o contador seja decrementado. Assim, o PSC é decrementado a cada pulso de SYSCLKOUT, quando é igual a zero, um pulso é gerado para decrementar o contador de 32 bits (TIMERxTIM/TIMH). Os registradores de controle de todos os timers são mostrados na Figura 5.

Registradores de controle.
Figura 5: Registradores de controle.

Exemplo de aplicação

O exemplo a seguir configura o timer 0 para gerar interrupções a cada 1 ms. Para isso, os registradores TIMER0PRD/PRDH foram configurados com a quantidade de pulsos necessários para atender o período especificado. Assim, considerando clock de 150MHz e o timer0 sem divisor de clock, são necessários 150MHz/1000Hz pulsos para contabilizar 1 ms. Quando o contador chega a zero, uma interrupção é gerada. Para tal, o vetor de interrupção do timer zero (localizado no endereço 0xD4C) foi configurado com o endereço da rotina de interrupção INT1_ISR. Além dessas configurações, o canal INT1 foi configurado para selecionar a fonte de interrupção INT1.7. Isso foi configurado no registrador PIEIER1.

Obs: Programa criado no CCSv7 (CCS Project – Empty ), usando o compilador TI v17.3.0.STS.

/*Registrador de controle do watchdog timer*/
#define WDCR (*(volatile unsigned int *)0x007029)

/*Reigstrador de */
#define PLLCR (*(volatile unsigned int *)0x007021)

/*Registrador que define a direção dos pinos do GPIOA*/
#define GPADIR (*(volatile unsigned int *)0x0070C1)

/*Registrador de estados do GPIOA*/
#define GPADAT (*(volatile unsigned int *)0x0070E0)

/*Reigistrador do controlador de interrupções*/
#define PIECRTL (*(volatile unsigned int *)0x00000CE0)

/*Registrador de ACK das interrupções*/
#define PIEACK (*(volatile unsigned int *)0x00000CE1)

/*Registrador de controle da fonte de interrupção INT1*/
#define PIEIER1 (*(volatile unsigned int *)0x00000CE2)


#define TIMER0TIM (*(volatile unsigned int *)0x00000C00)  /*Timer 0, Counter Register Low*/
#define TIMER0TIMH (*(volatile unsigned int *)0x00000C01)  /*Timer 0, Counter Register High*/
#define TIMER0PRD (*(volatile unsigned int *)0x00000C02)  /*Timer 0, Period Register Low*/
#define TIMER0PRDH (*(volatile unsigned int *)0x00000C03)  /*Timer 0, Period Register High*/
#define TIMER0TCR (*(volatile unsigned int *)0x00000C04)  /*Timer 0, Control Register*/
#define TIMER0TPR (*(volatile unsigned int *)0x00000C06)  /*Timer 0, Prescaler Register*/
#define TIMER0TPRH (*(volatile unsigned int *)0x00000C07) /**/


/*Endereço do vetor de interrupção XINT1 do PIE*/
#define INT1_ADDR (*(volatile unsigned long *)0x00000D4C)

/*Rotina de interrupção*/
interrupt void INT1_ISR(void);

#define F_IN 150000000 //150 MHz
#define F_OUT 1000 //1kHz
#define PRD ((long)(F_IN / F_OUT))

int main(void) {
    /*Habilita acesso aos registradores e ao vetor de interrupção do PIE*/
    asm(" EALLOW");

    /*bit 3~0: seleção de clock -> valor 10, CLKIN = (OSCCLK * 10.0)/2 = 150MHz*/
    PLLCR = 10;

    /* Desativa o watchdog timer
     * WDDIS: bit 6: bit de enable
     * WDCHK: bit 5~3: necessário escrever o valor 5*/
    WDCR = (1 << 6) | (5 << 3);

    /*Configura os GPIOAL como saída*/
    GPADIR = 0x00FF;

    /*Preenche o vetor de interrupção XINT1 com o endereço da rotina que será utilizada*/
    INT1_ADDR = (unsigned long)INT1_ISR;

    /*Ativa região protegida*/
    asm(" EDIS");


    /*Seleciona canal de interrupção INT1.7*/
    PIEIER1 = (1 << 6);

    /*Define que os vetores de interrupção são definidos no bloco PIE*/
    PIECRTL = 1;

    /*Habilita fonte de interrupção INT1*/
    asm(" OR IER,#1");

    /*Habilita interrupções*/
    asm(" CLRC INTM");

    /*TIE: bit 4 - pausa o timer
     */
    TIMER0TCR = (1 << 4);

    /*zera os contadores*/
    TIMER0TIM = 0;
    TIMER0TPR = 0;
    TIMER0TPRH = 0;

    /*configura o registrador que determina a quantidade de pulsos contados*/
    TIMER0PRD = (unsigned int)PRD;
    TIMER0PRDH = (unsigned int)(PRD >> 16);

    /* TIF: bit 15 - flag de interrupção (necessário escrever 1 para zerar a flag)
     * TIE: bit 14 - habilita a interrupção do timer
     * SOFT-FREE: bit 11~10 - modo free-run
     * TRB: bit 5: carregamento automático
     * */
    TIMER0TCR |= (1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 5);

    /*ativa o timer*/
    TIMER0TCR &= ~(1 << 4);


    while(1)
    {

    }
}

interrupt void INT1_ISR(void)
{
    static int cont = 0;

    /*zera flag de interrupção*/
    TIMER0TCR |= (1 << 15);

    /*Determina que a interrupção foi atendida*/
    PIEACK = 1;

    if(cont == 0)
        cont = 1;
    else
        cont = 0;

    /*escreve o valor do contador no GPIOA*/
    GPADAT = cont;
}

Referências

TMS320F2812 – 32-bit Digital Signal Controller with Flash

DSP TMS320F2812

Entradas e Saídas Digitais do DSP TMS320F2812
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Hardware » DSP » Timers do DSP TMS320F2812

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: