• Welcome to LusoRobótica - Robótica em Português.
 

Routina de 1ms com o tmr0

Started by Electropepper, 02 de November de 2014, 18:20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dave

Quote from: Electropepper on 03 de November de 2014, 10:04
E tenho de ver se arranjo um oscilóscpio para tirar as teimas.

Sim... é melhor que cronometrar à mão.... muito melhor  ;D ;D
David Martins
Eng. Electrotécnica e de Computadores, UBI

Sérgio_Sena

Quote from: Electropepper on 03 de November de 2014, 10:04
Ok pessoal, já deu para tirar umas conclusões.
Usar a interrupção com apenas uma flag(state machine) a dar indicação que o timer rolou.
Ter em conta a chamada e saida para a função de delay assim como fazer o load do tmr0 com o respectivo valor.
Mais logo quando chegar a casa já esperimento isto outa vez.
E tenho de ver se arranjo um oscilóscpio para tirar as teimas.


Olha q possivelmente para trabalho digital, ha algo melhor q o osciloscopio ::  um Logic Analyzer

Tipo estes muito bons: https://www.saleae.com/  com a vantagem de agora as entradas tb medirem sinais analogicos substituindo completamente o osciloscopio e com  memoria "infinita"

Mais baratuxo tens o Bus Pirate mas c as specs muito muito abaixo.
Tambem o USBEE, mais caro q o Saleae e nao eh melhor.

Ha outros.
O meu conselho eh comecar com um Analyzer q faca analogico tb e depois se precisares de medir RF, entao outro aparelho dedicado.
E podes levar na bolsa do computador, o q nao acontece c o scope.
Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

Electropepper

Boa dica, é que eu até tenho aqui um bus pirate  :D

Electropepper

Ora já tirei umas amostras com o bus pirate, a unica consistencia é que os valores são completamente inconsistentes, talvez por causa do cristal interno.
Ora vejam :
Para este código ,

#include <pic12f1822.h>


/* Setup chip configuration */
__code int __at(_CONFIG1) __CONFIG = _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF;

void setup(void);
void delay_ms(int milis);
void minute_delay(void);


void main(void) {

    setup();


    while(1) {

        delay_ms(1);
        LATA |= (1<<2);
        delay_ms(1);
        LATA &= ~(1<<2);
    }

}

void setup(void) {

    OSCCON = 0b01011000; // 1MHZ internal clock
    LATA = 0;
    TRISA = 0x00;
    PORTA = 0x00;

__asm
cblock 0x20
d1
endc
__endasm;

}

void delay_ms(int milis) {

    while (milis--) {
    __asm
        movlw   0x51
        movwf   d1
        Delay_0:
        decfsz  d1, f
        goto    Delay_0
    __endasm;
    }
}


void minute_delay(void) {

    unsigned char minute = 60;

    while (minute--) {
    delay_ms(1000);
    }
}

O ficheiro logic_sniffer_asm.png

E para este código,

#include <pic12f1822.h>


/* Setup chip configuration */
__code int __at(_CONFIG1) __CONFIG = _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF;

void setup(void);
void delay_ms(int milis);



void main(void) {

    setup();


    while(1) {

        delay_ms(1);
        LATA |= (1<<2);
        delay_ms(1);
        LATA &= ~(1<<2);
    }

}

void setup(void) {

    OSCCON = 0b01011000; // 1MHZ internal clock
    LATA = 0;
    TRISA = 0x00;
    PORTA = 0x00;


//  Clock source selection (Fosc/4)
    TMR0CS = 0;
    PSA = 1;    // No prescaler

}

void delay_ms(int milis) {

    while (milis--) {

        TMR0 = 6;  //
        while (!TMR0IF);  //latch till 1ms interrupt happens
        TMR0IF = 0;
    }
}

O ficheiro logic_sniffer_C_no_int.png.

senso

Tanto num como noutro é normal teres essas diferenças, quando apagas o led tens mais código a ser executado para voltares ao inicio do loop while, isso leva-te a que o on/off não tenha um duty cycle de 50%, terás sempre ligeiras diferenças, no outro, isso parece-me jitter devido a caminhos de execução diferentes, tempo de entrada numa ISR e la la la, não sei se num pic é totalmente deterministico mas num AVR um salto para uma interrupção pode demorar 3 ou 4 ciclos de relógio, depende de algumas coisas.
Avr fanboy

Electropepper

Tambem me cheira a imprecisão do próprio bus pirate, afinal é um PIC e não estou a ver nenhum cristal na placa pelo que tambem deve estar a usar o cristal interno. cómico no minimo.

Sérgio_Sena

Bom, eu acho q a aproximacao ao problema estah a ser feita da maneira menos correcta.
Andas preocupado no porque das funcoes nao darem o tempo correcto, qd dever-se-ah pensar de outra maneira.

Se sabes quanto tempo demora cada instrucao a executar, entao contar instrucoes eh a melhor solucao. E ASM eh a melhor solucao p esta situacao. Uma funcao completamente TODA em ASM apenas para fazer o temporizador.

Este exemplo em ASM estah feito par aum cristal de 4MHz tendo entao um Fosc de 1MHz. No teu caso eh aumentar o teu clock soh dividir o numero multiplicado.
Experimenta. Este garanto-te que te dah 1.000ms ou 2*500us



processor 16F886 ;configura o tipo de CPU usado
radix hex ;pre-definicao do tipo de valores numericos usados

include "P16F886.inc" ;inclui pre-definicoes do processador

;---------------------------
temp equ 0x20 ;define endereco 0x20 com o nome de TEMP

;---------------------------


inicio

call atraso_500u ;chama rotina de atraso
call atraso_500u ;chama rotina de atraso

goto inicio ;faz temporizacao de novo

;---------------------------

atraso_500u
movlw 0xA5 ;carrega W com o valor 0xA5
movwf temp ;move valor em W para TEMP

decfsz temp, f ;decrementa TEMP em uma unidade, coloca resultado em TEMP
;e salta a instrucao seguinte, se o resultado for zero
goto $-1


nop
nop

return ;sai fora da rotina de ATRASO

;---------------------------
end

Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

Sérgio_Sena

Quote from: Electropepper on 03 de November de 2014, 22:40
Tambem me cheira a imprecisão do próprio bus pirate, afinal é um PIC e não estou a ver nenhum cristal na placa pelo que tambem deve estar a usar o cristal interno. cómico no minimo.


Infelizmente equipamente barato tem sempre concessoes. E os cristais bons sao caros. Um cristal barato eh igual a usar o RC interno cortado a laser q vai alterar com a tensao e a temperatura.

Tambem o compilador nao estah provavelmente a optimizar para o melhor servico (soh vendo o ASM final) logo aih tambem tem falhas.

Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

Electropepper

Bem acho que definitivamente já não vou confiar no bus pirate para isto.
Esta foi feita com o mikroC.
Mas asena uma coisa eu garanto-te de todos os métodos com o mikroC tenho o melhor resultado se não perfeito com oscilador interno.

senso

Não tens nada mais standalone?
O bus pirate está a correr montes de código enquanto está a olhar para os pinos.
Avr fanboy

Electropepper

Bem tenho oscilóscopio no trabalho, é o próximo passo.
Mas asena o teu asm está simples e eficaz, não duvido que funcione, estás-me a sugerir que escreva o código todo em asm então ?
De outra maneira não estou a ver como transporto isto para projectos maiores.

jm_araujo

Quote from: Electropepper on 03 de November de 2014, 22:22

void delay_ms(int milis) {

    while (milis--) {

        TMR0 = 6;  //
        while (!TMR0IF);  //latch till 1ms interrupt happens
        TMR0IF = 0;
    }
}


Devias ler com mais atenção o que já te disseram pelo menos o Dave (http://lusorobotica.com/index.php?topic=7725.msg86679#msg86679), o asena (http://lusorobotica.com/index.php?topic=7725.msg86685#msg86685) e também ler os vários  exemplos que deram.
Deves adicionar ao TMR0 em vez de fazer uma atribuição para diminuir o erro: usar "TMR0+=6;" em vez de "TMR0=6;". Eu próprio ia fazer essa sugestão quando eles se me adiantaram, é usada desde os tempos em que praticamente só se programava PICs em assembly (ainda não havia compiladores de C de jeito).

Enquanto não eliminares o básico vai-te ser difícil despistar se é imprecisão do oscilador ou outro fator.

Electropepper

Ok peço desculpa não prestei mesmo atenção.
Vou fazer isso.

Dave

Não quero ser chato, mas faz lá teste ao exemplo que te deixei aí de 1s...

Só mesmo para matar a curiosidade...
David Martins
Eng. Electrotécnica e de Computadores, UBI

Sérgio_Sena

Quote from: Electropepper on 03 de November de 2014, 23:06
Mas asena o teu asm está simples e eficaz, não duvido que funcione, estás-me a sugerir que escreva o código todo em asm então ?
De outra maneira não estou a ver como transporto isto para projectos maiores.

Toda nao, mas a funcao de temporizacao se nao fizeres por Interrupcoes, deverahs fazer em ASM e inxluir no teu codigo.

Nem q seja educativo, merece a pena faze-lo.
Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram