Ir ao conteúdo
  • Cadastre-se

Temporização de 1us com ATMEGA328P usando AVR.


Posts recomendados

  • Membro VIP

Poderia usar T0 e T1 em conjunto.

Config Timer1 = Counter , Prescale = 1
On Ovf1 Int_timer1
Enable Ovf1

Enable interrupts.

_timer0:
Tccr0a.wgm01 = 1 : Tccr0a.wgm00 = 0                                             ' CTC
Tccr0a.com0a1 = 0 : Tccr0a.com0a0 = 1                                           'Toggle on Compare Match
Tccr0b.cs02 = 0 : Tccr0b.cs01 = 0 : Tccr0b.cs00 = 1                             'clock/2 = 8MHz
Ocr0a = 0
'****************************************************************************************************************

ATmega8, 88, 168 e 328 pinos 12 e 11 juntos... OC0A e T1 respectivamente.

Link para o comentário
Compartilhar em outros sites

Boa noite amigos, então ontem de noite consegui fazer funcionar da maneira que eu queria o projeto, vou deixar o código logo a baixo pra futuras referencias. Mas o que ocorreu foi o seguinte, eu estava errando em habilitar e desabilitar a interrupção por timer para conseguir controlar o tempo de disparo desta interrupção. O que eu deveria ter feito desde o inicio era dar um stop logo após entrar na interrupção do timer e um start logo após entrar na interrupção externa.

 

Mas depois que descobri isso fiquei quebrando a cabeça para encontrar os bit responsável por isso, e para minha surpresa no datasheet do atmega328 não consta nada disso detalhado em texto, apenas encontramos essa informação em uma unica linha da tabela do registrador TCCR1B e os bits responsáveis por esse start e stop são os CS2:0.

 

E como funciona isso, é simples quando você quer dar um stop no timer1 você deixar todos os bits CS2:0 em zero, e quando você quer reiniciar a contagem você seta o preescaler que deseja. Fácil néeeee e para encontrar esse macete, tremenda sacagem kkkkkkk, segue a tabela aonde encontrei a informação.

 

597a86a22d0be_stopstart.png.6ec6abd3375d7357acb08d742e01942e.png

 

Agora segue um código que fiz para testar isso.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define F_CPU 16000000UL

int Tempo = 1000;

volatile char msbyte = 0;
volatile char lsbyte = 0;

void config_uC(){                               //Configuração das portas do uC

    DDRC |= (1<<PC0)|(1<<PC1);
    PORTC = 0x00;

    DDRD |= (1<<PD2);
    PORTD &= ~(1<<PD2);

}

void config_interrupt(){                        //Configuração da interrupção externa PD3/INT0

    cli();

    EICRA |= (1<<ISC10)|(1<<ISC11);
    EIMSK |= (1<<INT1);

    sei();

}

void config_interrupt_timer(){

    cli();

    TCCR1A = 0x00;
    TCCR1B = (1<<WGM12)|(1<<CS11);
    OCR1A = 8000;
    TIMSK1 |= (1<<OCIE1A);

    sei();

}

ISR(INT1_vect){

    PORTC ^= (1<<PC0);

    OCR1AH = msbyte;                            //Transfere os bits mais significativos do tempo calculado
    OCR1AL = lsbyte;                            //Transfere os bits menos significativos do tempo calculado

    PORTD &= ~(1<<PD2);
    PORTC &= ~(1<<PC1);

    TCCR1B |= (1<<CS11);						//START

}

ISR(TIMER1_COMPA_vect){

    TCCR1B &= ~(1<<CS11);						//STOP
    PORTD |= (1<<PD2);
    PORTC |= (1<<PC1);

}

int main(void){

    config_uC();
    config_interrupt();
    config_interrupt_timer();

    while(1){

        msbyte = (Tempo & 0xFF00) >> 8;         //Separa dos bits mais significativos do tempo
        lsbyte = Tempo;                         //Separa dos bits menos significativos do tempo

        Tempo = Tempo + 1000;

        if(Tempo > 16000) Tempo = 1000;

        _delay_ms(5000);

    }

}

Esse programa sincroniza com a rede elétrica  e faz os disparar a interrupção do timer dentro do período entre uma interrupção externa e outra, alterando o tempo de disparo a cada 5 segundos, incrementando 500us até chegar a 8ms. Depois reinicia o ciclo.

 

Queria agradecer a todos e me ajudaram neste problema.

 

Att Thiago.

 

Link para o comentário
Compartilhar em outros sites

Parabéns por ter conseguido vencer teu desafio de programação quase que sozinho ^^ Acredite o datasheet do arduino é um dos mais detalhados que já vi, só vi* um mais detalhado que ele... apesar da minha pouca experiência na área, já que só por esses tempo decidi me envolver mais com a área que estou fazendo faculdade...

 

Arduino tem exemplo para tudo na net... agora se for atrás tem outros micro controladores por aí tem datasheets ridiculamente básicos, não explicam quase nada como fazer funcionar algo mais avançado... você tem que ficar fazendo esse joguinho de testar registradores... Afinal o Arduino é baseado em exemplos ^^

 

Enfim... já está melhor que eu, bons projetos futuros.

Link para o comentário
Compartilhar em outros sites

Um Atmega tem dentro dele um monte de hardware, que antigamente eram feitos por vários CI's auxiliares.

 

Por exemplo, a famosa família Z80A, que precisava dos auxiliares Z-80 PIO, Z-80 CTC e Z-80 SIO para termos os hardwares mais comuns hoje usados DENTRO de um Atmega !

 

Experimentem procurar os datasheets desses carinhas aí ...... é tanto detalhamento que deixava a gente louco.....

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...