This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

linking error in the program . can not find the solution

I am a newbee in Microcontroller programing . the code I have written in C was from a book and it is giving linker error. please help me to solve the problem.
I am sending the code:

/*reading pwm waveform and calculation of frequency using microcontroller*/
#include<reg52.h>
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;

sbit IN=P2^4;

void delay(void);
void INIT(void);
void ENABLE(void);
void LINE(int);

int ONTIME(int);
int offtime(int);
/*declaration of functions complete*/
//
void LINE(int i)
{ if(i==1) { RS=0; RW=0; P1=0x80; ENABLE(); RS=1; } else { RS=0; RW=0; P1=0xC0; ENABLE(); RS=1; }
}

/*dealy subroutine*/

void delay(void)
{ int i,j; for(j=0;j<10;j++) { for(i=0;i<100;i++); }
}

/*delay complete*/

/*Enable subroutine*/
void ENABLE(void)
{ EN=1; delay(); EN=0; delay();
}

/*initialisation of LCD giving proper command*/

void INIT(void)
{ RS=0; RW=0; EN=0; P1=0x38;// 2 Lines and 5*7 matrix LCD ENABLE(); ENABLE(); ENABLE(); P1=0x06; // Shift cursor to left ENABLE(); P1=0x0E; //display on, cursor blinking ENABLE(); P1=0x01; //clear display screen ENABLE();
} /* measuring ontime*/
int ONTIME(int m)
{ if(m==1) { IN=1; /*input to 8051 is from 555 osc*/ TMOD=0x01; TR0=0; TF0=0; TL0=0x00; TH0=0x00; while(IN); /*check for rising edge*/ while(!IN); TR0=1; while(IN); TR0=0; }

/* TO MEASURE OFFTIME*/

if(m==2) { IN=1; TMOD=0x01; TR0=0; TF0=0; TL0=0x00; TH0=0x00;

while(!IN); // check for falling edge while(IN); TR0=1; while(!IN); // CHECK FOR RISING EDGE TR0=0; } return((TH0*256)+TL0);
}

void main(void)
{ int unit, tens, hundred, thousand, tenthou, x; char code dis3[]="Fre in HZ="; char *p; int i,j,k,freq,l; while(1) { for(x=1;x<=3;x++) { if(x==1) { i=ONTIME(x); k=i; }

if(x==2) { i=offtime(x); l=i; } if(x==3) { freq=k+1; i=1/freq; } }

unit=(i%10); tens=(i/10)%10; hundred=(i/100)%10; thousand=(i/1000)%10; tenthou=(i/1000)%10; unit=unit+0x30; tens=tens+0x30; hundred=hundred+0x30; thousand=thousand+0x30; tenthou=tenthou+0x30; INIT(); LINE(0);

p=&dis3;

for(j=0;j<8;j++) { P1=*p++; ENABLE(); }

LINE(2); P1=tenthou; ENABLE(); P1=thousand; ENABLE(); P1=hundred; ENABLE(); P1=unit; ENABLE(); }
}

Parents Reply Children
  • When you say that you, "can not find the solution", what efforts have you made to actually look for a solution?

    eg, did you look-up the error code in the Linker Manual:

    http://www.keil.com/support/man/docs/bl51/bl51_l1.htm

    You still have not posted the source code in a legible form;
    Again, the instructions are quite clear and simple - look at this picture: www.danlhenry.com/.../keil_code.png

    You need to make these basic steps if you want people to be inclined to help you...

  • Note also the link, "Tips for Posting Messages"...

  • I have recopied it

    /*reading pwm waveform and calculation of frequency using microcontroller*/
    #include<reg52.h>
    sbit RS=P2^0;
    sbit RW=P2^1;
    sbit EN=P2^2;
    
    sbit IN=P2^4;
    
    void delay(void);
    void INIT(void);
    void ENABLE(void);
    void LINE(int);
    
    int ONTIME(int);
    int offtime(int);
    
    /*declaration of functions complete*/
    
    void LINE(int i)
    {
            if(i==1)
            {
                    RS=0;
                    RW=0;
                    P1=0x80;
                    ENABLE();
                    RS=1;
            }
            else
            {
                    RS=0;
                    RW=0;
                    P1=0xC0;
                    ENABLE();
                    RS=1;
            }
    }
    
    /*dealy subroutine*/
    
    void delay(void)
    {
            int i,j;
            for(j=0;j<10;j++)
            {
                    for(i=0;i<100;i++);
            }
    }
    
    
    /*Enable subroutine*/
    void ENABLE(void)
    {
            EN=1;
            delay();
            EN=0;
            delay();
    }
    
    /*initialisation of LCD giving proper command*/
    
    void INIT(void)
    {
            RS=0;
            RW=0;
            EN=0;
            P1=0x38;// 2 Lines and 5*7 matrix LCD
            ENABLE();
            ENABLE();
            ENABLE();
            ENABLE();
            P1=0x06; // Shift cursor to left
            ENABLE();
            P1=0x0E; //display on, cursor blinking
            ENABLE();
            P1=0x01; //clear display screen
            ENABLE();
    }
    /* measuring ontime*/
    int ONTIME(int m)
    {
            if(m==1)
            {
                    IN=1;             /*input to 8051 is from 555 osc*/
                    TMOD=0x01;
                    TR0=0;
                    TF0=0;
                    TL0=0x00;
                    TH0=0x00;
                    while(IN);       /*check for rising edge*/
                    while(!IN);
                    TR0=1;
                    while(IN);
                    TR0=0;
             }
    
     /* TO MEASURE OFFTIME*/
    
             if(m==2)
             {
                    IN=1;
                    TMOD=0x01;
                    TR0=0;
                    TF0=0;
                    TL0=0x00;
            TH0=0x00;
    
                    while(!IN);     // check for falling edge
                    while(IN);
                    TR0=1;
                    while(!IN); // CHECK FOR RISING EDGE
                    TR0=0;
            }
            return((TH0*256)+TL0);
    }
    
    void main(void)
    {
            int unit, tens, hundred, thousand, tenthou, x;
            char code dis3[]="Fre in HZ=";
            char *p;
            int i,j,k,freq,l;
            while(1)
            {
                    for(x=1;x<=3;x++)
                    {
                            if(x==1)
                            {
                                    i=ONTIME(x);
                                    k=i;
                }
    
                        if(x==2)
                            {
                                    i=offtime(x);
                                    l=i;
                            }
                            if(x==3)
                            {
                                    freq=k+1;
                                    i=1/freq;
                            }
                    }
    
                    unit=(i%10);
                    tens=(i/10)%10;
                    hundred=(i/100)%10;
                    thousand=(i/1000)%10;
                    tenthou=(i/10000)%10;
                    unit=unit+0x30;
                    tens=tens+0x30;
                    hundred=hundred+0x30;
                    thousand=thousand+0x30;
                    tenthou=tenthou+0x30;
                    INIT();
                    LINE(1);
    
                    p=&dis3;
    
                    for(j=0;j<8;j++)
                    {
                            P1=*p++;
                            ENABLE();
                    }
    
                    LINE(2);
                    P1=tenthou;
                    ENABLE();
                    P1=thousand;
                    ENABLE();
                    P1=hundred;
                    ENABLE();
                    P1=tens;
                    ENABLE();
                    P1=unit;
                    ENABLE();
            }
    }
    


    the error is

    Build target 'Target 1'
    compiling pwm waveform.c...
    linking...
    *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
        SYMBOL:  _OFFTIME
        MODULE:  pwm waveform.obj (PWM_WAVEFORM)
    *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
        SYMBOL:  _OFFTIME
        MODULE:  pwm waveform.obj (PWM_WAVEFORM)
        ADDRESS: 082CH
    Program Size: data=32.0 xdata=0 code=747
    "PWM waveform reading using microcontroller" - 0 Error(s), 2 Warning(s).
    

  • Did you write this code? I doubt that very much!
    Otherwise, you would have seen that you don't have a function called "offtime" in your code thus the linker error!

  • No; he didn't - he says he got it from a book!

    As noted previously,

    "Maybe you similarly missed some important instructions in the book...?"

    Does appear to be the case!

    Another example that just copying code is not enough - you have to understand it!
    See: http://www.keil.com/forum/19129/

  • And have you bothered to look-up the description of that error in the Manual yet?

    Again, here is the link: http://www.keil.com/support/man/docs/bl51/bl51_l1.htm

  • he says he got it from a book!

    I'll say it again: if you are not capable of writing a given code yourself, it serves no purpose to get it from elsewhere. "transfer of code" invariably will result is something not working and if you are not capable of writing the code yourself, you will be totally lost trying to make the 'found' code work.
    However, it can sometimes be a shortcut to grab some code and fix it rather than starting from scratch.

    Erik

  • void delay(void)
    {
            int i,j;
            for(j=0;j<10;j++)
            {
                    for(i=0;i<100;i++);
            }
    }
    

    If you found that in a book, throw it away and get a better one.

  • you are right. I have corrected the error. thank you very much

  • "that" refers to using 'for' loops for timing.

    Do not rely on 'for' loops - or, indeed, any othe HLL construct - for timing!

    See: www.8052.com/.../182476
    And: www.8052.com/.../162556
    and many, many more...

  • ""transfer of code" invariably will result is something not working"

    that may be a little bit too strong, don't you think?

  • A little - but not nuch!

    Especially with embedded code, it does tend to be so very specific to a particular target & environment that expecting any random piece of cut-&-paste code to "just work" is wishful thinking in the extreme!

  • "Especially with embedded code, it does tend to be so very specific to a particular target & environment that expecting any random piece of cut-&-paste code to "just work" is wishful thinking in the extreme!"

    exaggerated truth is a lie.

    sure, there is a degree of hardware dependency in any code, more in embedded than others. but that does not mean one piece of code written for one target cannot work for another hardware, unmodified or slightly modified (to use different header files for example).

    this is particularly true if your code is written with a logic structure and with portability in mind.

  • "Do not rely on 'for' loops - or, indeed, any othe HLL construct - for timing!"

    it depends on what the timing requirements are.

    sometimes, you don't need precise timing, or allow for large timing errors in one direction, it makes perfect sense to use simple delay loops in those cases.

    again, it is impossible to lay down a general rule, other than that you need to look into the specific applications to determine what is the best / better approach.

  • But there is this one general rule: An incorrectly written for-loop delay can be totally removed by the compiler resulting in zero delay.

    The posted code is without side effects so the OP is throwing a dice.

    You are missing out on an important ghing. When debating with beginners, it's way better to start with absolutes. Special cases are better debated at a later time, when the person have enough experience and knowledge to fully understand the details. Doing it your way means that the unexperienced developer will very, very often think: "But my code is probably so special, so I should be fine going the alternative route." And the person whill be much more hurt than first getting a truth in absolute terms and years later receiving a more modulated answer.

    If you had spent any real time reading enough thousands of threads, you would have noticed the number of people who are constantly burned by software delays just because they are too often seeing software delays and too often hearing people talking about software delays.