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

PWM3 duty unrecognized

 
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

PWM3 duty unrecognized
PostPosted: Wed Dec 31, 2014 6:44 am     Reply with quote

Hello,
I am facing a problem which others may already have encountered.
This relates to an error message from CCS which states "Undefined identifier--set_pwm3-duty".

I have defined it and it keeps displaying the same thing.
I am sending 3 different PWM signals through CCP1 but at different pushbutton moments.
The weird thing is that I have the very same code for PWM1 and PWM2 and CCS does not complain about it. But when I use a third PWM, the error message is displayed.
I have already unistalled and reinstalled CCS and nothing changed.
Bellow is the code for this part and I would appreciate if someone could help me to fix that. Thanks .
I am using PIC 16F877A.
Code:
 if ( (SW4 && !ISPRESSED_KEY4) )
   {
   
      ISPRESSED_KEY4=TRUE;
     
     
      if(cont==1)
     
   
     
   while(TRUE)
   {
       
       unsigned INT pwm1;
       setup_timer_2(T2_DIV_BY_4,249,1);
       pwm1=748;
       
       set_pwm1_duty(pwm1);//enable PWM
       setup_ccp1(CCP_PWM); 
       delay_ms(100);
       setup_ccp1(CCP_OFF);//disable PWM
       delay_ms(2200);

       
        }
     
       
      if(cont==2)
   
   while(TRUE)
   {
       unsigned INT pwm2;
     
       setup_timer_2(T2_DIV_BY_4,143,1);
       pwm2=430;
       set_pwm2_duty(pwm2);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM
       
       
   }
     

   if(cont==3)
   
   while(TRUE)
   {
       unsigned INT pwm3;
     
       setup_timer_2(T2_DIV_BY_4,97,1);
       pwm3=292;
       set_pwm3_duty(pwm3);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM
     
     
   }
   
   }
   
temtronic



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

View user's profile Send private message

PostPosted: Wed Dec 31, 2014 7:21 am     Reply with quote

I haven't used the 877 for about 12 years but I'm pretty sure it only has TWO PWM modules. You might want to consult the datasheet to confirm.

Jay
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Wed Dec 31, 2014 7:45 am     Reply with quote

Hi Jay, thanks for your reply.
I am a newbie to the world of microcontrollers and striving to survive.

Yes, I see that it has two modules.
So I can use int PWM1 and int PWM2.

But my situation is this.
I am using two pushbuttons to control the state of how PWM signals are being sent.
I have one connected to pinB4. When I push this button in a sequence of three times, it toggles between 3 different texts with a particular associated frequency I want to send and then after pressing the button a third time it returns to text#1. So, when I press another pushbutton( B7) the particular frequency associated with that text# is sent. When I press pushbutton B4, it will stop PWM and change text so that when I press B7 again another frequency is sent associated to the related text, etc.

So as you can see, I am only using CCP1 to send different frequencies, but at different times, and it should be no problem, right?
But how can I accomplish that, if CCS returns error messages if I use the same INT PWM1 for more than one instance?

Thanks in advance.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Wed Dec 31, 2014 8:39 am     Reply with quote

Well, I figured a workaround for this but don't know how correct this is.

I created an 'unsigned INT PWM1'.
I set a value. PWM1=500.

My first instance of duty cycle was 748. So I did :

pwm+=248;

Second instance was duty cycle=430. I did:

pwm-=70;

And last instance was 292.
pwm-=208;

CCS compiled with no errors this time.

What do you guys think, did I do it right?
Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed Dec 31, 2014 8:40 am     Reply with quote

Start with it isn't going to work....

How big is an 'int'. What can it hold?. Your int can't hold 748, 430 or 292.

Now you say you are only using one PWM, but you aren't. You are setting PWM2, and then trying to set PWM3. Get rid of these. All your values want to go to the single PWM1. You confuse things a little by calling your variables with PWM names. Use something like - however there is a big 'code flow' problem in what you post:

Code:

    //declare the time _once_
    int16 time;

    //your existing switch code

    //Then there is a big problem - moving the brackets shows this:
   while(TRUE)
   {
       setup_timer_2(T2_DIV_BY_4,249,1);
       time=748;       
       set_pwm1_duty(time);//enable PWM
       setup_ccp1(CCP_PWM);
       delay_ms(100);
       setup_ccp1(CCP_OFF);//disable PWM
       delay_ms(2200);     
   } //how is the code ever going to exit this......
   //Big problem here.......
   if (cont==2)
   {
       while(TRUE)
       {
            setup_timer_2(T2_DIV_BY_4,143,1);
            time=430;
            set_pwm1_duty(time); //at this point you were accessing the
            //second PWM, but setting up the first
            setup_ccp1(CCP_PWM);  //enable PWM
            delay_ms(100);
            setup_ccp1(CCP_OFF);
            delay_ms(2200);//disable PWM
       } //again how is it ever going to exit?.
   }
   if(cont==3)
   {
       while(TRUE)
       {
            setup_timer_2(T2_DIV_BY_4,97,1);
            time=292;
            set_pwm1_duty(time);
            setup_ccp1(CCP_PWM);  //enable PWM
            delay_ms(100);
            setup_ccp1(CCP_OFF);
            delay_ms(2200);//disable PWM
        } //same exit problem.....
    }

You were sending the time to PWM2, then PWM3 (which doesn't exist). Neither would work since you haven't enabled PWM2 anyway....

Use a name like 'time' or 'time1', 'time2', and 'time3', and then you are less likely to start trying to send the values to a third PWM....

Big problem is how it ever gets out of the while loops. Normally (if the keyboard is being scanned in an interrupt for instance), you would want to loop 'while' the key was pressed, rather than forever.

Then why use so much code?.

If you declared the time values as a two dimensional array, with:

249,748
143,430
97,292

called (say) times[3,2]

You could just use the value of 'cont' as an index into this array, and code as:
Code:
   
       setup_timer_2(T2_DIV_BY_4,times[cont,0],1);
       set_pwm3_duty(times[cont,1]);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM

and handle all three possibilities with the same code....
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Wed Dec 31, 2014 10:23 am     Reply with quote

Thank you so much Ttelmah. As I said, I am a newbie into programming. Acually this is my first project and have been studying this for only 3 weeks.

The loops were left blank and code flow on purpose. I simply do not know how to write the instructions I described yet. Actually this was going to be my next question here.
I then wrote 'break;'just to check if the signals were being output in the proteus simulator.
I am providing the whole code below, with the changes you made.
Please see if it's correct now.
Of course I am aware of the fact that it could be better written and shorter, but for now, that is all I could acomplish so far.

The project goes like this.
When circuit is turned on, pushing button(input B4), I toggle between 3 texts in the display. Each text has its associated signal with three different frequencies and duty cycles that are sent when I press button in input B7. Every time that I press again B4, it should toggle to the next text at the same time that the previous PWM signal stops. Then when I press B7 while at that display, PWM starts again with the correspondent frequency.
My remaining problem is to know what instruction I need to write to make this happen. I have already succeeded in switching the cases for different texts in the display but that is all.
Thanks a lot in advance for any help.
Code:
#include <16f877a.h>
#use delay(clock = 20000000)
#include <LCD.C>
#define LCD_ENABLE_PIN PIN_D0
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>
#int_rb

void main()
{
   output_drive(PIN_c1); //Makes pin C1 output
   output_drive(pin_c2);
 
   setup_adc_ports(AN0_VREF_VREF);
   setup_adc(  ADC_CLOCK_INTERNAL  );
 
   port_B_pullups(0xFF);
   setup_adc_ports(AN0);
   lcd_init();

   lcd_init();

    INT1 SW1;
    INT1 SW2;
    INT1 SW3;
    INT1 SW4;   
        BOOLEAN ISPRESSED_KEY1=FALSE;       // Boolean logic=0;
        BOOLEAN ISPRESSED_KEY2=FALSE;       // Boolean logic=0;
        BOOLEAN ISPRESSED_KEY3=FALSE;       // Boolean logic=0;
        BOOLEAN ISPRESSED_KEY4=FALSE;       // Boolean logic=0;
     
     int Cont;
   cont = 0;
   Int16 counter;
   unsigned int value_batt;
           
   while (true)
   {
   SW1=INPUT(PIN_B4); // Positive inputs
   SW2=INPUT(PIN_B5);
   SW3=INPUT(PIN_B6);
   SW4=INPUT(PIN_B7);
               
   SET_ADC_CHANNEL(0);     // INPUT AN0
   DELAY_MS(10);
                   
   if ( (SW1 && !ISPRESSED_KEY1) || (SW2 && !ISPRESSED_KEY2) || (SW3 && !ISPRESSED_KEY3)|| (SW4 && !ISPRESSED_KEY4) )
   { 
   DELAY_MS(10);
             
   if ( (SW1 && !ISPRESSED_KEY1) ) //

   {
    counter=5000;
     
   if(cont >= 1) counter=9000;
   if(cont >= 2) counter=10000;
   if(cont >= 3) counter=5000;
 
   if(++cont >= 4) cont = 1;
   ISPRESSED_KEY1=TRUE ;
   
   }   
   if ( (SW2 && !ISPRESSED_KEY2) ) //
   {
   counter+=10;               
   ISPRESSED_KEY2=TRUE;
               
   }                     
   if ( (SW3 && !ISPRESSED_KEY3) )
   {                     
   counter-=15;
   ISPRESSED_KEY3=TRUE; 
   }
   
   if ( (SW4 && !ISPRESSED_KEY4) )
   {
     
      ISPRESSED_KEY4=TRUE;
     
      if(cont==1)   
   while(TRUE)
   {
       INT16 time1;
       setup_timer_2(T2_DIV_BY_4,249,1);
       time1=748;
       set_pwm1_duty(time1);//enable PWM
       setup_ccp1(CCP_PWM); //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);//disable PWM
       delay_ms(2200);

       break;
        } 
      if(cont==2)
   
   while(TRUE)
   {
       INT16 time2;
       setup_timer_2(T2_DIV_BY_4,143,1);
       time2=430;
       set_pwm1_duty(time2);//enable PWM
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM
       
       break;
   }
   if(cont==3)
   
   while(TRUE)
   {
       INT16 time3;
       setup_timer_2(T2_DIV_BY_4,97,1);
       time3=292;
       set_pwm1_duty(time3);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM
     
     break;
   }   
   }
   switch(cont)               
   {
            case 1:
         
            if ( ISPRESSED_KEY1 )
               printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               lcd_putc("text1");
               lcd_gotoxy(7,2);
               printf(lcd_putc," %04LU ",counter);
               
               break;
                       
            case 2:
                           
            if ( ISPRESSED_KEY1 )
               printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               lcd_putc("text2");
               lcd_gotoxy(7,2);
               printf(lcd_putc," %04LU ",counter);
               
               break;                         
             case 3:
                         
             if (ISPRESSED_KEY1 )
               printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               lcd_putc("text3");
               lcd_gotoxy(7,2);
               printf(lcd_putc," %05LU ",counter);
                         
               break;
                           
               case 4:
               
               set_adc_channel(0);
               value_batt = read_adc();
               
           
                if (ISPRESSED_KEY1 )
                    printf(lcd_putc,"\f");
                    lcd_gotoxy(3,1);
               
                if (value_batt>130)
                   lcd_putc("BATTERY 5");
           
                if (value_batt>=114 && value_batt<=130)
                   lcd_putc("BATTERY 3");
             
                if (value_batt<114)
                   lcd_putc("BATTERY 1");
                   
               break;
              }
                     
               delay_ms(10);  // Required for button() function
                    }
                                 
               if (!SW1) ISPRESSED_KEY1=FALSE;       
               
               if (!SW2) ISPRESSED_KEY2=FALSE;
               
               if (!SW3) ISPRESSED_KEY3=FALSE;
               
               if (!SW4) ISPRESSED_KEY4=FALSE;
         
                }
                     
                }
             
            }
             
}
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Thu Jan 01, 2015 5:21 am     Reply with quote

Ttelmah wrote:
S
If you declared the time values as a two dimensional array, with:

249,748
143,430
97,292

called (say) times[3,2]

You could just use the value of 'cont' as an index into this array, and code as:
Code:
   
       setup_timer_2(T2_DIV_BY_4,times[cont,0],1);
       set_pwm3_duty(times[cont,1]);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM

and handle all three possibilities with the same code....


Hi Ttelmah,
I inserted your code suggestion as shown below. But CCS is displaying an error message "Error 30: Expecting a ]" on both lines regarding the 'comma' in the 'cont' structure:

Code:
 if ( (SW4 && !ISPRESSED_KEY4) )
   {

       
     
       INT16 times [3][2] = {{249,748},{143,430},{97,292}};
   
       
       setup_timer_2(T2_DIV_BY_4,times[cont,0],1);
       set_pwm1_duty(times[cont,1]);
       setup_ccp1(CCP_PWM);  //enable PWM
       delay_ms(100);
       setup_ccp1(CCP_OFF);
       delay_ms(2200);//disable PWM
       
   }   
   


Do you know what is happening?
Thanks, happy new year.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Jan 01, 2015 10:37 am     Reply with quote

I said as an 3*2 array, not that this was how to declare this in C....

Look at how arrays are specified and used in C.

Hint - each dimension needs it's own brackets.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Thu Jan 01, 2015 12:38 pm     Reply with quote

Ok, I looked about arrays and I came up with this:

Code:
INT16 times [3][2] = {249,748,143,430,97,292};
     
             setup_timer_2(T2_DIV_BY_4,times[cont],1);
             cont=0;
             set_pwm1_duty(times[cont]);
             cont=1;
             setup_ccp1(CCP_PWM);  //enable PWM
             delay_ms(100);
             setup_ccp1(CCP_OFF);
             delay_ms(2200);//disable PWM


Though CCS is compiling the code with no errors, this is not working for me.

As I said, whenever I press SW1 button, the texts toggle in display. I need that in each particular text display when I push SW4, the correspondent PWM signal starts in a loop. As I press SW1 again, PWM stops and display toggles to the next text, waiting for SW4 to be pressed again,etc.
Since I am a novice in programming, I just can't get to write the correct instructions for this.
Below is the portion of the code after the above instruction was inserted but it's not working.
Sorry if I still could not make your instruction work yet, but maybe if you can give me more details on how to set the loop and get out of it correctly, I will be able to succeed.
Thanks for your patience.

Code:
if ( (SW1 && !ISPRESSED_KEY1) || (SW2 && !ISPRESSED_KEY2) || (SW3 && !ISPRESSED_KEY3)|| (SW4 && !ISPRESSED_KEY4) )
   {
   
   DELAY_MS(10);
             
   if ( (SW1 && !ISPRESSED_KEY1) )
   {
   
    counter=1000;
     
   if(cont >= 1) counter=7000;
   if(cont >= 2) counter=10000;
   if(cont >= 3) counter=1000;
 
   if(++cont >= 3) cont = 1;
 
   ISPRESSED_KEY1=TRUE ;
   
   }
     
   if ( (SW2 && !ISPRESSED_KEY2) )
   {
   counter+=10;               
   ISPRESSED_KEY2=TRUE;
               
   }
                       
   if ( (SW3 && !ISPRESSED_KEY3) )
   {
                       
   counter-=20;
   ISPRESSED_KEY3=TRUE; 
   }
   if ( (SW4 && !ISPRESSED_KEY4) )
   {
   
    ISPRESSED_KEY4=TRUE;
           
       INT16 times [3][2] = {249,748,143,430,97,292};   

             setup_timer_2(T2_DIV_BY_4,times[cont],1);
             cont=0;
             set_pwm1_duty(times[cont]);
             cont=1;
             setup_ccp1(CCP_PWM);  //enable PWM
             delay_ms(100);
             setup_ccp1(CCP_OFF);
             delay_ms(2200);//disable PWM
 
             for   (cont=1;cont>=3;cont++)
         
       if(ISPRESSED_KEY1)
       ISPRESSED_KEY1=TRUE;   
     
        }
         
         
 
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Fri Jan 02, 2015 1:45 am     Reply with quote

Your original array declaration was right. It is how you use it in the setup lines that is wrong.

Code:

int16 times [3][2] = {{249,748},{143,430},{97,292}};
//don't capitalise unless you mean to. CCS wakes up with 'case significance'
//off, but enable this and if you change case incorrectly code won't compile...

   setup_timer_2(T2_DIV_BY_4,times[cont][0],1);
   set_pwm1_duty(times[cont][1]);


Don't go changing cont. Cont is the 'row number' you want, and you need element '0' from the row for the time, and element '1' for the duty.
picman62



Joined: 12 Dec 2014
Posts: 77

View user's profile Send private message

PostPosted: Fri Jan 02, 2015 8:57 pm     Reply with quote

Thanks for the explanation. I will try this.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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