Página 1 de 1

ATmega8 Timer 1 Interrupção Dúvida???

MensagemEnviado: 21 Out 2008 21:52
por brasilma
Esta é a dúvida do colega Fabricio que esta se cadastrando no Forum.

É o seguinte, eu tenho um problema no Timer1, no CTC, em um ATmega8. Compilo meu código e simulo no AVR Studio. Até então normal, há uma interrupção e o timer reseta(CTC) exatamente aos 12M de clocks(pra dar um segundo aproximadamente, já que estou usando um cristal de 12Mhz), depois altera o estado da porta D, ligando ou desligando o led debug que eu coloquei.
Perfeito, exatamente como eu planejei. Mas o problema é quando eu gravo no meu microcontrolador, ele simplesmente não pisca o led que eu coloquei pra debug, só que, se eu desativar o CTC, e ficar só por overflow, ele pisca normalmente. Estou usando um prescaler de 256, colocando 46875 no OCR1A.
Eu até desconfiei que pudesse ser um problema do MC mesmo, então coloquei outro(eu tenho três =]), mas ainda sim o problema continua...
Aposto e ganho que deve ser uma coisa muito boba que eu não estou vendo... estou com esse problema há mais de semanas, e não descubro, já olhei o datasheet e procurei na internet em fóruns e tudo mais, no entanto não consegui nada.
Eis ai o código... se puder me ajudar, eu agradeço.
*Comentei o código como se eu estivesse mandando pra alguem que está iniciando, mas não leve a mal não, é que eu gosto de comentar bem bonitinho, pra tentar deixar bem legível e visual =]
---
.include "m8def.inc"

.def temp0 =r16

.org 0
rjmp Start

.org OC1Aaddr
in temp0,PORTD //pega valor da porta D
eor temp0,r17 //Passa no XOR pra alterar apenas o pino5, que
foi 'setado' antes no r17
out PORTD,temp0 //Manda pra porta
reti //retorna =]

Start:
//Inicia o Stack
ldi temp0,LOW(RAMEND) ; stack low
out SPL,temp0
ldi temp0,HIGH(RAMEND) ; stack high
out SPH,temp0

//Define valor do registrador OCR1A
ldi temp0,LOW(46875)
out OCR1AL,temp0
ldi temp0,HIGH(46875)
out OCR1AH,temp0

//Liga flag interrupção
ldi temp0,1< out TIMSK,temp0

//Inicia timer com prescaler 256, com CTC
ldi temp0,(1< out TCCR1B,temp0

//Liga o Sleep mode, pra ter maior precisão de tempo na
interrupção(isso aqui é dispensável pra alguns casos,
//mas coloquei porque um projeto meu de TV necessitava disso, e
talvez, por causa desse CTC não funcionou heheheh)
ldi temp0,1< out MCUCR,temp0

//Define pino do led-debug, para servir como máscara pro XOR
ldi r17,1<
sei //interrupções na ativa mano

main:
sleep //dorme com os anjinhos =]
rjmp main

MensagemEnviado: 22 Out 2008 20:08
por vohr56
Cara, Assembler não manjo nada. Se fosse em C até poderia dar alguns palpites.

Abraços.

MensagemEnviado: 22 Out 2008 21:01
por RobL
Onde está escrito:

//Liga flag interrupção
ldi temp0,1< out TIMSK,temp0

Deveria ser:
ldi temp0, 1<<OCIE1A
out TIMSK, temp0

Onde está:

//Inicia timer com prescaler 256, com CTC
ldi temp0,(1< out TCCR1B,temp0

Deveria ser:

ldi temp0, (1<<CS12 | 1<<WGM12)
out TCCR1B, temp0

Os bits do registro TCCR1A <WGM10 e WGM11> = 0 (devem ser zero)
Nota:
Não é necessário a rotina para acender o led. O AVR faz isto diretamente por uma função de porta toggle ao gerar interrupção (Toggle OC1A/OC1B on Compare Match Bit 7:6 – COM1A1:0: Compare Output Mode for channel A do registro TCCR1A).
No seu caso essa função não foi configurada. Portanto fica o serviço de interrupção escrito.

MensagemEnviado: 22 Out 2008 21:17
por brasilma
Obrigado pela força Robl, enviei a mensagem para o Fabricio, creio que logo ele estará participando direto aqui.