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 CCS Technical Support

Timer1 in RC0 and RC1
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Thu Jan 22, 2015 2:58 am     Reply with quote

PCM programmer wrote:
Quote:
output_high(pin_c1)==get_timer1();

This statement is wrong, doesn't work as you intend, and should not
be written.


So, what's the correct one?
Ttelmah



Joined: 11 Mar 2010
Posts: 20063

View user's profile Send private message

PostPosted: Thu Jan 22, 2015 3:38 am     Reply with quote

We don't know, since we don't know what you want to do...

However 'output_high', does not return a value. In the manual 'returns undefined'. So it could return a 1 or a 0. You then compare this (at most a single bit) value with a number from a timer?. It's garbage.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Thu Jan 22, 2015 6:27 am     Reply with quote

Ttelmah wrote:
We don't know, since we don't know what you want to do...

However 'output_high', does not return a value. In the manual 'returns undefined'. So it could return a 1 or a 0. You then compare this (at most a single bit) value with a number from a timer?. It's garbage.


Thanks, I understand what you mean.
I presently have pin_C0 reading its input from the external source through timer1.
Code:
 freqc_low=get_timer1();

Actually I changed the variable's name. 'value' is now 'freqc_low' to fit in this latest code I have posted above.
This sets the bargraph activity. I wrote A=freqc_low/200 because the value read at C0's input divided by 200 shows the number of bars I wish to be displayed.
Then I created int B and C to set a particular number of bars depending on how far or close the frequency value read is from the target frequency, in this case 5KHz.

So what do I want to do?
I want the LED connected to pin_C1 to light up or blink according to the same behavior set to the bargraph regarding int A,B and C.
I assume that for this to happen, pin C1 needs to 'read' TIMER1 just like pin C0 does.
Is that correct?

So, as output_high(pin_C1) does not return a value, what should I write to make pin_C1 'get timer1'?
Ttelmah



Joined: 11 Mar 2010
Posts: 20063

View user's profile Send private message

PostPosted: Thu Jan 22, 2015 8:35 am     Reply with quote

No.

You'd need to do something like test the incoming value against a threshold value, and use this to set or clear the LED.

So (possibly), something like:
Code:

output_bit(PIN_C1, (freqc_low > 100));


This will turn on the LED when the freq_low value is >100, and off when it is <=100.

Two big differences:
1) Using output_bit, which accepts a true/false, to set or clear the bit.
2) Feeding this with the result of a logic test.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Thu Jan 22, 2015 10:43 am     Reply with quote

Thanks. I will do it.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Sat Jan 24, 2015 3:19 pm     Reply with quote

Hi folks, I need one last help from the experts here.

Ok, I got together my code for bargraph, TMR1 and LED. All set and working fine. However when adding this piece of the code to the rest of the programming I found an issue that I can't seem to solve.

This relates to one conditional for several instructions and how to organize them the correct way to make the code work.

I had the code below for a PWM pulse on and off in a loop with an interrupt so when pressing a button, display changed for another 'cont'.
Code:

void button_isr()
{
   
   if( !input(PIN_B7) && !signal )

      signal = 1;
   else
   
   
   if( !input(PIN_B7) && signal )
      signal = 0;   
}
if ( (SW4 && !ISPRESSED_KEY4) )
   
  {
   
         ISPRESSED_KEY4=TRUE;
   
   if(cont==1)   
           
   do // interrupts to loop state of PWM and out of it
   
   {
   
   if(signal)
   {
         setup_timer_2(T2_DIV_BY_4,249,1);
         set_pwm1_duty(748);//enable PWM
         setup_ccp1(CCP_PWM); //enable PWM
         delay_ms(100);
         setup_ccp1(CCP_OFF);//disable PWM
         delay_ms(1000);
 
}
       
   }
   
    while(input(pin_b4)==1); //if SW4 is pressed while in SW1 
   


However when I added the counter, bargraph and led codes to make the whole thing, I lost the PWM initialization or when it does, it will not loop anymore. I have tried different approaches to write the instruction, but it is not working.
Bellow is the latest code I wrote, after arranging bargraph, TIMER1 and led. All work, when I press button for 'cont', but PWM is not working anymore. PWM and TIMER1 should start at the same time and remain on while button PinB7 is pressed once and turned off when pressed twice.

How do I get PWM working in a loop as code #1 and being able to be turned off inside this latest code?
Thanks in advance.
Code:

 if ( (SW4 && !ISPRESSED_KEY4) )
   
  {
         
         ISPRESSED_KEY4=TRUE;
   
   if(cont==1)   
           
   do
   
   {
   
   if(signal)
{   
         setup_timer_2(T2_DIV_BY_4,249,1);
         set_pwm1_duty(748);//enable PWM
         setup_ccp1(CCP_PWM); //enable PWM
         delay_ms(100);
         setup_ccp1(CCP_OFF);//disable PWM
         delay_ms(1000);
       
       
         set_timer1(0);
         setup_timer_1(t1_external | T1_DIV_BY_1);
         delay_ms(1000);
         
         setup_timer_1(T1_DISABLED);// counter starts at the same time PWM starts
         value=get_timer1();
       
         printf (lcd_putc,"\f%LU\r\n",value);      // print frequency
         
         A=value/200;
         B=value/400;
         C=value/800;
         D=value/10000;

       
   if(value>=4998 && value<=5000)
         bargraph(A);      //print line 2 with the bargraph output
         
   else if ((value>=4994 && value<4998) || (value>=5005 && value<5020))
         bargraph(B);
     
   else if((value>=4985 && value<4994) || (value>=5020 && value<=5035))
         bargraph(C);
     
   else
         bargraph(D);
   
   
   
   if(value>=4998 && value<=5000)
               
   do
      {
         output_high(pin_c1); //led blinks according delay
         delay_ms(10);
         output_low(pin_c1);
         delay_ms(10);
       
      }
     
      while(signal);
     
   if((value>=4994 && value<4998) || (value>=5005 && value<5020))
               
   do
      {
         output_high(pin_c1);
         delay_ms(90);
         output_low(pin_c1);
         delay_ms(90);
       
      }
     
      while(signal);
     
   if((value>=4985 && value<4994) || (value>=5020 && value<=5035))
     
   do
      {
         output_high(pin_c1);
         delay_ms(160);
         output_low(pin_c1);
         delay_ms(160);
       
      }
     
      while(signal);
     
   if(value<4985 || value>5035)
   
   do
      {
         output_low(pin_c1);
         
      }
             
      while(signal);


      } 
   
       
      if(!signal)

   
      {         
            printf(lcd_putc,"\f");
            lcd_gotoxy(1,1);
            lcd_putc("text01");
            lcd_gotoxy(7,2);
            printf(lcd_putc," %04LU ",counter);
            break;
           
   }
       
   }
   
    while(input(pin_b4)==1); //if SW4 is pressed while in SW1
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Sun Jan 25, 2015 5:07 am     Reply with quote

Below is the PWM routine I need to include in a loop. It starts when pressing button pin_B7 happens until a new pressing of this button stops it.
There are 3 different pulses that will be sent at different times according to the 'cont' in the display.

Code:

           setup_timer_2(T2_DIV_BY_4,249,1);
           set_pwm1_duty(748);//enable PWM
           setup_ccp1(CCP_PWM); //enable PWM
           delay_ms(100);
           setup_ccp1(CCP_OFF);//disable PWM
           delay_ms(1000);




This is a better structured and shorter version of the code, still without the PWM. I just need to fit the PWM in there in a loop in a manner that it does not compromise the other instructions and start at the same time TIMER1 starts for the bargraph routine and stops also when pinB7 button is pressed a second time.
Thanks in advance

Code:

 if ( (SW4 && !ISPRESSED_KEY4) )
   
  {
         
         ISPRESSED_KEY4=TRUE;
   
   if((cont==1)||(cont==2)||(cont==3))   
           
   do
   
   {
   
   if(signal)
   
   {   
         
         set_timer1(0);
         setup_timer_1(t1_external | T1_DIV_BY_1);
         delay_ms(1000);
         setup_timer_1(T1_DISABLED);
         value=get_timer1();
         
         if(cont==1)
         printf (lcd_putc,"\fF1=       %LU\r\n",value);
         A=value/200;
         B=value/300;
         C=value/400;
         D=value/10000;
       
         
         if(cont==2)
         printf (lcd_putc,"\fF2=     %LU\r\n",value);
         A=value/360;
         B=value/460;
         C=value/560;
         D=value/10000;
         
         if(cont==3)
         printf (lcd_putc,"\fF3=    %LU\r\n",value);
         A=value/520;
         B=value/1200;
         C=value/2000;
         D=value/10000;
       
       
   if(value>=counter-3 && value<=counter+2)
         bargraph(A);      //print line 2 with the bargraph output
         
   else if ((value>=counter-6 && value<counter-2) || (value>=counter+5 && value<counter+20))
         bargraph(B);
     
   else if((value>=counter-15 && value<counter-6) || (value>=counter+20 && value<=counter+35))
         bargraph(C);
     
   else
         bargraph(D);
   
   
   
   if(value>=counter-3 && value<=counter+2)
               
   do
      {
         output_high(pin_c1);
         delay_ms(10);
         output_low(pin_c1);
         delay_ms(10);
       
      }
     
      while(signal);
     
   if((value>=counter-6 && value<counter-2) || (value>=counter+5 && value<counter+20))
               
   do
      {
         output_high(pin_c1);
         delay_ms(90);
         output_low(pin_c1);
         delay_ms(90);
       
      }
     
      while(signal);
     
   if((value>=counter-15 && value<counter-6) || (value>=counter+20 && value<=counter+35))
     
   do
      {
         output_high(pin_c1);
         delay_ms(160);
         output_low(pin_c1);
         delay_ms(160);
       
      }
     
      while(signal);
     
   if(value<counter-15 || value>counter+35)
   
   do
      {
         output_low(pin_c1);
         
      }
             
      while(signal);


      } 
   
       
      if(!signal) // if PWM is sent through C2 pin

   
      {         
           
            printf(lcd_putc,"\f");
            lcd_gotoxy(1,1);
            if(cont==1)
            lcd_putc("F1");
            if(cont==2)
            lcd_putc("F2");
            if(cont==3)
            lcd_putc("F3");
            lcd_gotoxy(7,2);
            printf(lcd_putc," %04LU ",counter);
            break;
           
   }
       
   }
   
    while(input(pin_b4)==1); //if SW4 is pressed while in SW1 
   }
   
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 25, 2015 11:20 am     Reply with quote

Quote:
There are 3 different pulses that will be sent at different times according to the 'cont' in the display.

if(cont==1)
printf (lcd_putc,"\fF1= %LU\r\n",value);
A=value/200;
B=value/300;
C=value/400;
D=value/10000;

etc.

In the C language, when you have multiple statements that are to be
executed if the if() statement is true, the statements must be enclosed
in braces. This is basic C. It shows the problem of trying to write a
program without first learning the C language. It should be like this:
Code:

if(cont==1)
  {
   printf (lcd_putc,"\fF1=       %LU\r\n",value);
   A=value/200;
   B=value/300;
   C=value/400;
   D=value/10000;
  }

And also for if(cont==2) and if(cont==3).


Quote:
do
{
output_high(pin_c1);
delay_ms(10);
output_low(pin_c1);
delay_ms(10);
}
while(signal);

Hopefully 'signal' is changed somewhere (in an interrupt ?), because if
not, then you will never get out of this do-while() loop.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 3:24 am     Reply with quote

PCM programmer wrote:

This is basic C. It shows the problem of trying to write a
program without first learning the C language.


You are right. But unfortunately I have a pritority in finishing this project and have no choice. After I am done with it, learning C language full time is my goal.



Quote:


It should be like this:
Code:

if(cont==1)
  {
   printf (lcd_putc,"\fF1=       %LU\r\n",value);
   A=value/200;
   B=value/300;
   C=value/400;
   D=value/10000;
  }

And also for if(cont==2) and if(cont==3).


Quote:
do
{
output_high(pin_c1);
delay_ms(10);
output_low(pin_c1);
delay_ms(10);
}
while(signal);

Hopefully 'signal' is changed somewhere (in an interrupt ?), because if
not, then you will never get out of this do-while() loop.


These are the LED instructions. I will include the braces , but you mention an interrupt... I actually have an interrupt as you can see in the code. This is for 'if(signal). Will I need another interrupt? If so, please specify.
What I need is the PWM on/off in a loop while I do not press B7 a second time. Also both PWM and timer1 should start at the same time. But this is just not happening. Even if I set Timer1 instructions before the PWM lines, it always suffer a delay and start after PWM.
Thanks in advance.
Ttelmah



Joined: 11 Mar 2010
Posts: 20063

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 4:04 am     Reply with quote

That is the wrong way round. It's like a guy going to do a motor race, and saying "I'm going to learn to drive a car afterwards"....
You at least need to learn basic C syntax, or you are wasting your own (and our) time. Some things need to come first.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 7:03 pm     Reply with quote

Ttelmah wrote:
That is the wrong way round. It's like a guy going to do a motor race, and saying "I'm going to learn to drive a car afterwards"....
You at least need to learn basic C syntax, or you are wasting your own (and our) time. Some things need to come first.


Sorry to disagree with you. I am not wasting my time and it's not my intention to waste people's time. Even the most wise scientist has always something to learn every day. So learning is a never ending proccess either for me or for you.

In reality I am learning the hard way. It's not theory only anymore. I am learning C now with hands on experience 24 hours a day dealing with this compiler. Banging my head on the wall has a lot of advantages over attending classes and reading the theory before the practice. In my case, theory and practice are walking side by side.

I could find out what was wrong. PCM programmer gave me some hints talking about the braces and it actually helped. But the braces alone did not fix the probem. I found that this compiler, bugs apart, utilizes priorities and hierarchies regarding commands and instructions. I did not know. Now I do. Code is 99% complete. Only the LED lines still need to be written.
This past month was an intense lesson for me. I had a project to complete, no prior knowledge on C but I accepted the challenge. Today I can see the long way I have come and maybe very soon I will be the one helping newbies here in this forum. Who knows?

It's funny. You told me that I need to crawl before attempting to walk. But at this very moment, I remembered my little daughter's case, and how she learned to walk without crawling at all. It was in the hardest way. Just like her father is doing now.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 8:37 pm     Reply with quote

Quote:

but you mention an interrupt... I actually have an interrupt as you can see
in the code. This is for 'if(signal).

I don't see any interrupt routines in your code. They would have a line
above them, such as #int_ext for a switch, or #int_timer1 for a timer.
It's possible to detect an interrupt in a polling loop, without using an
interrupt routine. I don't see that method used either.

So I repeat, I don't know how your do-while() loop will ever exit.
There is nothing apparent to change the 'signal' variable. Also your
code doesn't show a declaration of 'signal'.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Tue Jan 27, 2015 5:28 am     Reply with quote

PCM programmer wrote:
Quote:

but you mention an interrupt... I actually have an interrupt as you can see
in the code. This is for 'if(signal).

I don't see any interrupt routines in your code. They would have a line
above them, such as #int_ext for a switch, or #int_timer1 for a timer.
It's possible to detect an interrupt in a polling loop, without using an
interrupt routine. I don't see that method used either.

So I repeat, I don't know how your do-while() loop will ever exit.
There is nothing apparent to change the 'signal' variable. Also your
code doesn't show a declaration of 'signal'.


I did not include the whole code here for the purpose of saving space, but the interrupt routine is included:

Code:
void main()
{
   enable_interrupts(global);
   enable_interrupts(int_rb);

   ext_int_edge( H_TO_L );
}


I changed the do-while() routines. Your brace mentionings called my attention and I figured how to use them. But I could perceive that CCS compiler has a special way to deal with routines and instructions even with braces. They need to be placed in a special order for priority commands.

The whole code is almost ready. Only missing the inclusion of the LED blinking routines that I intend to write as soon as I figure how to insert them without compromising what I have done so far.
I intend to post the code here so that you and others can take a look and suggest changes for better efficiency. I am quite sure that this will happen, since I am still a newbie.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Wed Jan 28, 2015 5:55 am     Reply with quote

PCM programmer, here is the code with PWM, cont transitions and bargraph working. I had to relocate the PWM instruction in order to make it work as intended (loop while pinB7 is not pressed a second time), otherwise it would not.
But the LED instruction in output C1 is not working or it's being bypassed. As Ttelmah said, it might be a matter of 'syntax', but I just cannot find the reason why it is not working.
Code:
 if ( (SW4 && !ISPRESSED_KEY4) )
   
  {
            ISPRESSED_KEY4=TRUE;
   
   if((cont==1)||(cont==2)||(cont==3)) 
           
   do
     
  {
   
    if(signal) // if PWM is sent through C2 pin
   
  { 
         set_timer1(0);
         setup_timer_1(t1_external | T1_DIV_BY_1);
         delay_ms(1000);
         setup_timer_1(T1_DISABLED);
         value=get_timer1();
 
  }     
 
       if(Cont==1)
   
   {       
         printf (lcd_putc,"\f text1        %LU\r\n",value);
         A=value/200;
         B=value/300;
         C=value/400;
         D=value/10000;
         setup_timer_2(T2_DIV_BY_4,249,1);
         set_pwm1_duty(748);       
         
   }     
       if(Cont==2)
   {
         printf (lcd_putc,"\f text2      %LU\r\n",value);
         A=value/360;
         B=value/460;
         C=value/900;
         D=value/10000;
         setup_timer_2(T2_DIV_BY_4,142,1);
         set_pwm1_duty(430);
   }
         if(Cont==3)
   {
         printf (lcd_putc,"\f text3    %LU\r\n",value);
         A=value/520;
         B=value/1200;
         C=value/2000;
         D=value/10000;
         setup_timer_2(T2_DIV_BY_4,96,1);
         set_pwm1_duty(292);                 
   }

   
    if(value>=counter-3 && value<=counter+2)
          bargraph(A);      //print line 2 with the bargraph output 
             
    else if ((value>=counter-6 && value<counter-2) || (value>=counter+5 && value<counter+20))
         bargraph(B);
     
    else if((value>=counter-15 && value<counter-6) || (value>=counter+20 && value<=counter+35))
         bargraph(C);
     
    else
         bargraph(D);

 if(value>=counter-3 && value<=counter+2)
               
         output_bit(pin_c1(1));
         delay_ms(10);
         output_bit(pin_c1(0));
         delay_ms(10);
   
     
         if(signal)
  {
           setup_ccp1(CCP_PWM); //enable PWM
           delay_ms(100);
           setup_ccp1(CCP_OFF);//disable PWM
           delay_ms(1000);
           
  } 
         
   if(!signal) //if pin B7 is pressed a second time & PWM off

   {         
           
            printf(lcd_putc,"\f");
            lcd_gotoxy(1,1);
            if(cont==1)
            lcd_putc("text1");
            if(cont==2)
            lcd_putc("text2");
            if(cont==3)
            lcd_putc("text3");
            lcd_gotoxy(7,2);
            printf(lcd_putc," %LU ",counter);
            break;
           
 
 
       
           
    }
         
         
 
    }
   
   
    while(input(pin_b4)==1); //if SW4 is pressed while in SW1   
   
 
   }


In the code above, if I simply write only the first line
Code:
output_bit(pin_c1(1));
, the LED lights. But if the rest of the instruction is included which would make the LED blink, nothing happens.

I noticed that if I use the DO-WHILE command in the led instruction, it will work, but this time, PWM instructions get ignored.

Any light on this?
Thanks in advance.
Ttelmah



Joined: 11 Mar 2010
Posts: 20063

View user's profile Send private message

PostPosted: Wed Jan 28, 2015 9:33 am     Reply with quote

There are all sorts of potential problems, that we can't be sure about, because we don't know the types of the numbers. For instance:
Code:

((value>=counter-6 && value<counter-2)


Will give completely unexpected results, if 'counter' is an int, and is less than 5.

For an int8, 'counter-6', will solve for counter==2, to 252.... Not what you expect or want at all.
For an int16, for the same values, it'll solve to 65532.

Problem is that maths 'wraps', if an unsigned int, goes -ve, it wraps to '(max+1)- -ve result'.

Then the problem PCM_programmer has already pointed out, applies 'in spades':
Code:

if(value>=counter-3 && value<=counter+2) //This statement if true
               
         output_bit(pin_c1(1));  //executes this statement _only_
         delay_ms(10);
         output_bit(pin_c1(0));
         delay_ms(10);


Try to use some logic in your indentation to actually 'show' how things are executed/intended. Currently your indentation jumps around like a Mexican bean.
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 Previous  1, 2, 3, 4, 5, 6  Next
Page 5 of 6

 
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