Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Microcontroller-Based Overcurrent Protective Relay

Status
Not open for further replies.

THE^O/\/E

Newbie level 1
Joined
Jun 1, 2010
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,294
Hi there,

I'm new to this forum and to the world of pic microcontrollers programming. I have a project I'm working on which is to design a microcontroller based overcurrent protective relay. I'm using pic16f877A chip along with **broken link removed**. I'm programming using C and I'm using HI-Tech compiler with MPLab. I've simulated the algorithm I'm using on Matlab and everything went perfect. After that I started writing the C program and when I done with it I wrote it on the microcontroller but unfortunately it didn't work well.

I’m using a method called (Four-Sample) method to identify the signal “basically taking one sample each ¼ of the period (T=1/f=1/60) and using these samples to calculate the RMS value of the current to be monitored”. After getting the RMS value I used another algorithm to implement the relaying decision part of the program. It is required to display the current value in the three lines continuously in the normal condition and then if fault occurs, the program shows a massage on the LCD and the program stop. The LCD I’m using is 128*64 dots LCD.

Note/ I’ve tested the time required to execute the code completely from the beginning to the end and I got 6 seconds!!!. I need to take a one sample every 4.167ms that’s for the three lines!!!

Here is my code. Any help would be appreciated.

Regards,

Code:
///////////////

//

// taking analog input for three lines from port E

// and using port A as a control unit for the LCD

//

//

///////////////////// 
 

#include<pic.h>

#include<math.h> 
__CONFIG(0x1832); 
#define  rs  RA5                    //COMMNAD/DATA SELECT

#define  rw  RA4                    //READ/WRITE SELECT

#define  e   RA3                    //ENABLE SIGNAL

#define  psb RA2                    //PARALLEL/SERIAL SELECT£¨H/L£ˆ

#define  rst RA0                    //RESET SIGNAL

#define  nop()  asm("nop")          //nop func 

unsigned char MM[9];

const unsigned char NNA[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','A'};

const unsigned char NNB[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','B'};

const unsigned char NNC[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','C'}; 

unsigned int lcd_x;                //X address

unsigned int lcd_y;                //Y address

bit busy;                          //busy flag 

void display(int x,unsigned int y);

void fault(int r);

void init();                        //system init.

void lcd_init();                    //LCD init

void clear_p();                    //clear screen

void flash();

void wr_zb();                       //display setting mode.

void qushu(int counts,const unsigned char *ps);       //search table.

void send_d(unsigned char x);       //send data

void send_i(unsigned char x);       //send command.

void chk_busy();                    //check busy sub.

void delay();                       //delay func, decide the speed of display.

void delay1();                      //delay func, decide the speed of blink.

void delay2();                      //delay func, to insure saving sample.

void delayad();                     //delay func, to insure the 4 samples per cycle. 
 
 

void main()

{

      int i=0x0;

      int j=0x0;

      unsigned int A[4];

      unsigned int B[4];

      unsigned int Q[4];

      unsigned int a1=0x0;

      unsigned int b1=0x0;

      unsigned int q1=0x0;

      unsigned int ip1=0x0;

      unsigned int ip2=0x0;

      unsigned int ip3=0x0;

        unsigned int pp=0x0;

      unsigned int s=0x0;

      unsigned int c=0x0;

      unsigned int ipick=0x0231;

     

        //-------

      ADRESH=0x0;

      ADRESL=0x0;

      //-------

      TRISA=0xFF;

      PORTA=0X00;

      TRISE=0x07;

      PORTC=0X00; 
 

      ADCON1=0x80; 
      for(i=0;i<4;)

                  { 

                   /////////////////////////

                   ADRESH=0x0;

                   ADRESL=0x0; 

                   ADCON0=0x41;      // teke analog from RE0 >> line A 
 
 

                   ADGO=0X1;             //start convert

                   while(ADGO);

                   delay2();   // i<0x5 

                   A[i]= ADRESH << 8 | ADRESL; 

                   ///////////////////////// 

                   /////////////////////////

                  ADRESH=0x0;

                  ADRESL=0x0; 

                  ADCON0=0x71;     // take analog input from RE1 >> line B 
 
 

                  ADGO=0X1;             //start convert

                  while(ADGO);

                  delay2();   // i<0x5 

                  B[i]= ADRESH << 8 | ADRESL; 

                  ///////////////////////// 

                  ADRESH=0x0;

                  ADRESL=0x0; 

                  ADCON0=0x79;     // take analog input from RE2 >> line C 
 
 

                  ADGO=0X1;             //start convert

                  while(ADGO);

                  delay2();   // i<0x5 

                  Q[i]= ADRESH << 8 | ADRESL; 

                  ///////////////////////// 

                  delayad(); 

      i++;

      }

     

      while(1)

      {

              //-------

              ADRESH=0x0;

              ADRESL=0x0;

              //-------

              TRISA=0xFF;

              PORTA=0X00;

              TRISE=0x07;

              PORTC=0X00;

                    TRISB=0x0;

                    PORTB=0x01;

              //-------

              ADCON1=0x80;

              //-------

               
 

               /////////////////////////

               ADRESH=0x0;

               ADRESL=0x0; 

               ADCON0=0x69;      // teke analog from RE0 >> line A 
 
 

               ADGO=0X1;             //start convert

               while(ADGO);

               delay2();   // i<0x5 

               a1= ADRESH << 8 | ADRESL; 

               ///////////////////////// 

               /////////////////////////

              ADRESH=0x0;

              ADRESL=0x0; 

              ADCON0=0x71;     // take analog input from RE1 >> line B 
 
 

              ADGO=0X1;             //start convert

              while(ADGO);

              delay2();   // i<0x5 

              b1= ADRESH << 8 | ADRESL; 

              ///////////////////////// 

              ADRESH=0x0;

              ADRESL=0x0; 

              ADCON0=0x79;     // take analog input from RE2 >> line C 
 
 

              ADGO=0X1;             //start convert

              while(ADGO);

              delay2();   // i<0x5 

              q1= ADRESH << 8 | ADRESL; 

              ///////////////////////// 

              for(i=0;i<3;)      // shift the samples in the arrays to make room for

              {                  // the new sample

              A[i]=A[i+1];

              B[i]=B[i+1];

              Q[i]=Q[i+1]; 

              i++;

              } 

              A[3]=a1;

              B[3]=b1;

              Q[3]=q1; 

              //---------

             

              s=0x0;

              c=0x0;

             

              s=A[0]+A[1]-A[2]-A[3];

              c=A[0]-A[1]-A[2]+A[3];

             

              ip1=(sqrt((s*s)+(c*c)));

              ip1=ip1>>2; // ip1/4

             

              //---------

             

              s=0x0;

              c=0x0; 

              s=B[0]+B[1]-B[2]-B[3];

              c=B[0]-B[1]-B[2]+B[3]; 

              ip2=sqrt(((s*s)+(c*c)));

              ip2=ip2>>2; 

              //----------

             

              s=0x0;

              c=0x0; 

              s=Q[0]+Q[1]-Q[2]-Q[3];

              c=Q[0]-Q[1]-Q[2]+Q[3]; 

              ip3=sqrt(((s*s)+(c*c)));

              ip3=ip3>>2;

             

               //-----------------------

               // scale the voltage level here to the value of the current before

               // the conditioning circuit.

               //-----------------------

     

                      //ip3=0x0275; 
                        init();                 //initiate the ports for the LCD display

          lcd_init();    //LCD initiation.      

                        clear_p();    //LCD clear 

                     //pp=(A[0]+A[1]+A[2]+A[3])/4;

               display(0x1,pp);

               display(0x2,ip2);

               display(0x3,ip3); 

               //-------

               // disicion

               //-------

              

                
 
 

              //------- 

              if(ip1>ipick)

              {

                fault(0x1);

              }

              //else

              //{ display(0x1,ip1); }

               
              if(ip2>ipick)

              {

                fault(0x2);

              }

              //else

              //{ display(0x2,ip2); }

             

              if(ip3>ipick)

              {

                fault(0x3);

              }

             // else

             // { display(0x3,ip3); }

             

             

             

         PORTB=0x0;

             delay1();   

        } // end of the while(1) loop 
 
 
 
 
 
 
 
 
}  // end of main function 
///------------------------------------- 
void display(int x,unsigned int y)

{

       

        

        if(x==0x1)

         {

           MM[0]=76;                // L

          MM[1]=45;                // -

          MM[2]=49;                // 1

          MM[3]=61;                // =

          MM[4]=(5*y/1024)+48;     // first digit

          MM[5]=46;                // point (.)

          MM[6]=((50*y/1024)%10)+48; // second digit

          MM[7]=((20*y/41)%10)+48;   // third digit

          MM[8]=65;                 //  A for Amp 

          send_i(0x80);  /// search what is the thing 

          qushu(0x9,MM);

         } 

         if(x==0x2)

         {

          MM[0]=76;                 // L

          MM[1]=45;                 // -

          MM[2]=50;                 // 2

          MM[3]=61;                 // =

          MM[4]=(5*y/1024)+48;      // first digit

          MM[5]=46;                 // point (.)

          MM[6]=((50*y/1024)%10)+48; // second digit

          MM[7]=((20*y/41)%10)+48;  // third digit

          MM[8]=65;                 // A for Amp 

          send_i(0x90); 

          qushu(0x9,MM);

         } 

         if(x==0x3)

         {

          MM[0]=76;               // L

          MM[1]=45;              // -

          MM[2]=51;               // 3

          MM[3]=61;               // =

          MM[4]=(5*y/1024)+48;    // first digit

          MM[5]=46;               // point (.)

          MM[6]=((50*y/1024)%10)+48; // second digit

          MM[7]=((20*y/41)%10)+48;  // third digit

          MM[8]=65;                // A for Amp 
 

          send_i(0x88); 

          qushu(0x9,MM); 

         } 
 
 

        delay1();                     //

        //clear_p();                   // 
 
 

}

//---------------- 
void fault(int r)

{

      init();                      //system init.

      lcd_init();                  //

      clear_p();                   // 

      send_i(0x90);

     

      if(r==0x1)

      {

         qushu(0xd,NNA);

      }

     

      if(r==0x2)

      {

          qushu(0xd,NNB);

      }

     

      if(r==0x3)

      {

          qushu(0xd,NNC);

      } 
      delay1();                     //

      flash();

      clear_p();

     

     

}

//----------

void flash()

{

  send_i(0x08);                  //off display.

  delay1();                      //delay

  send_i(0x0c);                  //on display

  delay1();

  delay1();                      //delay

  send_i(0x08);                  //off

  delay1();

  send_i(0x0c);                  //on

  delay1();

  delay1();

  send_i(0x08);                  //off

  delay1();

  send_i(0x0c);                  //on

  delay1();

  delay1();

}

//------------ 
 
 

///---------------- 
void init()

{

  TRISA=0X00;                       //A port as output

  TRISD=0X00;                       //d port as output

  ADCON1=0X06;                      //A port as ordinary i/o

}

///// 

void lcd_init()

{

  rst=0;                         //reset LCD

  delay();

  rst=1;                         //LCD normal work.

  nop();

  psb=1;                         //8 bit as parrallel.

  send_i(0x30);                  //basic operation instruction

  send_i(0x01);                  //off display

  send_i(0x06);                  //set the cursor's moving direction.

  send_i(0x0c);                  //on display,off cursor,off blink

} 

//// 

void wr_zb()

{

  send_i(lcd_y);

  send_i(lcd_x);

} 

///// 

void clear_p()

{

  send_i(0x1);                   //clear all

  send_i(0x34);                  //extend.

  send_i(0x30);                  //basic

} 

//// 

void qushu(int counts,const unsigned char *ps)

{

  int i;                         //define loop count.

  for(i=counts;i>0;i--)          //

     {

        send_d(*ps);             //

        delay();                 //

        ps++;                    //get next.

     }

} 

//// 

void send_d(unsigned char x)

{

   chk_busy();                  //check busy.

   rs=1;                        //data not commnad.

   rw=0;                        //write not read.

   PORTD=x;                     //data to bus.

   e=1;                         //enable.

   nop();

   nop();

   nop();

   e=0;                         //disable.

} 

//// 

void send_i(unsigned char x)

{

   chk_busy();                   //check lcd if busy.

   rs=0;                         //data not commnad.

   rw=0;                         //write not read.

   PORTD=x;                      //data to bus.

   e=1;                          //enable.

   nop();

   nop();

   nop();

   e=0;                         //disable.

} 

//// 

void chk_busy()

{

   busy=1;                      //set busy signal

   TRISD=0XFF;                  //change the bus to input.

   rs=0;                        //command not data.

   rw=1;                        //read not write.

   while(busy)

      {

         nop();

         nop();

         nop();

         e=1;                   //enable.

         nop();

         nop();

         nop();

         if(!RD7) busy=0;       //

         nop();

         nop();

         nop();

         e=0;                   //DISABLE.

      }

   e=0;                         //DISABLE.

   TRISD=0X00;                  //bus as output.

}

 

////

  

//// 

void delayad()

{

    int i;

    for(i=0;i<0x100;i++)

       {;}

}

////

 

void delay()

{

    int i;

    for(i=0;i<5000;i++)

       {;}

} 

//-------------------------------------------

//delay1

void delay1()

{

    int i;

    for(i=0;i<10;i++)

      {

        delay();               //call delay.

      }

}

////

void delay2()

{

    int i;

    for(i=0;i<0x5;i++)

       {;}

}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top