collapse

* Posts Recentes

TV Antiga Desliga-se por almamater
[Hoje às 12:34]


Tubo PVC 32mm Branco por SerraCabo
[10 de Agosto de 2018, 22:49]


Ajuda para contruir uma "máquina" de fisioterapia para a minha filha. por Hugu
[08 de Agosto de 2018, 00:47]


Comprar solda decente por jm_araujo
[07 de Agosto de 2018, 11:30]


Telescopio por kieferdl
[03 de Agosto de 2018, 10:10]


Com que equipamento costumam aceder ao LR? por KammutierSpule
[01 de Agosto de 2018, 10:14]


BostonDynamics - Vai uma mãozinha? por jm_araujo
[01 de Agosto de 2018, 08:29]


Baby's got blue eyes por jm_araujo
[30 de Julho de 2018, 22:55]


Queimei 1 Motor :) por SerraCabo
[30 de Julho de 2018, 22:32]


KiCad stable release 5 por KammutierSpule
[30 de Julho de 2018, 09:25]

Autor Tópico: Timer no ATMega88  (Lida 1529 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.541
  • 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.541
  • 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> :|