Reputation: 243
this code is supposed to read the state of a digital input pin via a pushbutton and output the state to an LED. i.e. when input is high, LED is on and vice versa Since the pushbutton is connected to pull-up resistor, When the pushbutton is pressed the input is supposed to read a LOW and vice versa.
My code:
#include "board.h"
#include <stdio.h>
//setting pointers
#define Port0 ((LPC_GPIO_T *) 0x50000000) //Port 0
#define IOCON ((LPC_IOCON_T *) 0x40044000) //IO configuration
int main(void)
{
/* Initialize pins */
Port0->DIR &= ~((1 << 1)); //PIO0_1 input - onboard switch (unpressed state is pulled-up)
Port0->DIR |= (1<<7); //PIO0_7 output - onboard LED
//Pin configuration
IOCON->REG[IOCON_PIO0_7] &= 0x0 << 3; //No addition pin function
IOCON->REG[IOCON_PIO0_1] &= 0x0 << 3; // "
Port0->DATA[1<<7] &= ~(1<<7); // output initially low
while (1) {
if((Port0->DATA[1<<1]) & (1<<1)) //When input is high
{
Port0->DATA[1<<7] |= (1<<7); //drive PIO0_7 High
}
else
{
Port0->DATA[1<<7] &= ~(1<<7); //Drive PIO0_7 Low
}
}
return 0;
}
When this part of the code is executed PIO0_7 remains remains low unless the button is pressed..However isn't it meant to work the opposite way since switch is pulled-up? I also double checked this with the voltmeter.
I tried changing
if((Port0->DATA[1<<1]) & (1<<1)) //When input is high
to
if(!(Port0->DATA[1<<1]) & (1<<1)) //When input is Low
The LED output remains High, even when the button is pressed.
Upvotes: 0
Views: 1195
Reputation: 800
Assuming your Port0->DATA[0]
is pointing to Base-Address 0x5000 0000
and defined as aligned 8bit array then your Pin-Port addressing/masking is wrong.
See LPC111x user manual UM10398 Rev. 12.4 p196 Chapter 12.4.1 write/read data operation:
In order for software to be able to set GPIO bits without affecting any other pins in a single write operation, bits [13:2] of a 14-bit wide address bus are used to create a 12-bit wide mask for write and read operations on the 12 GPIO pins for each port.
So there is an offset of 2 bit in the address to get/set the value of your desired pin. Therefore you must shift your addressing by 2 bit, the following should do the trick:
Port0->DATA[1<<(7+2)] &= ~(1<<7); // output initially low
while (1) {
if((Port0->DATA[1<<(1+2)]) & (1<<1)) //When input is high
{
Port0->DATA[1<<(7+2)] |= (1<<7); //drive PIO0_7 High
}
else
{
Port0->DATA[1<<(7+2)] &= ~(1<<7); //Drive PIO0_7 Low
}
}
Upvotes: 1