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

Code not working on LPC2148 board

I bought an ARM LPC2148 Development board and started uploading code in it.  I wrote the code to blink the on-board 4 LEDs.  It gets uploaded successfully in the board but the LEDs never blink (leave alone the blinking according to the code).  I have rechecked the code again and again.  I am getting 0 V on the pins(P1.16, P1.17, P1.18, P1.19) to which the LEDs are connected.  I cannot figure out why this is happening.  Help!!

The code is:-

#include  <lpc214x.h> //Includes LPC2148 register definitions
#define LED1_ON() IO1SET=(1<<16) //Macro Functions to turn ON LED

#define LED2_ON() IO1SET=(1<<17)

#define LED3_ON() IO1SET=(1<<18)

#define LED4_ON() IO1SET=(1<<19)

#define LED1_OFF() IO1CLR=(1<<16) //Macro Functions to turn OFF LED

#define LED2_OFF() IO1CLR=(1<<17)

#define LED3_OFF() IO1CLR=(1<<18)

#define LED4_OFF() IO1CLR=(1<<19)

void  Delay(unsigned char j)    //This Function is used to cause delay between LED ON and OFF events

{

unsigned int  i;

for(;j>0;j--)

{

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

}

}

int  main(void)

{

PINSEL0 = 0x00000000; // Enable GPIO on all pins

PINSEL1 = 0x00000000;

PINSEL2 = 0x00000000;

IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16); // Set P1.16, P1.17, P1.18, P1.19 as Output
while(1)

{

  LED1_ON();

  Delay(25);

  LED1_OFF();

  LED2_ON();

  Delay(25);

  LED2_OFF();

  LED3_ON();

  Delay(25);

  LED3_OFF();

  LED4_ON();

  Delay(25);

  LED4_OFF();

}

return(0);

}

Parents
  • Hi Peter,

    I'm glad you're here to help.

    Delay is a usual problem in LED blinking program like this. However, I deferred to focus on that since if we analyze the code, regardless of the delay, P1.16 to P1.19 (and, supposedly, the LEDs) are always switched at 25% duty cycle. Here, the delay only affects the frequency of switching. If the delay is too short the LEDs will be sequenced at very high speed. mayankv2 would not notice them blink in succession. Instead, the LEDs will appear to be simultaneously lit albeit faint. Some factors can prevent the LEDs from working that way but at least there will be small voltages measured at P1.16 to P1.19, this was not observed by mayankv2.

    I am getting 0 V on the pins(P1.16, P1.17, P1.18, P1.19) to which the LEDs are connected.

    That's why I asked that the measurement be verified. Another reason why I deferred to point to delay is that in mayankv2's reply

    Also, I noted a strange behavior.  The pin P1.23 and P1.22 are always high in my board.  I wrote a simply code to output LOW on P1.23 and P1.22 but again they gave high voltage.

    If the objective of the code is to output a static low to P1.23 and P1.22, delay is not involved anymore but this problem surfaced.

    Nevertheless, your suggested remedy to your suspected cause of the trouble is a brilliant idea and I suggest that mayankv2 should try any of these:

    • Following your recommended modification to make j and i volatile (or maybe i only?).
    • Turning off compiler optimization of this kind (just for this exercise).
    • Another method used by programmers in preventing the compiler from omitting an empty loop is to insert something functional (from the point of view of a compiler) into the delay loop. The modification to the Delay function shown below is an example. However, it has an additional variable and statements and may not be immune to other type(s) of optimization.

    void  Delay(unsigned char j)   //This Function is used to cause delay between LED ON and OFF events

    {

    unsigned int  i,k;

    for(;j>0;j--)

    {

      k=0;

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

      {

        // Dummy operation(s) here so that the compiler will not optimize the loop as if it does not exist at all

        k++;

      }

    }

    }

    Regards,

    Goodwin

Reply
  • Hi Peter,

    I'm glad you're here to help.

    Delay is a usual problem in LED blinking program like this. However, I deferred to focus on that since if we analyze the code, regardless of the delay, P1.16 to P1.19 (and, supposedly, the LEDs) are always switched at 25% duty cycle. Here, the delay only affects the frequency of switching. If the delay is too short the LEDs will be sequenced at very high speed. mayankv2 would not notice them blink in succession. Instead, the LEDs will appear to be simultaneously lit albeit faint. Some factors can prevent the LEDs from working that way but at least there will be small voltages measured at P1.16 to P1.19, this was not observed by mayankv2.

    I am getting 0 V on the pins(P1.16, P1.17, P1.18, P1.19) to which the LEDs are connected.

    That's why I asked that the measurement be verified. Another reason why I deferred to point to delay is that in mayankv2's reply

    Also, I noted a strange behavior.  The pin P1.23 and P1.22 are always high in my board.  I wrote a simply code to output LOW on P1.23 and P1.22 but again they gave high voltage.

    If the objective of the code is to output a static low to P1.23 and P1.22, delay is not involved anymore but this problem surfaced.

    Nevertheless, your suggested remedy to your suspected cause of the trouble is a brilliant idea and I suggest that mayankv2 should try any of these:

    • Following your recommended modification to make j and i volatile (or maybe i only?).
    • Turning off compiler optimization of this kind (just for this exercise).
    • Another method used by programmers in preventing the compiler from omitting an empty loop is to insert something functional (from the point of view of a compiler) into the delay loop. The modification to the Delay function shown below is an example. However, it has an additional variable and statements and may not be immune to other type(s) of optimization.

    void  Delay(unsigned char j)   //This Function is used to cause delay between LED ON and OFF events

    {

    unsigned int  i,k;

    for(;j>0;j--)

    {

      k=0;

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

      {

        // Dummy operation(s) here so that the compiler will not optimize the loop as if it does not exist at all

        k++;

      }

    }

    }

    Regards,

    Goodwin

Children
  • Just adding an increment of an integer isn't enough to stop an optimizing compiler removing  the loop (the value of k is never used, so will be dropped, and what is left is still an empty loop).

    Generally you either need (1) something which writes back to a volatile memory location, or (2) something which is passed outside of the translation unit.

    Just disabling optimization is probably a good starting point for debugging, but if in doubt it's always sensible to disassemble the binary if you are not sure =)

    Pete

  • Just disabling optimization is probably a good starting point for debugging, but if in doubt it's always sensible to disassemble the binary if you are not sure =)

    I agree.

    Just adding an increment of an integer isn't enough to stop an optimizing compiler removing  the loop (the value of k is never used, so will be dropped, and what is left is still an empty loop).

    That's a reason why I stated skepticism on that approach in my previous reply. I included that kind of workaround because I encountered it in some articles and tutorials, I wonder how their program seem to work (as they claim) >:\

    Iterating a NOP is common in creating delay in assembly language. Although NOP is not guaranteed to acquire processing time in newer high-performance processors, it may be possible to use it to avoid an empty loop in C/C++. Below, the Delay function is modified by placing a __nop() in the inner loop (not necessarily to consume clock cycle/s although in the case of Delay expending time is beneficial).

    void  Delay(unsigned char j)   //This Function is used to cause delay between LED ON and OFF events

    {

    unsigned int  i;

    for(;j>0;j--)

    {

      for(i=0; i<60000; i++) __nop();

    }

    }

    GCC's optimization results in no code generated for asm("mov r0,r0") and to prevent that, we turn to volatile again, asm volatile("mov r0, r0"). On the other hand, the above code may work without appealing to a volatile qualifier. The armcc User Guide states that the compiler does not optimize away the NOP instructions inserted by the __nop intrinsic.