Problemas de Timer0 + interrupções + velocidade I/O

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Problemas de Timer0 + interrupções + velocidade I/O

Mensagempor geraldomelo » 06 Mai 2007 04:56

Pessoal , estou com um problema meio "casca dura " aqui ..

Estou usando o Pic 16F629 , para implantar 3 pwms , mas ai , fazendo alguns testes , me deparei com alguns problemas conceituais "brabos" .. pois vamos lá ..

aqui estão os fragmentos do meu programa em CCS:

#int_timer0

void trata_t0 ()
{
short int led;
set_timer0(0);
led=!led;
pino0=led; }

Se voces observarem bem eu carrego o timer0 com 0 ou seja , já divide por 256 naturalmente , e o pino0 é minha frequencia .. até aqui ok
Ai , eu configurei o prescaler para dividir por 128 , até dividir por 2 , isso me gerou uma tabela , que eu medi os valores calculados , e medidos no frequencimetro ... ai começaram os problemas ... segue tabela de medidas :

primeiramente vou dizer como cheguei nos valores calculados

frequencia do pic 4MHZ , ..... fosc4 ... dá 1mhz ...
ai vai 1000000hz / 128 /256 = 30,5 hz , ai eu dividi por 2 novamente , para a frequencia do pino , que sobe , e desce , que ai dão os 15,3 hz , que bate com a freq. medida pelo frequencimetro no pino0

PRESCALER | FREQ> CALCULADA | FREQ MEDIDA
128 | 15,31 hz | 15,31 ---> ótimo
64 | 30,63 hz | 30,61 ---> ótimo
32 | 61,27 hz | 61,12 ---> ótimo ainda
16 | 122,55 hz | 121,8 ----> + -
8 | 245,11hz | 241 ---> péssimo [
4 | 490,23 | 477 ---> fora
2 | 980 hz | 928 nada a declarar

Bom , ai que tá , vcs perceberam a total falta de precisão , e também a total desconfiança nos calculos com a formula ? Mas ai é que tá , como pode acontecer isso ... Isso porque estamos falando em Hz ainda , nem chegamos ao Khz ... os erros estão muito grotescos .. Bom , mas para apimenta ainda mais , ai eu comecei a carregar o timer com outros valores e o prescaler sempre em div 2 , e para quanto maior a frequencia , maior ainda o erro , como indica a tabela , e mais ainda , com o timer carregado em 253 (que é o max que tá aceitando aqui ) a frequencia no pino0 também chega no máx a 9khz ( ou seja , muito baixa , e absurdamente fora dos calculos) Bom , o mais grave de tudo isso é que no AN1074 da microchip na página 3 , fala que para eu ter os intervalos de 312 uS , eu preciso configurar o prescaler para div2 , e carregar o timer em 100 ... então vamo lá outra vez:
com essas configurações vem : 312uS , são 3205hz ok ??? como isso está ligado ao pino0 , então ele tem seu ciclo de subida e descida , então 3205/2 = 1602 hz .. até qui ok ?
Agora , medindo o pino0 do pic com o freq. a frequencia apresentada é : 1460 hz ..

Bom , antes também de escrever este post , pensei que essa limitação/imprecisão do timer0 e da interrupção , estivesse ligada ao fato deles estarem ligados ao pino0 , e esta mudança de estado do pino0 fosse lenta , então fiz esse programinha para testar a velocidade da porta do pic ..
ai vai :



main()
{


trisio=0; // trisio zerado .. todos os gpios para saida
cmcon = 7 ; // todas as enradas como digitais
gpio=0; // iniciando o port gpio --> todo zerado


while (true) // enquando verdade , looping infinito
{
gpio=0; // clear byte gpio
gpio=0b00000001; // byte gpio.0 setado
gpio=0; // clear gpio
gpio=0b00000010; // gpio.1 setado
gpio=0; // clear
gpio=0b00000100; // gpio.2 setado
gpio=0; // clear
gpio=0b00010000; // gpio.4 setado
gpio=0; // clear
gpio=0b00100000; // gpio.5 setado


}

}

Agora para minha surpresa , todos os pinos ai do pic que vcs estão vendo , chegam em uma frequencia igual para todos , de incriveis 57Khz ....

Bom pessoal , agora eu perdi a fé mesmo viu .. ainda bem que o Papa tá chegando .. hehe ... mas falando sério , algum ser iluminado pderia me dar uma explicação/aula/argumento para tudo isso ... também estou rezando para eu estar errado , pois se eu não posso contar com o timer0 , pois ele não tem precisão alguma , e sobra lerdeza , ai tem que para tudo mesmo e mudar de ramo .... hehehhe

abraços a todos pessoal , e espero que me ajudem ..

Geraldo .
geraldomelo
Byte
 
Mensagens: 267
Registrado em: 14 Out 2006 16:53
Localização: Ribeirão preto - SP

Mensagempor Fábio Pereira » 07 Mai 2007 07:23

Olá Geraldo,

Me parece que você esteja desconsiderando que as instruções do PIC necessitam de um tempo (diferente de zero) para serem executadas.

Veja: com o oscilador a 4 MHz o seu ciclo de instruções será de 1us. Bem pouquinho não é ?

Parece pouco, mas veja só:

Quando o timer está configurado para dividir por 256 e com um prescaler igual a 2, teremos aproximadamente 1953 interrupções por segundo, ou seja, uma interrupção a cada 512 us.

Como você deve saber, o PIC não possui um mecanismo de interrupção vetorada, por isso, o programa deve verificar "manualmente" qual a origem da interrupção que causou o desvio para o endereço 0x0004.

Pois bem, a latência intrínseca de interrupção dos PICs é de 3 ciclos de instrução (para interrupções síncronas como a do timer 0): some + 3 ao tempo total de processamento da interrupção.

Além da latência de entrada da interrupção, antes do efetivo processamento do comando pino0 = led, uma série de eventos deverá ocorrer:

1 - salvamento do contexto (pelo menos o registrador W e o STATUS): +3 instruções
2 - verificação da origem da interrupção (depende do número de interrupção habilitadas): no mínimo +3 ciclos de instrução
3 - apagamento do flag de interrupção do timer: +1 ciclo
4 - apagamento da contagem do timer 0: +1 ciclo
5 - a linha led = !led deve gerar as suas 5 instruções, das quais umas duas são executadas (ambas desvios): + 4 ciclos
6 - finalmente a atribuição pino0=led: + 2 ciclos

Total: +16 ciclos, ou seja, +16 us.

Assim, o tempo total para modificar o estado do seu pino 0 no exemplo citado será de 512 + 16 = 528 us, ou seja, uma freqüência no led aproximadamente igual a 946,97 Hz (contra os 976,56 Hz desejados).

Ruim ? Sim e deve piorar muito, pois quanto mais instruções e mais interrupções ativas, mais tempo você necessitará para executar o código.

Soluções:
1 - aumente a freqüência do clock da CPU (não se esqueça de refazer os seus cálculos para o timer 0);
2 - procure reduzir a latência de interrupção;
3 - utilize PWM por hardware.

Conclusão principal: nunca despreze os tempos de execução das instruções e nem a latência de interrupção, por menores que estes números sejam é muito fácil deparar-se com problemas causados por desconsiderá-los.

T+
Fábio Pereira
embeddedsystems.io
Avatar do usuário
Fábio Pereira
Word
 
Mensagens: 674
Registrado em: 16 Out 2006 09:07
Localização: Kitchener, ON

Mensagempor geraldomelo » 10 Mai 2007 00:23

Fabio Pereira , muito obrigado pela resposta ... esclareceu muito .. foi por ai mesmo ....

Estou testando agora interrupção com tratamento manual , como vc descreve em seu livro ... melhorou demais , esta bem mais próximo da "realidade" ... na verdade , a interrupção automatica do CCs , estava clococando 60 e poucas instruções a mais nos meus calculos originais ... dai essa diferença toda ... computando essas 60epoucas instruções a mais no código , ai sim eu tenho os valores obtidos na minha tabela ..

Fabio , obrigado mais uma vez ..

abraços

Geraldo .
geraldomelo
Byte
 
Mensagens: 267
Registrado em: 14 Out 2006 16:53
Localização: Ribeirão preto - SP


Voltar para PIC

Quem está online

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

x