Página 1 de 1

Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 10:58
por Rickmascar
Minhas interrupções no programa a seguir não esta funcionando....Preciso de ajuda o mais rápido, pois preciso entregar esse meu projeto ...

Código: Selecionar todos
//Definicoes de Entrada
#define TIME_DELAY 8500
#define BT_INC PORTC.B4
#define BT_DEC PORTC.B3
#define BT_START PORTC.B2
#define BT_MPROG PORTC.B1
#define BT_SEL PORTC.B0

int varsaida;

void inint();
void interrupt();


void main() {

     // INICIALiZaNDO O PIC
     ADCON0 = 0;        // Desabilita Entradas analógicas
     CMCON  = 0x07;     // Desabilita comparadores.

     inint();      //Preparando a configuração das interrupções.
     PORTB = 0xFF;
     TRISB = 0xff;
     while (1)
     {
            if (varsaida ==1) PORTB.B1 =1 ;
            else PORTB.B1 =0;
     }
}

void inint() // configura interrupcao por TIMER1 a cada 10ms. Ele faz uma checagem no botão.
{

       // ANTES DE HABILITAR A INTERRUPÇAO OS REGISTRADORES DE FLAG E
                           // INTCON = INTERRUPT CONTROL REGISTER.
                           // Registador que habilita quem chamara a interrupcao.
       INTCON.GIE = 1;     // HABILITA INTERRUPCAO GERAL
       INTCON.PEIE =1;     // HABILITA INTERRUPCAO PELOS PERIFERICOS. "TIMER1" É UM PERIFERICO.

       PIE1.TMR1IE = 1;    // TMR1IE = 1. Habilita interrupção pelo OVERFLOW DO Timer1.
       T1CON.T1CKPS1 = 0;  // T1CKPS1 = "0" ; T1CKPS0 = "0";  DIV / 1 Pode ser dividio por 1 2 4 ou 8. Verificar no datasheet
       T1CON.T1CKPS0 = 0;
       T1CON.TMR1CS = 0;    // "0" Clock interno, modo TIMER (FOSC/4)
       TMR1H = 0x8A;        // MSB  => 35536 = 10ms. = 0x8AD0    => 65536-  ( tempodesejado / ( 1/(Fosc/4) ) ).
       TMR1L = 0xD0;        // LSB  => Tempo para cristal de 12MHZ  65536 - ( 10ms / (   1 / (12Mhz/4) ) ) .
                            // P1R1 = Interrupt Service Routine.
       PIR1.TMR1IF = 0;     // Zera flag do Overflow do TIMER1. TEM QUE ZERAR.
       T1CON.TMR1ON = 1;    // TMR1ON = 1 LIGA O TIMER.

}

// No mikroc todas as rotinas para atendimento da interrupção é chamada dentro da
// funcao itnerrupt. Basta consultar o help ; D para entender.
void interrupt()
{
       if(PIR1.TMR1IF == 1)        // SE HOUVE INTERRUPCAO do timer 1 faça: .
       {
               PIR1.TMR1IF = 0;    //TMR1IF = 0 Zera o FLAG de Overflow do Timer1.
                                   // Recarrega valores
               TMR1H = 0x8A;       // MSB   35536 = 10ms. = 0x8AD0 =>  65536 - ( tempodesejado / ( 1/(Fosc/4) ) ).
               TMR1L = 0xD0;       // LSB                          => 65536 - ( 10ms / (   1 / (12Mhz/4) ) ) .

               if (varsaida == 1) varsaida =0;
               else varsaida = 1;

       }
}


Bom a interrupção não esta atuando na saída B1 como eu quero.... Preciso de ajuda pra resolver esse programa

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 11:31
por ze2
desculpe por não responder rápido. portanto leia devagar
tente:
TRISB=0x00;

Uma taquigrafia (agora sim pode ler rápido) para inverter na interrupt

varsaida^=1; //varsaida pode ser variável tipo bit. "Basta consultar o help ; D para entender."

no main pode fazer

PORTB.B1=varsaida

abç

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 14:28
por Rickmascar
bom mais oq esta acontecendo, é que eu tenho impressão que minha rotina pra atender a interrupção não esta sendo chamada :cry:

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 14:49
por andre_luis
Você precisa informar com qual compilador C está trabalhando...



+++

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 14:52
por ze2
ta com cara de mikroc

ok. pensei que estivesse avaliando apenas pelo pino.
pra teste, voce pode tirar a condição
"if(PIR1.TMR1IF == 1) // SE HOUVE INTERRUPCAO do timer 1 faça: ."
isso deixará a interrupt exclusiva pro timer... nadaver mas quem sabe...
voce pode também avaliar pelo mplab. importe o hex, rode e verifique o setup dos bits. pode até analisar graficamente o sinal do pino. veja se seu compilador gera arquivo .cof. (me lembro vagamente de um tal de coffmaker ou seilá) com ele voce pode simular passo a passo no proteus
abç

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 15:10
por Rickmascar
Sim é mikro C ... consegui resolver meu problema era apenas a conta que eu estava fazendo erado... dem uma olhada como ficou funcionando.
Código: Selecionar todos
//Definicoes de Entrada
#define TIME_DELAY 8500
#define BT_INC PORTC.B4
#define BT_DEC PORTC.B3
#define BT_START PORTC.B2
#define BT_MPROG PORTC.B1
#define BT_SEL PORTC.B0

bit varsaida;

void inint();
void interrupt();


void main() {

     // INICIALiZaNDO O PIC
     ADCON0 = 0;        // Desabilita Entradas analógicas
     CMCON  = 0x07;     // Desabilita comparadores.

     inint();      //Preparando a configuração das interrupções.
     PORTB = 0xFF;
     TRISB = 0x00;
     PORTB.B1=varsaida;
     while (1)
     {
            if (varsaida ==1) PORTB.B1 =1 ;
            else PORTB.B1 =0;
     }
}

void inint() // configura interrupcao por TIMER1 a cada 10ms. Ele faz uma checagem no botão.
{

       // ANTES DE HABILITAR A INTERRUPÇAO OS REGISTRADORES DE FLAG E
                           // INTCON = INTERRUPT CONTROL REGISTER.
                           // Registador que habilita quem chamara a interrupcao.
       INTCON.GIE = 1;     // HABILITA INTERRUPCAO GERAL
       INTCON.PEIE =1;     // HABILITA INTERRUPCAO PELOS PERIFERICOS. "TIMER1" É UM PERIFERICO.

       PIE1.TMR1IE = 1;    // TMR1IE = 1. Habilita interrupção pelo OVERFLOW DO Timer1.
       T1CON.T1CKPS1 = 0;  // T1CKPS1 = "0" ; T1CKPS0 = "0";  DIV / 1 Pode ser dividio por 1 2 4 ou 8. Verificar no datasheet
       T1CON.T1CKPS0 = 0;
       T1CON.TMR1CS = 0;    // "0" Clock interno, modo TIMER (FOSC/4)
       TMR1H = 0xB1;        // MSB  => 35536 = 10ms. = 0x8AD0    => 65536-  ( tempodesejado / ( 1/(Fosc/4) ) ).
       TMR1L = 0xE7;        // LSB  => Tempo para cristal de 12MHZ  65536 - ( 10ms / (   1 / (8Mhz/4) ) ) .
                            // P1R1 = Interrupt Service Routine.
       PIR1.TMR1IF = 0;     // Zera flag do Overflow do TIMER1. TEM QUE ZERAR.
       T1CON.TMR1ON = 1;    // TMR1ON = 1 LIGA O TIMER.

}

// No mikroc todas as rotinas para atendimento da interrupção é chamada dentro da
// funcao itnerrupt. Basta consultar o help ; D para entender.
void interrupt()
{
       if(PIR1.TMR1IF == 1)        // SE HOUVE INTERRUPCAO do timer 1 faça: .
       {
               PIR1.TMR1IF = 0;    //TMR1IF = 0 Zera o FLAG de Overflow do Timer1.
                                   // Recarrega valores
               TMR1H = 0xB1;       // MSB   35536 = 10ms. = 0x8AD0 =>  65536 - ( tempodesejado / ( 1/(Fosc/4) ) ).
               TMR1L = 0xE7;       // LSB                          => 65536 - ( 10ms / (   1 / (8Mhz/4) ) ) .

              varsaida^=1;

       }
}

Re: Chamar de INTERRUPÇÃO por TIMER1... No PIC16F877A

MensagemEnviado: 22 Abr 2014 15:55
por ze2
kibon
voce pode fazer dentro do loop
while (1)
{
PORTB.B1 = varsaida ;
}
é a lesma lerda mas...

ah... quase ia esquecendo.... que falha a minha...de nada por... nada...