SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By karlwr
#176861
Hi all, I have a Little problem getting my LPC2119 to work as I want it to.

Im running a ET-ARM et-arm stamp lpc2119 with GNU arm compiler in µVision3

Im trying to interface a push button with 2LEDs. Using one LED works but not 2.
The compiler does not complain or give me an error.

Here is the code that works, a push button to p0.7 and a LED to p1.18

!

include <LPC21xx.H> // LPC2119 MPU Register

int main(void)
{
PINSEL2 &= ~0x0000000C; // Makesure GPIO1.16-1.31 = GPIO Function,
PINSEL0 &= ~0x0000C000; //GPIO P0.7,
IODIR1 |=(1<<18); // GPIO 1.18 as output
IODIR0 &=~((1<<7)); // Set GPIO0.7 AS input

while(1) // Loop Continue
{

if(!(IOPIN0 & (1<<7))) // When button is pressed

{
IOSET1 |=(1<<18);
}
else
{
IOCLR1 =(1<<18);
}

Here is the code that does not work, 2 LEDs on p1.16 and p1.18, and the push button on p0.7

Im trying to set that when the button is pressed LED1 on and LED2 off, when button not pressed then LED2 on and LED2 off but it only works as Before with one LED turning on and off, the second LED never turns off.!! :(. What is it that I'm missing

include <LPC21xx.H> // LPC2119 MPU Register

int main(void)
{
PINSEL2 &= ~0x0000000C; // Makesure GPIO1.16-1.31 = GPIO Function,
PINSEL0 &= ~0x0000C000; //GPIO P0.7,
IODIR1 |=((1<<16)|(1<<18)); // GPIO p1.18 and p1.16 as output
IODIR0 &=~((1<<7)); // Set GPIO0.7 AS input

while(1) // Loop Continue
{

if(!(IOPIN0 & (1<<7))) // When button is pressed

{
IOSET1 |=(1<<18);
IOCLR1 =(1<<16);
}
else
{
IOCLR1 =(1<<16);
IOCLR1 =(1<<18);
}

}

}
By cfb
#176896
Both your if and your else sections are identical so they will do the same thing whether your button is pressed or not:
Code: Select all
{
    IOSET1 |=(1<<18);
    IOCLR1 |=(1<<16);
}
else 
{
    IOSET1 |=(1<<18);
    IOCLR1 |=(1<<16);
}
e.g. switch the leds around in the else section
Code: Select all
{
    IOSET1 |= (1<<18);
    IOCLR1 |= (1<<16);
}
else 
{
    IOSET1 |= (1<<16);
    IOCLR1 |= (1<<18);
}
I haven't checked the rest of your code so there might be more errors but you'll be one step closer.
By karlwr
#176908
Sry, I was tierd when I wrote this after a weeks hard work finding a lot of bugs at work.

This is my code for the 2LEDs.
Code: Select all
int main(void)
{  
PINSEL2 &= ~0x0000000C;					// Makesure GPIO1.16-1.31 = GPIO Function, 
PINSEL0 &= ~0x0000C000;					  //GPIO P0.7,  
IODIR1 |=((1<<18)|(1<<16));						  // GPIO 1.18 as output
IODIR0  &=~((1<<7));						// Set GPIO0.7 AS input
    

   while(1)													// Loop Continue
  {
	
	
	if(!(IOPIN0 & (1<<7)))	 // When button is pressed => IOPIN0 7 =1;
	{
	
		IOCLR1 |=(1<<18);
	        IOSET1 |=(1<<16);
	}
	
	else  
	{ 
		 
		  IOCLR1 |=(1<<16);
	   	  IOSET1 |=(1<<18);
	
	}
	  
}	  
}
Ive tried several things, the thing that anodes me the most is that I manage to make it work with one LED without a problem but can not make it work with two.
The other thing that annoys me is that only IOCLR works in the IF statement, if i swap for one button e.g

This will work
Code: Select all
if(!(IOPIN0 & (1<<7)))	 // When button is pressed 
	{
	IOCLR1 |=(1<<16);
	 }
	else  
	{ 
       IOSET1 |=(1<<16);
	}
This will not work
Code: Select all
     if(!(IOPIN0 & (1<<7)))	 // When button is pressed 
	{
	IOSET1 |=(1<<16);
	 }
	else  
	{ 
       IOCLR1 |=(1<<16);
	}
BR
//Karl
User avatar
By viskr
#176995
Are you sure you want to do a
Code: Select all
IOSET1 |=(1<<16);
The purpose of the set/clear registers it to write a 1 to bits you want to SET/CLEAR and leave the rest alone. Typically I never do |= operations on those registers. As in some NXP ARMs reading the SET register will return the pin state, some NXP ARMs don't. I would think you really want just
Code: Select all
IOSET1 =(1<<16);
By karlwr
#176999
Hi Viskr

That is not really a problem, I have tried IOSET1 = (1<<16) with the same result as before. I have eliminated all read-modify-write from the IOSET/IOCLR. I want my application to switch the LED that is on when I press the button, so LED1 is on and LED2 is off when button pressed and vice versa when not pressed. I cant get it to work. Apparently I can't do a IOSET after my if statement.

Here is the million dollar question, WHY can't I do a IOSET after I do a " if(!(IOPIN0&(1<7))"
Observe that I have tried " if(!(IOPIN & (0x00000080).
This code won't work!!!
Code: Select all
   
   if(!(IOPIN0 & (1<<7)))    // When button is pressed => IOPIN0 7 =1;
   {
      IOSET1 =(1<<16)|(1<<18);
   }
   else  
   { 
     IOCLR1 =(1<<16)|(1<<18);
   }  
}
This will work!!!
Code: Select all
 if(!(IOPIN0 & (1<<7)))    // When button is pressed => IOPIN0 7 =1;
   {
      IOCLR1 =(1<<16)|(1<<18);
   }
   else  
   { 
     IOSET1 =(1<<16)|(1<<18);
   }  
}
thanks for the help!
//Karl
By karlwr
#177005
Hi viskr

Im not sure what you are talking about but I dont have any debouncing routine in my code because I haven't experienced any flickering.

My LEDs are connected from my GPIOs via a resistor to GND and My button is Active low meaning that when i press the button goes down to GND.

The thing that surprises me is that it works to set a IOCLR in my If statement but I can't do a IOSET in the If statement and I can't seem to get an answer why this does not work!!! :doh: :doh:
User avatar
By viskr
#177012
I can assure you IOSET and IOCLR work on the LPC2119. The part has been shipping for probably 10 years, and millions in the field

So ignore the button issue, you should be able to set a pin high with IOSET is a simple program. If you can't then you have a define wrong or something similar.

If you are not debouncing a switch you will have unexpected results, particularly with a push button switch, and any "flicker" you would see is way faster than you can see. Most any switch will not make a contact cleanly, so you may see multiple "pushes" every time you think you push it once, as the contact bounce off each other at a rate in the 100s of Hz. Depending on the switch it may be a lot of times. So your code has to detect the first switch closure and ignore any other closures for probably 50 msec or so. Google switch bounce for more details.
By karlwr
#177022
Yes, I understand this, I know about debouncing, this is embedded 101.
My connection on the push button is GPIO P07-> Push Button ->GND.
When i connect GPIO p07 directly to GND I still have this problem,I mean connecting the Push button pin directly to GND would show how the button would act when pressed under perfect debouncing circumstances.

I have tried to debounce in software with no success

Thanks anyway

/K
By hsutherl
#177115
Hello karlwr,

I dug out my LPC-P2148** to check your example. I checked it first by having the LEDs opposite, then both the same. In each case everything worked exactly as we would expect. So I'm guessing you have what I'll call a "toolchain" problem.

The LEDs and button(s) are connected to different pins, so you cannot directly use my hex or binary files, but you could compare your disassembly to mine. (The main loop in that file is only 13 machine instructions).

I'm guessing you don't have any way to connect a de-bugger to your board?

Good luck,
-Hugh

**I'm pretty sure I bought mine through Sparkfun. Not suprising they no longer carry it; the bang for the buck would be pretty low by today's standards.
User avatar
By viskr
#177155
The LPC2148 is a superset of the LPC2138, which we have a set of gcc tools configured for.

If you don't have a JTAG connection or debugger, you should include a small monitor into your C program, something we routinely do. Yes this is kind of old school, but it lets you read and write memory locations which also means peripherals from a serial port connection. And we always use ISP programming in our board designs. We also route unused interrupts to this routine.

Source for that small monitor is in breakpoint.h and .c and is part of the installer setup

www.coridium.us/files/setupC.exe
By karlwr
#177199
hsutherl wrote:
I'm guessing you don't have any way to connect a de-bugger to your board?
Hi Hsutherl

I dont have the possibility to debug on my board since Im working with a ET-ARM Stamp card that dont have a JTAG interface. I Could debug in software som way but I haven't looked in to it yet.
The thing that irritates me is that I'm working on a hobby project with a I2C sensor network on the same board and this works fine and all but blinking two LEDs dont.
I got a tip from Another forum to try to make the registers to IOSET0, IOSET1 to volatile registers so that the compiler dont throw away the values that I want to store.
I will test this today after work and let you guys know

/K
By UhClem
#177202
karlwr wrote:I got a tip from Another forum to try to make the registers to IOSET0, IOSET1 to volatile registers so that the compiler dont throw away the values that I want to store.
They are already defined as volatile in the file LPC21xx.H.

Not that it matters if you don't read them. Or if you have compiler optimization turned off.

Since you don't have JTAG to observe the program running another option is to look at the compiler output to see what instructions it is generating.