TMR1 como unir TMR1H com TMR1L

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

TMR1 como unir TMR1H com TMR1L

Mensagempor alex_a » 07 Ago 2012 21:04

Estou tentando implementar um contador no pic18F87j60, usando o TIMR1.(pino RC0).
Habilitei o bit RD16 como manda o manual. Mas não consigo ler um valor de 16bits.

Tentei usar :

cont= unsigned int ReadTimer1(); // inclui o timers.h so lê 0-255.
cont=((TMR1H<<8)& 0XFF00) | (TMR1L & 0XFF); // mesma coisa.
a variável cont é de 16bits.

Alguém já implementou um contador no pic 18 com o C18 ?
Qual o jeito certo de ler estes registradores?

Agradeço qualquer ajuda.
ALEX_A
Avatar do usuário
alex_a
Bit
 
Mensagens: 43
Registrado em: 11 Out 2006 19:25
Localização: Ipiranga- São Paulo-SP

Mensagempor xultz » 07 Ago 2012 21:38

eu chuto que pode ter angu pelo fato de (quase que muito provavelmente) TMR1H ser unsigned char, bem como o TMR1L.
Exprimenta fazer typecast deles antes, por exemplo

Código: Selecionar todos

unsigned int cont;
cont = 0;
cont = (unsigned int)TMR1H;
cont = cont << 8;
cont = cont + (unsigned int)TMR1L;


Vai que funciona...
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor alex_a » 07 Ago 2012 22:12

Você tem razão xultz, os registradores são de 8 bits. mas....

Usando seu raciocínio o valor inicial mostrado foi de 14080,deveria ser 0.

Quando uso , cont=(unsigned int) ReadTimer1(); o valor inicia com 14080,deveria ser 0.


Quando uso , cont=(unsigned char) ReadTimer1(); o valor vai de 0 a 255.
cont=((TMR1H <<8) & 0XFF00) | (TMR1L & 0XFF); mesma coisa.

A parte baixa (TMR1L) consigo ler mas a parte alta (TMR1H) não.
ALEX_A
Avatar do usuário
alex_a
Bit
 
Mensagens: 43
Registrado em: 11 Out 2006 19:25
Localização: Ipiranga- São Paulo-SP

Mensagempor alex_a » 07 Ago 2012 22:12

Você tem razão xultz, os registradores são de 8 bits. mas....

Usando seu raciocínio o valor inicial mostrado foi de 14080,deveria ser 0.

Quando uso , cont=(unsigned int) ReadTimer1(); o valor inicia com 14080,deveria ser 0.


Quando uso , cont=(unsigned char) ReadTimer1(); o valor vai de 0 a 255.
cont=((TMR1H <<8) & 0XFF00) | (TMR1L & 0XFF); mesma coisa.

A parte baixa (TMR1L) consigo ler mas a parte alta (TMR1H) não.
ALEX_A
Avatar do usuário
alex_a
Bit
 
Mensagens: 43
Registrado em: 11 Out 2006 19:25
Localização: Ipiranga- São Paulo-SP

Mensagempor andre_luis » 08 Ago 2012 07:27

Seguindo o raciocínio do xultz, tenta assim :

Código: Selecionar todos
cont=((unsigned int)(TMR1H <<8) & 0XFF00) | (TMR1L & 0XFF);


Outra opção, é forçar tudo para unsigned int, e depois ir retirando o cast aos poucos para saber onde estava o erro.


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor barboza » 08 Ago 2012 08:44

Ou mesmo escrever o código separado, para "facilitar" ao compilador:

Código: Selecionar todos
cont = (TMR1H << 8);
cont &= 0xFF00; // Talvez não precise, se o deslocamento for com zeros a direita.
cont += TMR1L;
 



andre_teprom escreveu:Seguindo o raciocínio do xultz, tenta assim :

Código: Selecionar todos
cont=((unsigned int)(TMR1H <<8) & 0XFF00) | (TMR1L & 0XFF);


Outra opção, é forçar tudo para unsigned int, e depois ir retirando o cast aos poucos para saber onde estava o erro.


+++
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor ze » 08 Ago 2012 09:18

no hitech fiz com sucesso com o ad sem esta idiotice de casting
ad=ADRESH*256+ADRESL
talvez voce também possa fazê-lo no teu
cont=TMR1H*256+TMR1L
não poderia ser + simples e entendível
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor barboza » 08 Ago 2012 09:27

Cuidado para não descobrir da pior forma que casting não é idiotice...

Tomará que seu compilador seja sábio o suficiente para saber que *256 é o mesmo que <<8, pois senão a performance do seu código será uma M. Já pensou em chamar biblioteca de multiplicação dentro de uma IRQ ou FIQ?


lellis escreveu:no hitech fiz com sucesso com o ad sem esta idiotice de casting
ad=ADRESH*256+ADRESL
talvez voce também possa fazê-lo no teu
cont=TMR1H*256+TMR1L
não poderia ser + simples e entendível
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor alex_a » 08 Ago 2012 09:43

No final do dia vou poder trabalhar nisso, vou olhar o código com mais calma e usar as dicas dos amigos.

No manual do c18 fala que ao habilitar o bit RD16 e usando a função, valor= (unsigned int) ReadTimer1(); retorna o valor em 16bits.
Deve ser um detalhe bobo, estou aprendendo a usar o C18.

Valeu.
ALEX_A
Avatar do usuário
alex_a
Bit
 
Mensagens: 43
Registrado em: 11 Out 2006 19:25
Localização: Ipiranga- São Paulo-SP

Mensagempor xultz » 08 Ago 2012 10:30

Isso que dá não usar o CCS.
No CCS, se o código não funciona você tem certeza que a culpa é do compilador e xinga ele, e escreve um work around qualquer e pronto.
No C18, acha que culpa é sua, e escreve o work around achando que precisa aprender mais sobre C.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor alex_a » 08 Ago 2012 10:47

Pois é, o CCS me deixou mau acostumado. É so usar rotacao = get_timer1(); MOLEZA RSRSRS..
ALEX_A
Avatar do usuário
alex_a
Bit
 
Mensagens: 43
Registrado em: 11 Out 2006 19:25
Localização: Ipiranga- São Paulo-SP

Mensagempor ze » 08 Ago 2012 12:51

amigo barboza. forcei um pouco. troque idiotice por frescura. tenho dificuldade pra entender como o casting colaboraria da otimização do codigo mas enfim... sou burro mesmo

esta é uma opção curiosa para testar tal sabedoria. realmente isso me fez lembrar quando comecei a usar tal compilador num mc de 1k quando multiplicava/dividia por um numero diferente de 2^x não cabia e sim quando igual. Deduzi que para tal façanha ele usava inteligentemente as funções de rotate do asm. Ah sim, com algumas sacudidas coube.

Amiga alexa, sugiro que leia em paralelo o ds do teu mc. De repente o timer pode ser lido em 16 bits mesmo. Um pouco de graxa não faz mal (1/2 sem graxa esta e nem precisa entender)
abç & boa sorte
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor xultz » 08 Ago 2012 12:57

Lellis, type casting não é idiotice nem frescura. Há compiladores que tentam fazer type casting automagicamente, como no exemplo que você citou:
ad=ADRESH*256+ADRESL
se ad é int e ADRESH é char, ele fez o casting prá você. O problema é que o compilador consegue fazer isso quase sempre. Mas às vezes, ele pode não fazer o resultado ser imprevisível.
Assim, o mais adequado é nunca confiar, e fazer o type casting no código. Se o resultado é int, os operandos têm que ser int, ou convertidos prá int. O hitech fez o type casting prá você, mas colocar um cast na tua linha de código não faria o código nem maior, nem menor.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor ze » 08 Ago 2012 13:22

xuts não tinha visto por este angulo. mas creio que esta imprevisibilidade é só durante a compilação e espero que não no runtime senão tô ******.

O negoço é trabalhar com mc de 32bits pois acaba com esta frescura (acho)

Um bj amigo!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor xultz » 08 Ago 2012 14:56

Não acaba Lellis, trabalhar com variáveis de tipos diferentes e confiar no compilador é dar tiro no escuro. O ideal é ser muito rígido com esta questão. E o problema dificilmente aparece no tempo de compilação (pode ser que apareça só um warning), mas na hora de rodar, tudo pode acontecer. Um dos pepinos maiores é quando a variável estoura, e você não tem certeza de como vai se comportar (por exemplo, você acha que ela está trabalhando em 16 bits mas no fundo está em 8), e esse tipo de coisa só acontece quando o aparelho está em campo, ou fazendo manobras prá aterrissar em Marte...
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Próximo

Voltar para PIC

Quem está online

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

cron

x