Autor Tópico: Como usar dois timers no Pic 16F877A  (Lida 7780 vezes)

Description:

0 Membros e 1 Visitante estão vendo este tópico.

Offline robsonyuri

  • Novato
  • *
  • Posts: 5
  • Sexo: Masculino
    • Planeta Mecânico
Como usar dois timers no Pic 16F877A
« Online: 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

Offline Beto_s

  • Hobby
  • ****
  • Posts: 284
  • Sexo: Masculino
  • Cidade - UF: S.José dos Pinhais-PR
  • Nome:: Alberto
  • Profissão: Téc. em Eletrônica
Re: Como usar dois timers no Pic 16F877A
« Resposta #1 Online: 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 !




Offline robsonyuri

  • Novato
  • *
  • Posts: 5
  • Sexo: Masculino
    • Planeta Mecânico
Re: Como usar dois timers no Pic 16F877A
« Resposta #2 Online: 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.

 

Offline minilathe

  • How to ask questions - The Smart Way...
  • Moderadores
  • CNCMASTER
  • ******
  • Posts: 4295
  • Sexo: Masculino
  • http://science-lakes.com/article43-html.html
  • Cidade - UF: Rio de Janeiro - RJ
  • Nome:: Gil Pinheiro
  • Profissão: Engenheiro e professor universitário
Re: Como usar dois timers no Pic 16F877A
« Resposta #3 Online: 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,

Offline robsonyuri

  • Novato
  • *
  • Posts: 5
  • Sexo: Masculino
    • Planeta Mecânico
Re: Como usar dois timers no Pic 16F877A
« Resposta #4 Online: 29 de Setembro de 2010, 18:37 »
Resolvi sim Gil, obrigado.

 

/** * */