PIC16F877A problem with Routine too Large

General discussion on mikroC.
Post Reply
Author
Message
Killing Tank
Posts: 4
Joined: 12 Oct 2010 09:11

PIC16F877A problem with Routine too Large

#1 Post by Killing Tank » 13 Oct 2010 00:01

Hi everyone, i am programming a controller for a Piezoelectric Transducer Actuator and have come up with the error Routine too large. I have tried many methods of overcoming it but still have not found the solution. Please help me in way you can.
I have commented out Case 7 since it runs perfectly without it, but the problem is when you delete the comments, this is relevant also if you uncomment some of the other cases.

Thank you.

Here is the code:

Code: Select all


    char kp, kp2, kp3, kp4, kp5, kp6, Emergency, Resume, State, Cancel, Check;
    float StepSize, Resol, kv, kv2, kv3, kv4, kv5, kv6, See, Voltage, Frequency, Amplitude;

    char Text[15];
    
    const char *Intro = "Step:1 Cont:2";
    const char *StepSet = "Step Mode Set";
    const char *ContSet = "Cont Mode Set";
    const char *Size = "Enter Step Size";
    const char *Displacement = "Enter Displ mm";
    const char *UpDown = "Incr:1  Decr:2";
    const char *Freq = "Enter Freq kHz";


    const char lookup[] = {'U','1','2','3','U','4','5','6','U','7','8','9','U','*'
                          ,'0','#','U'};


    void strConstCpy (char *dest, const char *source) {
    while(*source)
    *dest++ = *source++ ;

    *dest = 0 ;
                                                     }


    void main()
    {
    //Pwm_Init(1000);
    //Pwm_Start();
    State = 0;
    CMCON = 7;   //Comparators off
    TRISA = 0b000001;    // ,Set Bit 0 as Input
    TRISB = 0b11111111;    //Set all Bits as Inputs for the Keypad
    TRISC = 0b00011100;     // Bit 7 (Sound) as an output, Bits 4 to 2
    //Cancel, Emergency Stop, Resume) as Inputs, Bit 0 (Actuator) as an output
    TRISD = 0b00000000; // Set Port D as Outputs for the LCD

    ADCON0 = 0b00000001;     //Set Fosc/8 and turn Convertor on
    ADCON1 = 0b00000000;     // Set PORTA.F0 as an Analog Input

    LCD_Config(&PORTD,7,6,5,3,2,1,0);
    LCD_Cmd(LCD_CLEAR);
    LCD_Cmd(LCD_CURSOR_OFF);
    
    strConstCpy(Text,Intro);
    LCD_OUT(1,1,Text);

    Keypad_Init(&PORTB) ;

    while(1){

    switch (State){

    case 0:
    PORTA.F0 = 0; //  Set Actuator Position to Initial 0 Volts
    State = 1;
    break;


    case 1:
    while(!keypad_Read()){}
    kp = Keypad_Released();
    kv = lookup[kp];
    LCD_Chr(2,1,kv);

    if(kv == '1')    //Step mode selected
    {
    State = 2;
    strConstCpy(Text,StepSet);
    LCD_OUT(1,1,Text);
    }
    else
        {
    State = 3;
    strConstCpy(Text,ContSet);
    LCD_OUT(1,1,Text);
        }
    break;



    case 2:
    Delay_ms(100);
    LCD_Cmd(LCD_CLEAR);
    strConstCpy(Text,Size);
    LCD_OUT(1,1,Text);

    while(!keypad_Read()){}
    kp2 = Keypad_Released();
    Delay_ms(10);
    kv2 = lookup[kp2];
    //Delay_ms(1);
    if (kv2=='#')
    {
    kv2=0;
    StepSize = kv2;
    State = 4;
    break;
    }
    else
         {
    LCD_Chr(2,1,kv2);
    LCD_OUT(2,2,".");
         }

    while(!keypad_Read()){}
    kp3 = Keypad_Released();
    Delay_ms(10);
    kv3 = lookup[kp3];
    //Delay_ms(1);
    if (kv3=='#')
    {
    StepSize = kv2;
    State = 4;
    break;
    }
    else
           {
    LCD_Chr(2,3,kv3);
           }

    while(!keypad_Read()){}
    kp4 = Keypad_Released();
    Delay_ms(10);
    kv4 = lookup[kp4];
    //Delay_ms(1);
    if (kv4=='#')
    {
    StepSize = kv2 + (0.1 * kv3);
    State = 4;
    break;
    }
    else
        {
    LCD_Chr(2,4,kv4);
        }

    while(!keypad_Read()){}
    kp5 = Keypad_Released();
    Delay_ms(10);
    kv5 = lookup[kp5];
    Delay_ms(1);
    if (kv5=='#')
    {
    StepSize = kv2 + (0.1 * kv3) + (0.01 * kv4);
    State = 4;
    break;
    }
    else
        {
    LCD_Cmd(LCD_CLEAR);
    Delay_ms(100);
    State = 2;
        }

    break;

    case 3:
    Delay_ms(100);
    LCD_Cmd(LCD_CLEAR);
    strConstCpy(Text,Displacement);
    LCD_OUT(1,1,Text);

    while(!keypad_Read()){}
    kp2 = Keypad_Released();
    Delay_ms(10);
    kv2 = lookup[kp2];
    if (kv2=='#')
    {
    kv2=0;
    State = 7;
    break;
    }
    else
         {
    LCD_Chr(2,1,kv2);
         }

    while(!keypad_Read()){}
    kp3 = Keypad_Released();
    Delay_ms(10);
    kv3 = lookup[kp3];
    if (kv3=='#')
    {
    Amplitude = kv2;
    State = 7;
    break;
    }
    else
           {
    LCD_Chr(2,2,kv3);
    LCD_OUT(2,3,".");
           }

    while(!keypad_Read()){}
    kp4 = Keypad_Released();
    Delay_ms(10);
    kv4 = lookup[kp4];
    if (kv4=='#')
    {
    Amplitude = kv2 + (0.1 * kv3);
    State = 7;
    break;
    }
    else
        {
    LCD_Chr(2,4,kv4);
        }

    while(!keypad_Read()){}
    kp5 = Keypad_Released();
    Delay_ms(10);
    kv5 = lookup[kp5];
    if (kv5=='#')
    {
    Amplitude = kv2 + (0.1 * kv3) + (0.01 * kv4);
    State = 7;
    break;
    }
    else
        {
    State = 3;
        }
    break;

    case 4:
    Resol = StepSize * (0.0000167);
    State = 5;
    break;

    case 5:
    LCD_Cmd(LCD_CLEAR);
    strConstCpy(Text,UpDown);
    LCD_OUT (1,1,Text);

    while(!keypad_Read()){}
    Check = Keypad_Released();         //Checks to see if the Increase or Decrease
    Delay_ms(10);                      //Button was pressed
    See = lookup[Check];
    Delay_ms(1);
    if(See == '1')
    {
    State = 6;
    LCD_Cmd(LCD_CLEAR);                                //Increase
    break;
    }
    else
        {
        LCD_Cmd(LCD_CLEAR);
        Voltage = PORTA.F0;
        Delay_ms(1);                      //Decrease
        if(Voltage = 0)
          {
          State = 10;
          }
    else
            {
            State = 9;
            }
         }
    break;

    case 6:
    Voltage = PORTA.F0 + Resol;             //Increase PZT piston length


    if(Voltage > 0.02)                    //check if Maximum reached
    {
    State = 10;                           //goes to state 10 for the sound to be played
    }
    else
        {
        State = 6;
        }
    break;

//    case 7:
//    Delay_ms(100);
//    LCD_Cmd(LCD_CLEAR);
//    strConstCpy(Text,Freq);
//    LCD_OUT(1,1,Text);

//    while(!keypad_Read()){}
//    kp2 = Keypad_Released();
//    Delay_ms(10);
//    kv2 = lookup[kp2];
//    if (kv2=='#')
//    {
//    kv2=0;
//    State = 8;
//    break;
//    }
//    else
//         {
//    LCD_Chr(2,1,kv2);
//    LCD_OUT(2,2,".");
//         }

//    while(!keypad_Read()){}
//    kp3 = Keypad_Released();
//    Delay_ms(10);
//    kv3 = lookup[kp3];
//    if (kv3=='#')
//    {
//    Frequency = kv2;
//    State = 8;
//    break;
//    }
//    else
//           {
//    LCD_Chr(2,3,kv3);
//           }

//    while(!keypad_Read()){}
//    kp4 = Keypad_Released();
//    Delay_ms(10);
//    kv4 = lookup[kp4];
//    if (kv4=='#')
//    {
//    Frequency = kv2 + (0.01 * kv3);
//    State = 8;
//    break;
//    }
//    else
//           {
//    State = 7;
//           }

    break;

//    case 8:
//    Voltage =  Amplitude * SinE3(2* 3.14 * Frequency * (1/Frequency));
//    State = 11;                                //Calculate Sine Wave
//    break;
//
    case 9:
    Voltage = PORTA.F0 - Resol;
    if(Voltage = 0)
    {
    Sound_Init(&PORTC, 7);
    Sound_Play(1000, 100);
    State = 5;
    break;
    }
    else
      {
      State = 9;
      }
    break;

    case 10:
    Sound_Init(&PORTC, 7);
    Sound_Play(1000, 100);
    State = 5;
    break;

//    case 11:
//    Pwm_Change_Duty(Voltage);
//    State = 12;   //how do you generate it and send?
//    break;
//
//    case 12:
//    while(!keypad_Read()){}
//    kp6 = Keypad_Released();
//    Delay_ms(10);                            //check for Stop button
//    kv6 = lookup[kp6];
//
//    if(kv6 == '*')
//    {
//    State = 3;                                //Stop Button pressed
//    break;
//    }
//    else
//      {
//      State = 11;
//      }
//    break;

    default:
    State = 0;
    break;
                }//End Swtich State
          }//End While Ever
    }//End Void Main






Killing Tank
Posts: 4
Joined: 12 Oct 2010 09:11

Re: PIC16F877A problem with Routine too Large

#2 Post by Killing Tank » 18 Oct 2010 00:13

Bump

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: PIC16F877A problem with Routine too Large

#3 Post by filip » 02 Nov 2010 11:17

Hi,

In applications targeted at PIC16, no single routine should exceed one page (2,000 instructions). If routine does not fit within one page, linker will report an error.
When confront with this problem, maybe you should rethink the design of your application – try breaking the particular routine into several chunks, etc.

Regards,
Filip.

netos
Posts: 36
Joined: 15 Aug 2008 01:03

Re: PIC16F877A problem with Routine too Large

#4 Post by netos » 07 Nov 2010 15:19

use pic18f452 instead of pic16f877a. it has almost the same price and more powerful :)

Killing Tank
Posts: 4
Joined: 12 Oct 2010 09:11

Re: PIC16F877A problem with Routine too Large

#5 Post by Killing Tank » 08 Nov 2010 05:10

Yes I have come to the conclusion that the PIC was the problem, now that problem has been solved but a new obstacle has shown up... How do you use Digital to Analog Conversion in a PIC18F452?

netos
Posts: 36
Joined: 15 Aug 2008 01:03

Re: PIC16F877A problem with Routine too Large

#6 Post by netos » 08 Nov 2010 16:58

just same as pic16 devices.
read the device datasheet about configuring ADCONx registers and TRISx registers.
some devices olso have analog comparators sharing the analog pins. So you may configure CMCON registers if you don't use them

Killing Tank
Posts: 4
Joined: 12 Oct 2010 09:11

Re: PIC16F877A problem with Routine too Large

#7 Post by Killing Tank » 16 Nov 2010 02:12

netos wrote:just same as pic16 devices.
read the device datasheet about configuring ADCONx registers and TRISx registers.
some devices olso have analog comparators sharing the analog pins. So you may configure CMCON registers if you don't use them

you misread my post i said "Digital to Analog" i want to send Analog signals to my PZT (Piezoelectric Transducer) i am familiar with the Analog to Digital Conversion Module, but what about the reverse?

netos
Posts: 36
Joined: 15 Aug 2008 01:03

Re: PIC16F877A problem with Routine too Large

#8 Post by netos » 12 Dec 2010 21:42

oh i'm so sorry about this.

if your transducers does not need fast settling time of digital-to-analog converter, mcu's pwm outputs are good for you. otherwise you need external DACs

Post Reply

Return to “mikroC General”