CCS C struct problem (Undefined identifier)

Thread Starter

BurhanBhos

Joined Apr 4, 2019
14
Hi! I have developed code for controlling servo motor which worked fine. Then, I tried to make it as header file and c file separately.
C:
//this is main.c

#include <config.h>
#include "servo_control.h"

void main()
{ 
   struct Servo servo1;
   servo1.servo_attach('D', 0);
   
   while(TRUE)
   {
    servo1.servo_write(45);
   }
}

//this is servo_control.h

#ifndef SERVO_CONTROL_H
#define    SERVO_CONTROL_H

struct Servo
{
    int servo_pin;
    unsigned long CCPR;
    unsigned long current_period;
    unsigned long total_period;
};

void servo_attach(char, int);
void servo_write(int);

#endif

//this is servo_control.c

#include "servo_control.h"

#INT_CCP1
void compare_CCP1_interrupt()
{
    if((current_period > 0) && (current_period < total_period))
    {
        if(input(servo_pin))
        {
            output_low(servo_pin);
            CCPR = total_period - current_period;
        }
        else
        {
            output_high(servo_pin);
            CCPR = current_period;
        }
    }
    else
    {
        if(current_period == total_period)  output_high(servo_pin);
        if(current_period == 0)             output_low(servo_pin);
    }

    CCP_1_HIGH = CCPR >> 8;
    CCP_1_LOW = CCPR;
}

void servo_attach(char servo_port_inp, int servo_pin_inp)
{
    if(servo_port_inp == 'B')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_B0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_B1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_B2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_B3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_B4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_B5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_B6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_B7;
    }
    else if(servo_port_inp == 'C')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_C0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_C1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_C2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_C3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_C4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_C5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_C6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_C7;
    }
    else if(servo_port_inp == 'D')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_D0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_D1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_D2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_D3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_D4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_D5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_D6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_D7;
    }
   
    output_drive(servo_pin);
    output_low(servo_pin);
}

void servo_write(int angle)
{
    CCPR = 0;
   
    setup_ccp1(CCP_COMPARE_RESET_TIMER);
   
    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
    set_timer1(0);
   
    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);
}
The error is in the part:
C:
struct Servo servo1;
servo1.servo_attach('D', 0);
The error is: Error#12 Undefined identifier servo1
What is my problem I don't know. I have checked tutorials but no clue. Thank you very much :)
 

WBahn

Joined Mar 31, 2012
26,398
I am trying to write C code.
So how are these functions supposed have access to the data within the structure?

How is dereferencing the structure with the name of an unrelated function supposed to invoke that function?

Are you using some kind of C compiler that has object-oriented like extensions?

What compiler are you using?

Could you post the code that you have that you say is working properly?
 

Thread Starter

BurhanBhos

Joined Apr 4, 2019
14
So how are these functions supposed have access to the data within the structure?

How is dereferencing the structure with the name of an unrelated function supposed to invoke that function?

Are you using some kind of C compiler that has object-oriented like extensions?

What compiler are you using?

Could you post the code that you have that you say is working properly?
I am using CCS C compiler which works based on C. My working code is:
C:
#include <config.h>
#include <stdint.h>

#define SERVO PIN_D0

unsigned long CCPR = 0;
unsigned long current_period = 0;
const unsigned long total_period = 3750;

void servo_write(int);

#INT_CCP1
void compare_CCP1_interrupt()
{
    if((current_period > 0) && (current_period < total_period))
    {
        if(input(SERVO))
        {
            output_low(SERVO);
            CCPR = total_period - current_period;
        }
        else
        {
            output_high(SERVO);
            CCPR = current_period;
        }
    }
    else
    {
        if(current_period == total_period)  output_high(SERVO);
        if(current_period == 0)             output_low(SERVO);
    }

    CCP_1_HIGH = CCPR >> 8;
    CCP_1_LOW = CCPR;
}

void main()
{
    output_drive(SERVO);
    output_low(servo_pin);

    CCPR = 0;

    setup_ccp1(CCP_COMPARE_RESET_TIMER);

    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
    set_timer1(0);

    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);

   while(TRUE)
   {
    servo_write(45);
   }
}

void servo_write(int angle)
{
    double on_time = (angle/180.0) + 1.0;
    current_period = total_period * (on_time / 20.0);
}
This code works without problem, but when I want to make it as a header file and c file it doesn't work.
Isn't the below code is the same as the working one?
C:
//this is main.c

#include <config.h>
#include "servo_control.h"
#include <servo_control.c>

void main()
{ 
   servo_attach('D', 0);
   
   while(TRUE)
   {
    servo_write(45);
   }
}

//this is servo_control.h

#ifndef SERVO_CONTROL_H
#define    SERVO_CONTROL_H

int servo_pin;
unsigned long CCPR;
unsigned long current_period;
unsigned long total_period;

void servo_attach(char, int);
void servo_write(int);

#endif

//this is servo_control.c

#include "servo_control.h"

#INT_CCP1
void compare_CCP1_interrupt()
{
    if((current_period > 0) && (current_period < total_period))
    {
        if(input(servo_pin))
        {
            output_low(servo_pin);
            CCPR = total_period - current_period;
        }
        else
        {
            output_high(servo_pin);
            CCPR = current_period;
        }
    }
    else
    {
        if(current_period == total_period)  output_high(servo_pin);
        if(current_period == 0)             output_low(servo_pin);
    }

    CCP_1_HIGH = CCPR >> 8;
    CCP_1_LOW = CCPR;
}

void servo_attach(char servo_port_inp, int servo_pin_inp)
{
    if(servo_port_inp == 'B')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_B0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_B1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_B2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_B3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_B4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_B5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_B6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_B7;
    }
    else if(servo_port_inp == 'C')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_C0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_C1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_C2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_C3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_C4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_C5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_C6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_C7;
    }
    else if(servo_port_inp == 'D')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_D0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_D1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_D2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_D3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_D4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_D5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_D6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_D7;
    }
   
    output_drive(servo_pin);
    output_low(servo_pin);
   
    current_period = 0;
    total_period = 3750;
   
    CCPR = 0;
   
    setup_ccp1(CCP_COMPARE_RESET_TIMER);
   
    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
    set_timer1(0);
   
    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);
}

void servo_write(int angle)
{
    double on_time = (angle/180.0) + 1.0;
    current_period = total_period * (on_time / 20.0);
}
 

WBahn

Joined Mar 31, 2012
26,398
You are changing lots of things at one time and then having to try to figure out which one of the changes broke your code.

Instead, take your working code and try to get that split into files the way you want so that it does exactly what the working code does -- nothing more.

Part of your problem is that you are including the C source code file into your main program. That defeats the point of splitting up the code. Only include the header file.

You are also using the two different #include formats in a way that is probably causing you problems. Use the angle brackets '<' '>' ONLY for the standard include files -- they tell the compiler to only look for the file in the standard include directory. Use the quotes for header files you create and put them in the same directory as the rest of your code. They tell the compiler to look in the current directory first.
 

Thread Starter

BurhanBhos

Joined Apr 4, 2019
14
So, at the end I excluded .h file and keep only .c file and it worked. But, it is a pity that I didn't know what is the problem with just putting the same variables into the header file :(

C:
//this is main.c

#include <config.h>
#include <servo_control.c>

void main()
{ 
   servo_attach('D', 0);
   
   while(TRUE)
   {
    servo_write(50);
   }
}

//this is servo_control.c

int servo_pin;
unsigned long CCPR = 0;
unsigned long current_period = 0;
const unsigned long total_period = 3750;

#INT_CCP1
void compare_CCP1_interrupt()
{
    if((current_period > 0) && (current_period < total_period))
    {
        if(input(servo_pin))
        {
            output_low(servo_pin);
            CCPR = total_period - current_period;
        }
        else
        {
            output_high(servo_pin);
            CCPR = current_period;
        }
    }
    else
    {
        if(current_period == total_period)  output_high(servo_pin);
        if(current_period == 0)             output_low(servo_pin);
    }

    CCP_1_HIGH = CCPR >> 8;
    CCP_1_LOW = CCPR;
}

void servo_attach(char servo_port_inp, int servo_pin_inp)
{
    if(servo_port_inp == 'B')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_B0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_B1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_B2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_B3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_B4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_B5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_B6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_B7;
    }
    else if(servo_port_inp == 'C')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_C0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_C1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_C2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_C3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_C4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_C5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_C6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_C7;
    }
    else if(servo_port_inp == 'D')
    {
        if(servo_pin_inp == 0)  servo_pin = PIN_D0;
        else if(servo_pin_inp == 1)  servo_pin = PIN_D1;
        else if(servo_pin_inp == 2)  servo_pin = PIN_D2;
        else if(servo_pin_inp == 3)  servo_pin = PIN_D3;
        else if(servo_pin_inp == 4)  servo_pin = PIN_D4;
        else if(servo_pin_inp == 5)  servo_pin = PIN_D5;
        else if(servo_pin_inp == 6)  servo_pin = PIN_D6;
        else if(servo_pin_inp == 7)  servo_pin = PIN_D7;
    }
   
    output_drive(servo_pin);
    output_low(servo_pin);
   
    CCPR = 0;
   
    setup_ccp1(CCP_COMPARE_RESET_TIMER);
   
    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
    set_timer1(0);
   
    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);
}

void servo_write(int angle)
{
    double on_time = (angle/180.0) + 1.0;
    current_period = total_period * (on_time / 20.0);
}
 

Thread Starter

BurhanBhos

Joined Apr 4, 2019
14
You are changing lots of things at one time and then having to try to figure out which one of the changes broke your code.

Instead, take your working code and try to get that split into files the way you want so that it does exactly what the working code does -- nothing more.

Part of your problem is that you are including the C source code file into your main program. That defeats the point of splitting up the code. Only include the header file.

You are also using the two different #include formats in a way that is probably causing you problems. Use the angle brackets '<' '>' ONLY for the standard include files -- they tell the compiler to only look for the file in the standard include directory. Use the quotes for header files you create and put them in the same directory as the rest of your code. They tell the compiler to look in the current directory first.
Without including .c and .h file together, compiler gives error.
 

JohnInTX

Joined Jun 26, 2012
4,503
Without including .c and .h file together, compiler gives error.
Have you set up a project and are you using the IDE version of the compiler? As I understand the manual, you can include .c source in a single compilation where the source in the other file(s) is just treated as text in the original file - that's what it looks like you are doing.

To use multiple files compiled separately ('Multiple Compilation Units' in CCS), it looks like you must use an IDE and create a project file which lists all of the C source files you want to use in the final build. These are compiled separately then linked to form the .HEX file. The project file automates the process.

Many compilers allow command line compilation and linker scripts to put it all together (that the IDE and project file does automatically) but the CCS manual says you have to use the IDE for theirs. I didn't research it further.

Good luck!
 

Attachments

Top