Proteus - Timer0 no MikroC - 16f84a

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Proteus - Timer0 no MikroC - 16f84a

Mensagempor hemasc » 05 Out 2009 16:08

Galera, fiz uns testes no Proteus e funcionaram direitinho, mas quando tentei simular o Timer0, o tempo que calculei não ficou compatível, era para inverter o estado da porta B0 a cada 1 seg. Ah, e o LED acende e nunca mais apaga hehehe
abaixo está o programa

Com o TMR0 começando a contar do 156 até o 256. Lembrando que o prescaler é de 1:1, então o calculo fica assim:

Valor inicial do TMR0 = 256 – 100 = 156
Calculando o tempo do timer0 x prescaler = tempo do estouro do timer0
Tempo do timer0 = 100
prescaler = 1
Tempo do estouro do timer0 = 100 x 1 = 100us
Tempo do estouro do timer0 = 100us
Valor do cont = (1s/ 100us) = (1000000us/100us) = 10000
cont = 10000

não acredito que tenha errado no cálculo, mas sei lá
por não apagar o led, acho que não estou ressetando o timer...
seria erro meu ou bug do proteus/mikroC? (prefiro ficar com a primeira opção)


int cont = 0;

void interrupt ( ) //rotina de interrupção
{
cont++; //incrementa o valor de cont a cada interrupção
TMR0 = 156; //Valor inicial para o Timer0, conta de 156 a 256
INTCON = 0x20; //Configura T0IE e limpa T0IF, em bin 0b00100000
}

void main ( )
{
OPTION_REG = 0x80; //Atribui prescaler de 1:1 ao TMR0
TMR0 = 156; //Valor inicial para o Timer0
INTCON = 0xA0; //habil. interrup. TMR0 e conf. os reg. GIE e T0IE

TRISB = 0b0; //configura o pino B0 como saída
PORTB = 0b0; //desliga o pino B0, LED apagado

cont = 0;

while(1)
{
if(cont >= 10000)
{
portb.f0 = ~ portb.f0; //inverte o estado do pino B0
cont = 0;
}
}
}

detalhe: nunca fiz na prática...
hemasc
Nibble
 
Mensagens: 80
Registrado em: 26 Fev 2007 08:59
Localização: Campinas - SP

Mensagempor r.bertini » 05 Out 2009 19:22

Você tem que limpar o flag de estouro do TMR0.

Código: Selecionar todos
int cont = 0;

void interrupt ( ) //rotina de interrupção
{
cont++; //incrementa o valor de cont a cada interrupção
TMR0 = 156; //Valor inicial para o Timer0, conta de 156 a 256
INTCON = 0x20; //Configura T0IE e limpa T0IF, em bin 0b00100000
}

void main ( )
{
OPTION_REG = 0x80; //Atribui prescaler de 1:1 ao TMR0
TMR0 = 156; //Valor inicial para o Timer0
INTCON = 0xA0; //habil. interrup. TMR0 e conf. os reg. GIE e T0IE

TRISB = 0b0; //configura o pino B0 como saída
PORTB = 0b0; //desliga o pino B0, LED apagado

cont = 0;

while(1)
{
if(cont >= 10000)
{
portb.f0 = ~ portb.f0; //inverte o estado do pino B0
cont = 0;
intcon.tmr0if=0;

}
}
}


Espero que ajude.
R.Bertini
__________________________________
#include<stdio.h>
main()
{
printf("\n R.Bertini");
}
r.bertini
Bit
 
Mensagens: 28
Registrado em: 30 Ago 2008 01:43

Mensagempor hemasc » 06 Out 2009 01:01

Na rotina de interrupção, quando eu coloco

INTCON = 0x20;

acredito que esteja zerando a flag do timer0...

Se a flag não zerasse, não iria acender o led, mas ele acende, no momento errado mas acende, e o outro problema é que não apaga, pois deveria inverter o estado da porta após o timer0 estourar 10 mil vezes novamente.

Peguei um livro de PIC em assembly e parece que estou configurando tudo corretamente, mas não me sinto seguro para afirmar isso. Apesar que o livro fala de outro PIC. Existe a possibilidade da configuração do timer0 e INTCONT variar de PIC pra PIC? Sem chance né?


Por favor, me ajudem, já estou desconfiando do Proteus, rs..
ah, estou usando a versão free do MikroC, não acredito que isso influencie
hemasc
Nibble
 
Mensagens: 80
Registrado em: 26 Fev 2007 08:59
Localização: Campinas - SP

Mensagempor jorgeluiz » 06 Out 2009 01:30

dependendo do seu computador, o Proteus nao simula em tempo real. As vezes simula errado. O Pic Simulator Ide e' mais confiavel, mas tambem erra as vezes. Simuladores nao sao perfeitos. So' numa protoboard voce vai ter o resultado real.
Avatar do usuário
jorgeluiz
Byte
 
Mensagens: 448
Registrado em: 26 Mar 2007 02:26

Mensagempor fabim » 06 Out 2009 08:26

INTCON = 0x20;
sei, limpou o TMR0 IF..
Antes de sair da int, ta tendo certeza que
INTCON.GIE = 1 ?
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor hemasc » 06 Out 2009 11:02

haha, certeza só tenho que de nada tenho certeza...

modifiquei para

void interrupt ( )
{
cont++;
TMR0 = 156;
INTCON = 0xA0; //em bin10100000, ou seja... GIE =1
}

mas dá na mesma... lembrando... se fosse registradores ou timer0, nem acender iria... o problema é que ele entra no if uma vez e pelo jeito não entra mais...

vou seguir o conselho do amigo jorgeluiz e testar isso na placa e depois posto o resultado aqui, também estou com a impressão de ser o simulador...
mesmo assim, obrigado à todos pelos auxílios
hemasc
Nibble
 
Mensagens: 80
Registrado em: 26 Fev 2007 08:59
Localização: Campinas - SP

Mensagempor hemasc » 06 Out 2009 16:56

pessoal, resolvi... BUG do Proteus
usei o metodo da teimosia e resolvi fazer outro circuito... um contador de zero a nove usando timer0 e funcionou, mas apenas o tempo não é simulado como eu gostaria, isso é o de menos

programa que fiz pra testar

int cont=0, display=0;

void interrupt ( ) //rotina de interrupção
{
cont++; //incrementa o valor de cont a cada interrupção
TMR0 = 156; //Valor inicial para o Timer0, conta de 156 a 256
INTCON = 0x20; //Configura T0IE e limpa T0IF, em bin 0b00100000
}

void main ( )
{
OPTION_REG = 0x80; //Atribui prescaler de 1:1 ao TMR0
TMR0 = 156; //Valor inicial para o Timer0
INTCON = 0xA0; //Hab. a int. do TMR0, conf. os registros GIE e T0IE

TRISB = 0b0000000;
PORTB = 0b0000000;

cont = 0;

while(1)
{
if(cont>=10000) //se cont for maior ou igual a 1000
{ display++;
cont = 0;
}
if(display==0) //zero no display
{ portb=0b0111111;
}
if(display==1) //um no display
{ portb=0b0000110;
}
if(display==2) //dois no display
{ portb=0b1011011;
}
if(display==3) //três no display
{ portb=0b1001111;
}
if(display==4)
{ portb=0b1100110;
}
if(display==5)
{ portb=0b1101101;
}
if(display==6)
{ portb=0b1111101;
}
if(display==7)
{ portb=0b0000111;
}
if(display==8)
{ portb=0b1111111;
}
if(display==9)
{ portb=0b1101111;
}
if(display>9)
{ display = 0;
}
}
}

problema resolvido
obrigado à todos pelas informações
hemasc
Nibble
 
Mensagens: 80
Registrado em: 26 Fev 2007 08:59
Localização: Campinas - SP

Mensagempor hemasc » 08 Out 2009 14:52

Consegui resolver o problema em relação ao tempo

Devido ao pipeline... 4MHz -> cada instrução leva 1us

Quando configuro OPTION_REG = 0x80; achei que estava usando o prescaler de 1:1, mas olhei no datasheet e percebi que configurado assim, o prescaler é de 1:2 ao TMR0, é só modificar isso no cálculo

Valor inicial do TMR0 = 256 – 100 = 156
Calculando o tempo do timer0 x prescaler = tempo do estouro do timer0
Tempo do timer0 = 100
prescaler = 2
Tempo do estouro do timer0 = 100 x 2 = 200us
Tempo do estouro do timer0 = 200us
Valor do cont = (1s/ 200us) = (1000000us/200us) = 5000
cont = 5000
hemasc
Nibble
 
Mensagens: 80
Registrado em: 26 Fev 2007 08:59
Localização: Campinas - SP


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x