Guia CNC Brasil - Tudo sobre CNC, Router, Laser, Torno e 3D Print

ELETRÔNICA / ELÉTRICA => Eletrônica Básica => Microcontroladores => Tópico iniciado por: robsonyuri em 26 de Setembro de 2010, 18:23

Título: Como usar dois timers no Pic 16F877A
Enviado por: robsonyuri em 26 de Setembro de 2010, 18:23
Olá amigos, estou iniciando em programação de MCU PIC, e tenho uma dúvida.
Tentei fazer uma interrupção usando o TMR0 e TMR1 para e somente o timer 0 esta atuando, segue o meu código em C (compilador CCS), gostaria de saber onde errei e como posso fazer para corrigir.
Abraços.
/* acende leds usando TMR0 E TMR1 */

#include<16F877A.h>
#use delay(clock=8000000)
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#INT_TIMER0 // timer 0 interrupção
#INT_TIMER1 // timer 1 interrupção
//** trata timer 0 ***///
void Exception_T0(){
   static boolean led;
   static int conta;
   SET_TIMER0(61-GET_TIMER0());
   conta++;
if(conta == 4){
      conta=0;
      led = !led;
      output_bit(pin_d7, led);
}
}
//*** TRATA TIMER 1 ***//
   void Exception_T1(){ //trata evento
   static boolean led1;   
   static int conta1;
   SET_TIMER1(3036-GET_TIMER1());
   conta1++;
   if(conta1 == 2){
   conta1 = 0;
   led1 = !led1;
   output_bit(pin_d0, led1);
}
}
void main(){
//*timer 0*//
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256);
SET_TIMER0(61);
ENABLE_INTERRUPTS(GLOBAL);
ENABLE_INTERRUPTS(INT_TIMER0);

//*timer 1*/
   SET_TIMER1(3036);
   SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
   ENABLE_INTERRUPTS(INT_TIMER1);
   

while(true) //Loop principal
{
}// fim while
}// fim main
Título: Re: Como usar dois timers no Pic 16F877A
Enviado por: Beto_s em 27 de Setembro de 2010, 02:30
Não manjo de CCS , só ASM e MikroC , mas vamos dar aquele chute....

Citar
//*timer 1*/
   SET_TIMER1(3036);
   SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
   ENABLE_INTERRUPTS(INT_TIMER1);
   

while(true) //Loop principal
{
}// fim while
}// fim main

tentaria inverter dessa maneira , primeiro configurando o timer 1 , depois colocando a constante
//*timer 1*/
   SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
   SET_TIMER1(3036);
             ENABLE_INTERRUPTS(INT_TIMER1);

Da mesma maneira que vc fez no timer0

É só um chute....

Outra detalhe que não achei no seu programa é a definição do port D como saída .

TRISD= 0x00  ( se todo o port for saida ) . Não sei como define no CCS ...

Boa sorte !



Título: Re: Como usar dois timers no Pic 16F877A
Enviado por: robsonyuri em 27 de Setembro de 2010, 07:56
Olá, a definição do portD foi feita somente nos pinos RD0 e RD7 pelo uso da diretiva output_bit(PIN_Dx, var);
Esta diretiva vai colocar o Pino em alta.
No caso invertendo, foi o que fiz na primeira tentavia, ai o que ocorre, o TMR1 funciona e o TMR0 não. Se colocar o TMR0 primeiro funciona o 0 e o 1 para.

Eu acabei resolvendo desta forma veja:
/* acende leds usando TMR0 E TMR1
   LED 1 pin_d0 LED 8 pin_d7 */
#include<16F877A.h>
#use delay(clock=8000000)
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP

int i,j;

#define LED PIN_D0 // define o led 1 no pino RD0 como saída
#define OSC PIN_D7 // define o led 8 no pino RD7 como saída

#define ON   output_high // coloca em alta
#define OFF  output_low  // coloca em baixa

#INT_TIMER0 // inicializa a interrupção do timer 0
void tempo() // função
   {
static int conta; //define variável conta como estática e inteiro
   set_timer0(61-GET_TIMER0());
conta++;
if (conta == 40){//se for = a 40
conta = 0; //zera e inicia o if aninhado
   if (i == 0){ //faz o flipflop
      i = 1;
      ON(OSC);
      }
   else {
    OFF(OSC);
   i = 0;
   }   
}
      }
   
#INT_TIMER1 //inicializa a interrupção do timer 1
void temp1() // função do timer 1
   {
     static int conta1;
   SET_TIMER1(3036-GET_TIMER1());
   conta1++;
   if(conta1 == 2){//se for igual a 2 inicia
conta1=0; //zera o contador
      if (j == 0){ //faz o flipflop
      j = 1;
      ON(LED);
      }
   else {
    OFF(LED);
    j = 0;
   } 
 }
}

void main(){

    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); //prescaler 256
    enable_interrupts(INT_TIMER0); //habilita interrupção timer 0

    setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //prescaler 8
    enable_interrupts(INT_TIMER1); //habilita interrupção timer 1
    set_timer1(3036);             

    enable_interrupts(GLOBAL); //habilita o global para interrupções funcionarem

    OFF(LED); //inicia em baixa led1
    OFF(OSC); //inicia em baixa led8

    while(true); //enquanto condição for verdadeira.

 
Título: Re: Como usar dois timers no Pic 16F877A
Enviado por: minilathe em 27 de Setembro de 2010, 10:45
Robson,

Resolveu?

A habilitação de flag de interrupções (GLOBAL) só deve ser feita após ajustar os parâmetros do TIMER0, TIMER1.

Abraços,
Título: Re: Como usar dois timers no Pic 16F877A
Enviado por: robsonyuri em 29 de Setembro de 2010, 18:37
Resolvi sim Gil, obrigado.