collapse

* Links de Robótica

* Posts Recentes

Feira de electricidade e eletrónica por artur36
[Ontem às 23:07]


Power_OK Enermax por almamater
[Ontem às 12:10]


Recomendação de um opamp para um DAC r2r por jm_araujo
[23 de Novembro de 2017, 10:48]


RN42 e TP-Link MR3020 por doiga
[22 de Novembro de 2017, 19:22]


Ajuda Projecto IR / RF por senso
[22 de Novembro de 2017, 13:15]


Ideias para construir um quadrúpede simples por dropes
[21 de Novembro de 2017, 22:43]


Ajuda com TRIAC por senso
[17 de Novembro de 2017, 18:00]


TV LG White Screen por almamater
[15 de Novembro de 2017, 08:37]


Pergunta sobre prototipagem ( Pesquisa ) por luisjustin
[14 de Novembro de 2017, 23:22]


Medir Agua que está no Poço por Njay
[14 de Novembro de 2017, 13:28]

Autor Tópico: Timer no ATMega88  (Lida 1268 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline zepedro

  • Mini Robot
  • *
  • Mensagens: 17
Timer no ATMega88
« em: 21 de Junho de 2012, 22:30 »
Olá,

estou a usar um ATMega88 e estou a tentar implementar um timer. Apesar de ter preenchido os registos todos conforme o datasheet, obtenho um erro que me faz com que o programa comece sempre de novo cada vez que a interrupção é chamada!
Sei isto porque tenho uma variavel incializada a 0 que é mostrada num LCD, e quando carrego no botão de incrementar, esta volta-me sempre a 0!

Tá aqui o código dos registos:


Código: [Seleccione]
OCR0A=250;  //*Escreve 250 no OCR0A    -   0.0321 segundos
TCCR0A=2;  //*Configuracao do TC0 para modo CTC*
TCCR0B=0b00000101;    //*Prescaler para 1024    -    1/(8*10^6/(1024*(250+1))
TIMSK0|=2;            //*Saida do TC0 compara as interrupçoes activas*
SREG|=0b10000000;


E a rotina de interrupção:

ISR(TIMER0_COMPA_vect)
{
count--;
if (count==0)
{
conv=1;

count=156;
}
}

Já aconteceu isto a alguém? Abraço.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: Timer no ATMega88
« Responder #1 em: 21 de Junho de 2012, 22:35 »
Podes mostrar o resto do código.
A variavel count está definida como volatile?
Já apanhei este tópico em mais 2 fóruns, se responderes tens mais ajuda do que espalhares a pergunta por todo o lado e mais algum  ;)
« Última modificação: 21 de Junho de 2012, 23:13 por senso »
Avr fanboy

Offline zepedro

  • Mini Robot
  • *
  • Mensagens: 17
Re: Timer no ATMega88
« Responder #2 em: 21 de Junho de 2012, 23:42 »
O código é um bocado extenso e por isso é que não colei aqui tudo! A variável count não está como volatile, mas não é essa que está a ser passada para o LCD. Aliás, se eu nem puser nada na rotina obtenho o mesmo erro!

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: Timer no ATMega88
« Responder #3 em: 21 de Junho de 2012, 23:57 »
Qualquer variavel usada numa ISR tem de ser declarada como volatile, sem o código completo não há muito mais a fazer.
E não deves mexer no SREG, usa antes o sei() para ligar interrupções e o cli() para as desligar, é muito mais seguro.
Avr fanboy

Offline zepedro

  • Mini Robot
  • *
  • Mensagens: 17
Re: Timer no ATMega88
« Responder #4 em: 22 de Junho de 2012, 00:26 »
Basta escrever "sei()" para as interrupts ficarem activas?


Cá vai código inteiro então:


Código: [Seleccione]
#define F_CPU 8000000UL

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

#include "lcd.h"
#include "ds1307.h"
#include "I2C.h"
#include "therm_ds18b20.h"


unsigned int count=156, conv=0;   //count 156*0.032s para fazermos 5 segundos

int main(void)
{
unsigned int c=10, inc=0, flag1=0;
char buffer [33];
char x[20] = {0};
uint8_t temperature[2];
int8_t digit;
uint16_t decimal;

DDRD=0b00000010; //so TX é que é saida (para ja)


OCR0A=200;  //*Escreve 250 no OCR0A    -   0.0321 segundos
TCCR0A=2;  //*Configuracao do TC0 para modo CTC*
TCCR0B=0b00000101;    //*Prescaler para 1024    -    1/(8*10^6/(1024*(250+1))
TIMSK0|=2;            //*Saida do TC0 compara as interrupçoes activas*
SREG|=0b10000000;



// Initialize my LCD display.  Uses the Fleury LCD code
lcd_init(LCD_DISP_ON);

// Clear the LCD screen
lcd_clrscr();         


  while(1)
{


inc=(PIND & 0b00100000); //conta o numero de impulsos no botao
  if (inc==0b00100000)
    flag1=0;
   if(inc==0 && flag1==0) //flag para evitar que conte mais do que um impulso no caso do botao estar activo bastante tempo activo
  {
    flag1=1;
    c++;
    }



//----------Termometro-----------------

if(conv==1)
{
therm_read_temperature2(&digit, &decimal);
conv=0;
}

//----------Apresentar-------------------

lcd_command(0b00001100); //desliga o cursor
lcd_home(); //volta com o cursor ao inicio

sprintf(buffer, "%d.%d C", digit, decimal);

lcd_puts(buffer);
 

sprintf(buffer, "\n%d",c);

lcd_puts(buffer);




}
 
return 0;
 
 }   



//*******************FIM DA MAIN********************

ISR(TIMER0_COMPA_vect)
{
count--;
if (count==0)
{
conv=1;

count=156;
}
}

Offline zepedro

  • Mini Robot
  • *
  • Mensagens: 17
Re: Timer no ATMega88
« Responder #5 em: 22 de Junho de 2012, 15:47 »
Já resolvi. Burrice minha... Tinha-me esquecido de por a biblioteca <interrupts.h> :|