title: initialization function for pic microcontroller
body: <p>I am trying to get a pic16 controller to run an initialization function that displays some text on an LCD only once and then goes on to display other things</p>
  
  <p>The LCD output is working fine the problem is that the initialization function keeps executing. What am I doing wrong ?</p>
  
  <pre><code>/*
   * File:   main.c
   *
   * Created on Sep 1, 2013, 12:09 PM
   */
  
  
  #include &lt;pic.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  #include "delay.h"
  
  __CONFIG(WDTE_ON &amp; PWRTE_ON &amp; MCLRE_ON &amp; BOREN_ON &amp; FOSC_INTRCIO );
  
  static int exec_counter = 0;
  
  #define set_bit(ADDRESS,BIT) (ADDRESS |= (1&lt;&lt;BIT))      // bit mask macros
  #define clear_bit(ADDRESS,BIT) (ADDRESS &amp;= ~(1&lt;&lt;BIT))
  #define flip_bit(ADDRESS,BIT) (ADDRESS ^= (1&lt;&lt;BIT))
  #define test_bit(ADDRESS,BIT) (ADDRESS &amp; (1&lt;&lt;BIT))
  #define E  RC4         //  Define the LCD Control Pins
  #define RS RC5
  int i;                 //  Use Global Variables for Debug
  
  LCDWrite(int LCDData, int RSValue)
  {
  
      PORTC = (LCDData &gt;&gt; 4) &amp; 0x0F;  //  Get High 4 Bits for Output
      RS = RSValue;
      E = 1;  E = 0;                   //  Toggle the High 4 Bits Out
  
      PORTC = LCDData &amp; 0x0F;          //  Get Low 4 Bits for Output
      RS = RSValue;
      E = 1;  E = 0;                   //  Toggle the Low 4 Bits Out
  
      if ((0 == (LCDData &amp; 0xFC)) &amp;&amp; (0 == RSValue))
          DelayMs(5);
      else
          DelayUs(200);
  
  }  //
  
  void writeLines(char top[],char bottom[]){
      for (i = 0; top[i] != 0; i++)   //  Write Line 1
          LCDWrite(top[i], 1);
  
      LCDWrite(0b11000000, 0);        //  Move Cursor to the Second Line
  
      for (i = 0; bottom[i] != 0; i++)//  Write Line 2
          LCDWrite(bottom[i], 1);
  
  }
  
  int countelems(char arr[]){
      for (i = 0; arr[i] != 0; i++){}
      return i;
  }
  void pad_number(char number[],char numberout[],char unit[]){
      int size_n = countelems(number);        // get length of number array by reference
      int size_u = countelems(unit);          // get length of unit array by reference
      int size = size_u + size_n + 1;         // calculate total size of text with 1 space between number and unit
      int L_space = floor((16-size)/2)-1;     // calculate space required on left side of display to center text
      for (i = 0; i &lt;= 15; i++)
          numberout[i] = 0b10100000;          // fill output char array with spaces
      for (i = 0; i &lt;= (size_n); i++){
          numberout[i+(L_space+1)] = number[i];       // fill output char array with number
      }
      numberout[L_space+size_n+1] = 0b10100000;       // put space in output char array between number and unit
      for (i = 0; i &lt;= size_u; i++){
          numberout[i+(L_space+size_n+2)] = unit[i];  // fill output char array with unit
      }
  }
  void pad_text(char text[],char textout[]){
      int size = countelems(text);            // get length of char array by reference
      int L_space = floor((16-size)/2);       // calculate space required on left side of display to center text
      for (i = 0; i &lt;= 15; i++)
          textout[i] = 0b10100000;            // fill output char array with spaces
      for (i = 0; i &lt;= 15; i++){
          if( i &gt;= L_space &amp;&amp; i &lt;= (L_space+size)){
              textout[i] = text[i-L_space];   // fill middle of output char array with text
          }
      }
  }
  void getAnalog(int channel,char parameter[], char unit[]){
      char output_parameter[16];
      char output_number[16];
      char number[16];
      ADCON0 = channel &lt;&lt; 2;                  // select channel
      //set_bit(ADCON0,7);                    // set ADFM flag so LSB is bit 0 of ADRESL
      set_bit(ADCON0,0);                      // switch ADC on = set ADON flag 0b00000001
      sampleTime();                           // wait required aquisition time
      set_bit(ADCON0,1);                      // start conversion = set GO/DONE bit
      while(test_bit(ADCON0,1)){/* wait for ADC to complete conversion */;}
      int ADCresult = (ADRESL+ADRESH)/10;     // get result from ADC
      itoa(number,ADCresult,10);              // convert ADC result to charstring
      LCDWrite(0b00000001, 0);                //  Clear LCD
      pad_text(parameter,output_parameter);
      pad_number(number,output_number,unit);
      writeLines(output_parameter, output_number);
  }
  void init(){
      DelayMs(20);                //  Wait for LCD to Power Up
  
      PORTC = 3;                  //  Start Initialization Process
      E = 1;  E = 0;              //  Send Reset Command
      DelayMs(5);
  
      E = 1;  E = 0;              //  Repeat Reset Command
      DelayUs(200);
  
      E = 1;  E = 0;              //  Repeat Reset Command Third Time
      DelayUs(200);
      PORTC = 2;                  //  Initialize LCD 4 Bit Mode
      E = 1;  E = 0;
      DelayUs(200);
  
      LCDWrite(0b00101000, 0);    //  LCD is 4 Bit I/F, 2 Line
  
      LCDWrite(0b00000001, 0);    //  Clear LCD
  
      LCDWrite(0b00000110, 0);    //  Move Cursor After Each Character
  
      LCDWrite(0b00001110, 0);    //  Turn On LCD and Enable Cursor
      //          "0123456789012345"
      writeLines( "  INITIALIZE    ",
                  "     TEXT       ");
  
  }
  void main(void) {
      OPTION_REG |= 0x7;  // set prescaler to 1:128 or 2.3 Seconds
      OPTION_REG |= 0x8;  // assign prescaler to WDT
      TRISA = 0b00000101; // configure PORTA set RA0 and RA2 to analog input;
      ANSEL = 0b00000101; // disable input buffers if I/O pins RA0 and RA2
      TRISC = 0;          // configure PORTC as output
      ADCON1 = 0;         // select FOSC2
      if (exec_counter == 0){
          exec_counter++;
          init();
          DelayS(4);
      }
      PORTC = 0;
  
      while (1) {
          getAnalog(0,"VELOCITY","KM/H");
          DelayS(4);
          getAnalog(2,"ACCELERATION","M/S^2");
          DelayS(4);
      }
      return;
  }
  
  /*
   * File:   delay.c
   *
   * Created on Sep 3, 2013, 12:09 PM
   */
  
  #include "delay.h"
  #include &lt;pic.h&gt;
  #define _XTAL_FREQ 4000000
  
  void DelayMs(unsigned char cnt)
  {
  #if XTAL_FREQ &lt;= 2MHZ
          do {
                  DelayUs(996);
          } while(--cnt);
  #endif
  
  #if    XTAL_FREQ &gt; 2MHZ
          unsigned char   i;
          do {
                  i = 4;
                  do {
                          DelayUs(250);
                  } while(--i);
          } while(--cnt);
  #endif
  }
  
  void DelayS(unsigned int count){
      for (int i=0; i&lt;=count;i++){
          NOP();
          CLRWDT();
          DelayMs(1000);
      }
  }
  
  void sampleTime(){
      // TC = – 10pF ( 1k Ω + 7k Ω + 1k Ω ) ln(0.0004885)
      //    = 0.686 μS
      // TACQ = 5μS + 0.686μS + [ ( 50°C- 25°C ) ( 0.05μ S /°C ) ]
      //      = 6.936 μS /
      // 1 instruction cycle = 4μS @ 1 mHz
      // 1 instruction cycle = 1μS @ 4 mHz
      // 1 instruction cycle = 500nS @ 8 mHz
      // 1 instruction cycle = 200nS @ 20 mHz
      // TACQ @  1 mHz is 6.936 μS / 4 μS   or ~  2  instruction cycles
      // TACQ @  4 mHz is 6.936 μS / 1 μS   or ~  7  instruction cycles
      // TACQ @  8 mHz is 6.936 μS / 0.5 μS or ~  14 instruction cycles
      // TACQ @ 20 mHz is 6.936 μS / 0.2 μS or ~  35 instruction cycles
      DelayUs(8);
  }
  </code></pre>