CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Timer0 nor timer1 does not burst.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Timer0 nor timer1 does not burst.
PostPosted: Mon Nov 06, 2017 1:16 pm     Reply with quote

Hello friends I have a doubt in running the scan of timer0 and timer1 together. I'm setting up a home test clock, but I do not need to count the seconds, just to see it work. I am trying to use the timer0 overflow to update the displays by multiplexing and timer1 for counting seconds. However when executing the program, they do not execute the programmed overflow neither timer0 nor timer1, I tested each other separately, activating output B7. Could you help me understand why or what is wrong in the code below? Thank you. Timer0 nor timer1 does not burst.

Thank you very much..
Code:

#include <16f877a.h>
#fuses hs, nowdt, nolvp, put, brownout
#use delay(clock = 12M)

#use fast_io(b)
#use fast_io(c)


// --- Mapeamento de Hardware ---
#define dig_uni  PIN_B0                       //Dígito das unidades no RB0
#define dig_dez  PIN_B1                       //Dígito das dezenas no RB1
#define dig_cen  PIN_B2                       //Dígito das centenas no RB2
#define dig_mil  PIN_B3                       //Dígito dos milhares no RB3
#define aj_min   PIN_B4                       //Botão para ajuste dos minutos ligado em RB4
#define aj_hor   PIN_B5                       //Botão para ajuste das horas ligado em RB5



// --- Protótipo das Funções Auxiliares ---
int display(int num);                          //Exibe o valor correspondente no display de catodo comum
void relogio();                              //Função de controle do relógio


// --- Variávei Globais ---
char control = 0x01;                          //Variável de controle (para saber qual display está ativo)
 
int mil, cen, dez, uni;                      //Variáveis auxiliares para dados nos displays
char cont = 0x00;
char segundos = 0x00,                          //Variável que armazena os segundos
     minutos  = 0x00,                          //Variável que armazena os minutos
     horas    = 0x00,                          //Variável que armazena as horas
     clk_cont = 0x00;                          //Variável para controle de incremento


// --- Rotina de Interrupção ---
#int_timer0
void interuptimer0()
{
         
       set_timer0(0);
       output_toggle(PIN_B7);
             
        if(output_low (dig_mil) && control == 1)           //Dígito dos milhares desligado?
        {                                      //Variável de controle igual a 1?
           control = 0x02;                     //Sim, control recebe o valor 2
           output_low (dig_uni);               //Apaga dígito das unidades
           output_low (dig_dez);                //Apaga dígito das dezenas
           output_low (dig_cen);                     //Apaga dígito das centenas
           output_c(0x00);                     //Desliga PORTC
           mil = (horas%100)/10;               //Calcula o dígito das dezenas para exibir as horas
           output_high (dig_mil);               //Ativa dígito dos milhares
           output_c (display(mil));             //Escreve o valor no display dos milhares

        } //end if dig_mil

        else if(output_low (dig_cen) && control == 2)      //Dígito das centenas desligado?
        {                                      //Variável de controle igual a 2?
            control = 0x03;                    //Sim, control recebe o valor 3
            output_low (dig_uni);                    //Apaga o dígito das unidades
            output_low (dig_dez);                    //Apaga o dígito das dezenas
            output_low (dig_mil);                    //Apaga o dígito dos milhares
            output_c(0x00);                    //Desliga PORTC
            cen = horas%10;                    //Calcula o dígito das unidades para exibir as horas
            output_high (dig_cen);                    //Ativa dígito das centenas
            output_c (display(cen));            //Escreve o valor no display das centenas

        } //end if dig_cen

        else if(output_low(dig_dez) && control == 3)      //Dígito das dezenas desligado?
        {                                      //Variável de controle igual a 3?
            control = 0x04;                    //Sim, control recebe o valor 4
            output_low (dig_uni);                    //Apaga o dígito das unidades
            output_low (dig_cen);                    //Apaga o dígito das centenas
            output_low (dig_mil);                    //Apaga o dígito dos milhares
            output_c(0x00);                    //Desliga PORTC
            dez = (minutos%100)/10;            //Calcula o dígito das dezenas para exibir os minutos
            output_high (dig_dez);                    //Ativa dígito das dezenas
            output_c (display(dez));            //Escreve o valor no display das dezenas

        } //end if dig_dez

        else if(output_low(dig_uni) && control == 4)      //Dígito das unidades desligado?
        {                                      //Variável de controle igual a 4?
            control = 0x01;                    //Sim, control recebe o valor 1 (para encerrar a lógica)
            output_low (dig_dez);                    //Apaga o dígito das dezenas
            output_low (dig_cen);                    //Apaga o dígito das centenas
            output_low (dig_mil);                    //Apaga o dígito dos milhares
            output_c(0x00);                    //Desliga PORTC
            uni = minutos%10;                  //Calcula o dígito das unidades para exibir os minutos
            output_high (dig_uni);                    //Ativa dígito das unidades
            output_c (display(uni));            //Escreve o valor no display das unidades
        }
     
     } //end if (teste de estouro)

#int_timer1

    void interuptimer1()  //  Os segundos são incrementados a cada estouro do TMR1  Houve overflow do Timer1?
 {   
      set_timer1(0);
      cont =cont ++;
      if (cont == 3)
     {                                         //Sim...
       
       

        clk_cont++;                            //Incrementa variável de controle de tempo

        if(clk_cont == 0x05)                   //clk_cont igual a 2?
        {                                      //Sim...
           clk_cont = 0x00;                    //Reinicia clk_cont

           segundos++;                         //Incrementa segundos

        } //end if clk_cont

     } //end if Timer1

} //end interrupt



// --- Função Principal ---
void main()
{
 
 
   set_tris_b(0x70); //Configura TRISB<6 a 4> como entrada, TRISB<3:0> como saída, RB7 como saída
   set_tris_c (0x80); //Configura todo PORTC como saída, exceto RC7
 
   output_b(0x07); //Inicializa PORTB (dígitos desligados)
   output_c(0x80); //Inicializa PORTC (segmentos desligados), RC7 em nível alto
 
   port_b_pullups(true);
   
   //**** Configuracao timers
   
   SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   set_timer0(0);
   
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   set_timer1(0);
 

// -- Loop infinito --
     while(1)
     {

         relogio();                          //Chama a função de controle do Relógio
 

     } //end while


} //end main


// === Desenvolvimento das Funções Auxiliares ===

//Esta função acha o bit pertinente a cathode (matrix de bits) para ser enviado
//para o PORTC e mostrar um número no display de 7 segmentos. O número
//é passado como um parâmetro para a função.
 
 
int display(int num)
{
    int cathode;                               //armazena código BCD

// -- Vetor para o código BCD --

    int SEGMENTO[10] = {0x3F,                  //BCD zero   '0'
                        0x06,                  //BCD um     '1'
                        0x5B,                  //BCD dois   '2'
                        0x4F,                  //BCD três   '3'
                        0x66,                  //BCD quatro '4'
                        0x6D,                  //BCD cinco  '5'
                        0x7D,                  //BCD seis   '6'
                        0x07,                  //BCD sete   '7'
                        0x7F,                  //BCD oito   '8'
                        0x67};                 //BCD nove   '9'

    cathode = SEGMENTO[num];                   //para retornar o cathode

    return(cathode);                           //retorna o número BCD

} //end display


//Função destinada ao controle do Relógio
void relogio()
{
   char anti_boucyng = 0x00;                    //Variável para armazenar o estado dos botões
   
    if(segundos > 59)                          //segundos maior que 59?
    {                                          //sim...
         segundos = 0x00;                      //Reinicia segundos
         minutos++;                            //Incrementa minutos

         if(minutos > 59)                      //minutos maior que 59?
         {                                     //sim...
              minutos = 0x00;                  //Reinicia minutos
              horas++;                         //Incrementa horas

              if(horas > 23) horas = 0x00;     //Se horas maior que 23, reinicia

         } //end if minutos


    } //end if segundos

      //****Ajusta horas

    if(!input(aj_min)) bit_set(anti_boucyng,0);   //Se botão de ajuste dos minutos pressionado envia low em aj_min e seta flag 0 da variavel anti_boucyng
    if(!input(aj_hor)) bit_set(anti_boucyng,1);    //Se botão de ajuste de horas pressionado envia low em aj_hor e seta flag 1 da variavel anti_boucyng
   
    if(input(aj_min) && bit_test(anti_boucyng,0))  //Se Botão de ajuste de minutos solto envia hight a aj_min e flag 0 de anti_boucyng==1?
    {                                          //Sim...
      bit_clear(anti_boucyng,0);                        //Limpa flag0
       minutos++;                              //Incrementa minutos

       if(minutos > 59) minutos = 0x00;        //Se minutos maior que 59, reinicia

    } //end if b_min


    if(input(aj_hor) && bit_test(anti_boucyng,1))     //Botão de ajuste das horas solto envia hight a aj_hor e flag 1 de anti_boucyng setada?
    {                                          //Sim...
       bit_clear(anti_boucyng,1);                       //Limpa flag1
       horas++;                                //Incrementa horas

       if(horas > 23) horas = 0x00;            //Se horas maior que 23, reinicia

    } //end if b_hor


} //end clock_PIC
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Nov 06, 2017 1:32 pm     Reply with quote

Start from something simple.

Does anything work?
(i.e. Does a 1Hz flasher operate at the correct frequency)

Then get each timer to toggle a pin separately then together.
Your program to do the tests need be no more than 10 to 20 lines of code.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 06, 2017 1:37 pm     Reply with quote

You're still doing newbie C language mistakes.

Quote:
if(output_low (dig_mil) && control == 1) //Dígito dos milhares desligado?

output_low() doesn't return a value. You can't test it in an if() statement.
There is nothing to test. It could return a 0 or a 1.
The CCS manual says:
Quote:
Syntax: output_low (pin)

Returns: undefined




Quote:
cont =cont ++;

This doesn't hurt anything, but it's completely unnecessary.
All you need is this:
Code:
cont++;
drolleman



Joined: 03 Feb 2011
Posts: 116

View user's profile Send private message

PostPosted: Mon Nov 06, 2017 1:41 pm     Reply with quote

only do he absolute minimum in your interrupts.
typically 5 lines or less

remove the set timer in the interrupts.
this line will trigger a interrupt immediately


David
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Nov 06, 2017 1:44 pm     Reply with quote

Start by testing with something much simpler.

There are a lot of problems with what you post:
Quote:

set_tris_c (0x80); //Configura todo PORTC como saída, exceto RC7

C7 is set as an input.
Quote:
output_c(0x80); //Inicializa PORTC (segmentos desligados), RC7 em nível alto


Yet you then try to output a bit on it?.

Then you only need to enable the global bit once:
Code:

   //SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
   //The command here is _setup_ not set....
   SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_16 );
   set_timer0(0);
   
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   set_timer1(0);

   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);


Then what is connected to RB7?.
'Toggle' will not work if the pin is overloaded.

Then setting to zero in the interrupts is pointless. The interrupt is called when the timer wraps to zero.

Then far too much maths in the interrupt. This takes a huge time, and results in interrupts being disabled in all maths outside the interrupt (doesn't apply at present, but _will_).

Have individual digit counters. Count 0 to 9. When it reaches 9, increment the next digit, and reset this counter to 0. For the next digit count 0 to 5 etc. etc..

Have you actually tested the chip is running. Simple 'toggle an LED' test. Do this before anything else.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank you Ttelmah
PostPosted: Tue Nov 07, 2017 11:25 am     Reply with quote

//SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
//The command here is _setup_ not set....
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_16 );
set_timer0(0)

The big mistake was just in this line. I did not understand why the compiler did not generate error when compiling???

I changed the line: set_tris_c (0x80); // Set all PORTC as output except RC7.
I changed the set to

set_tris_c (0x00); // Set all PORTC as output, except RC7, since I'm not using Pin_C7.

Then what is connected to RB7 ?.
A led to test if there was a timer overflow. Because I was testing timer0 and timer1 separately.

Thank you for your help..
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank you too Drolleman
PostPosted: Tue Nov 07, 2017 11:27 am     Reply with quote

Thank you friend Drolleman.

The big mistake was just in this line //SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
//The command here is _setup_ not set...

I did not understand why the compiler did not generate error when compiling???
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank you PCM programmer
PostPosted: Tue Nov 07, 2017 11:34 am     Reply with quote

PCM Programmer Thank you friend.

Yes, you're right.
Quote:

output_low() doesn't return a value. You can't test it in an if() statement.
There is nothing to test. It could return a 0 or a 1.

I am changing the test to:

if(dig_mil==0 && control == 1) and all other commands.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Nov 07, 2017 11:42 am     Reply with quote

if you're going to be testing 2 different timers (or conditions...) use two LEDs so you can see which is occurring. PICs can have lots of pins so use them...

Also , have a look at the software RTC in the code library. It's easily modified for any PIC and might save you some time (no pun intended).

Jay
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

PCM Pogrammer
PostPosted: Tue Nov 07, 2017 11:52 am     Reply with quote

Hi friend:

PCM Programmer:

In my new test the program the program did not execute multiplexing with this if command (dig_mil == 0 && control == 1), but with this: if (output_low (dig_mil) && control == 1) multiplexing of displays is occurring. And now how should I proceed? I do : int mil=0x00, cen=0x00, dez=0x00, uni=0x00;

PCM programmer wrote:
You're still doing newbie C language mistakes.

Quote:
if(output_low (dig_mil) && control == 1) //Dígito dos milhares desligado?

output_low() doesn't return a value. You can't test it in an if() statement.
There is nothing to test. It could return a 0 or a 1.
The CCS manual says:
Quote:
Syntax: output_low (pin)

Returns: undefined




Quote:
cont =cont ++;

This doesn't hurt anything, but it's completely unnecessary.
All you need is this:
Code:
cont++;
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 07, 2017 12:00 pm     Reply with quote

Quote:
I am changing the test to:

if(dig_mil==0 && control == 1) and all other commands.

This is wrong !

Your own program says:
Code:
#define dig_mil  PIN_B3

So your code is doing this:
Code:
if(PIN_B3 == 0 ...

But what is PIN_B3 ? Look in the 16F877A.h file. It's right there in
the CCS compiler installation, in the \Devices folder. It says pin B3 is
the number 51:
Code:

#define PIN_B0  48
#define PIN_B1  49
#define PIN_B2  50
#define PIN_B3  51
#define PIN_B4  52
#define PIN_B5  53
#define PIN_B6  54
#define PIN_B7  55


So your code, which you think will work, is doing this:
Code:
if(51 == 0 ...

That is NOT what you want.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

Re: Thank you too Drolleman
PostPosted: Tue Nov 07, 2017 1:31 pm     Reply with quote

jacktaylor wrote:
Thank you friend Drolleman.

The big mistake was just in this line //SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
//The command here is _setup_ not set...

. I did not understand why the compiler did not generate error when compiling???


Because it is perfectly correct. It just does not do what you want.

setup_timer is the command to configure the timer.
set_timer is the command to set the timer to a number.

Both are simply commands that accept numbers.

The values like RTCC_INTERNAL are just macro defines to give 'names' to particular numbers, to mean you don't have to know that the number needed to select the internal clock is xxx. Instead you can use the name and this generates the particular number required.

So syntactically the line is fine. So no error. It just doesn't do what you want.....
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank you PCM Progammer
PostPosted: Thu Nov 09, 2017 10:31 am     Reply with quote

Thank you PCM Programmer.

Yes I had already understood his explanation, but the doubt that still remains is:

Quote:
output_low () does not return a value. You can not test it in an if () statement.
There is nothing to test. It could return to 0 or a 1.

to check if an entry is at zero, we can use the command if (input (xxxxx) == 0) do ...

since the command if (output (xxxxx) == 0) does ..... can not be used, even though it has run in my program, because it returns an undefined value.

The question is: How to check in an if () function if an output is at zero, low level?

output_bit (PIN_B0, 0);
// Same as output_low (pin_B0);

output_low () does not return a value. You can not test it in an if () statement.
There is nothing to test. It could return to 0 or a 1.

Or can my program only control ??:

if (control == 1) {}
if (control == 2) {}
if (control == 3) {}
if (control == 4) {} ???



PCM programmer wrote:
Quote:
I am changing the test to:

if(dig_mil==0 && control == 1) and all other commands.

This is wrong !

Your own program says:
Code:
#define dig_mil  PIN_B3

So your code is doing this:
Code:
if(PIN_B3 == 0 ...

But what is PIN_B3 ? Look in the 16F877A.h file. It's right there in
the CCS compiler installation, in the \Devices folder. It says pin B3 is
the number 51:
Code:

#define PIN_B0  48
#define PIN_B1  49
#define PIN_B2  50
#define PIN_B3  51
#define PIN_B4  52
#define PIN_B5  53
#define PIN_B6  54
#define PIN_B7  55


So your code, which you think will work, is doing this:
Code:
if(51 == 0 ...

That is NOT what you want.
Wink
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Re: Thank you Ttelmah
PostPosted: Thu Nov 09, 2017 10:39 am     Reply with quote

OK now I got it. Thank you Ttelmah.

Ttelmah wrote:
jacktaylor wrote:
Thank you friend Drolleman.

The big mistake was just in this line //SET_TIMER0(RTCC_INTERNAL | RTCC_DIV_16 );
//The command here is _setup_ not set...

. I did not understand why the compiler did not generate error when compiling???


Because it is perfectly correct. It just does not do what you want.

setup_timer is the command to configure the timer.
set_timer is the command to set the timer to a number.

Both are simply commands that accept numbers.

The values like RTCC_INTERNAL are just macro defines to give 'names' to particular numbers, to mean you don't have to know that the number needed to select the internal clock is xxx. Instead you can use the name and this generates the particular number required.

So syntactically the line is fine. So no error. It just doesn't do what you want.....
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 10:58 am     Reply with quote

One way to read the status of an output pin, is to 'loopback' that pin to an Input pin. Simply connect the two pins together. Reading the input pin will show what the output pin is , either high(1) or low(0). I did this 3 decades ago to 'confirm' pins were set/reset.

The other way is to have a variable called 'outcmd' You set the 'outcmd' variable to desired value, then use it to set the output pin. By reading the variable 'outcmd' it will reflect what you sent to the output pin. This is NOT the same as reading the actual pin though.

Now it _may_ be possible to read the 'status' of an output pin by quickly changing the TRIS bit for it, doing a quick read, then setting back to output. Not near the lab today to try this though pretty sure there was an APPNOTE from Microchip about doing this, maybe in their 'tips and tricks' manual...sigh 2-3 decades ago..

Also some newer PICs have a separate output vs input register for I/O pins, which _may_ allow you to read the status of output pin

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group