Issue setting and clearing bits

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issue setting and clearing bits

739 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarkG on Thu Jul 02 02:01:52 MST 2015
Hi Folks.

I am relatively new to NXP 32 bit processors so I apologise in advance if this question seems silly. I am having an issue turning a bit on and off. Using the following code pin should go high and low but it stays high. Am I using the correct format to clear the bit?

#include <stdint.h>


//registers used for gpio & systick setup
#define GPIO_NOT             (*((volatile unsigned int *)(0xA0002300)))
#define GPIO_SET             (*((volatile unsigned int *)(0xA0002200)))
#define GPIO_CLEAR           (*((volatile unsigned int *)(0xA0002280)))
#define GPIO_DIR             (*((volatile unsigned int *)(0xA0002000)))
#define SYSCON_PRESETCTRL    (*((volatile unsigned int *)(0x40048004)))
#define SYSCON_SYSAHBCLKCTRL (*((volatile unsigned int *)(0x40048080)))
#define NVIC_ST_CTRL         (*((volatile unsigned int *)(0xE000E010)))
#define NVIC_ST_RELOAD       (*((volatile unsigned int *)(0xE000E014)))
#define NVIC_ST_CURRENT      (*((volatile unsigned int *)(0xE000E018)))
#define SCB_SHP1             (*((volatile unsigned int *)(0xE000ED20)))


void delay(void) {
  int volatile counter = 0;
  while(counter < 1000000){
    ++counter;
  }
}

int main(void) {
  //enable AHB clock to the GPIO domain
  SYSCON_SYSAHBCLKCTRL |= (1<<6);
  //reset gpio peripheral control
  SYSCON_PRESETCTRL &= ~(1<<10);
  SYSCON_PRESETCTRL |= (1<<10);
  //make gpio #0 pin an output (physical pin #8)
  GPIO_DIR |= (1<<0);

  //set systick clock interrupt reload count
  NVIC_ST_RELOAD = (1200000UL & 0xFFFFFFUL) - 1;
  //set SysTick IRQ to lowest priority
  SCB_SHP1 = 0xC0000000;
  //reset the counter
  NVIC_ST_CURRENT = 0;
  //enable the IRQ and go
  NVIC_ST_CTRL = 0x07;

  //loop forever
  while(1){

   
    GPIO_SET |= (1<<0);
   
    delay();
   
    GPIO_SET |= (0<<0);
 
    delay();
   
  }
}


If I change the main while loop to below it goes high only once

  while(1){
       
    GPIO_NOT |= (1<<0); //toggle led pin
   
    /delay();

  }
}

Any ideas as to why this may be happening and/or is there a better way to turn the pins on and off?

Thanks,

Mark.
Labels (1)
0 Kudos
Reply
4 Replies

701 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarkG on Fri Jul 03 04:08:27 MST 2015
i used your original recommendation for 4 pins (1,2,5,8) and all worked ok. When would this format present a problem??
0 Kudos
Reply

701 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Thu Jul 02 06:48:51 MST 2015

Quote: lpc_bloke

GPIO_SET |= (1<<0);
delay();
GPIO_CLEAR |= (1<<0);


You also don't need the read-modify-write sequence above if you are changing all the bits at one time.


It's wrong to use read-modify-write here. Every 1 bit in the word you write will do the Set or Clear operation on the corresponding port bit, so the correct way is like this:
GPIO_SET = (1<<0);
delay();
GPIO_CLEAR = (1<<0);

0 Kudos
Reply

701 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarkG on Thu Jul 02 03:40:44 MST 2015
Thanks for the reply. Its working now. Its always very simple in the end.

  :)
0 Kudos
Reply

701 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpc_bloke on Thu Jul 02 03:01:22 MST 2015
Try this in your code above:
//loop forever
while(1){


GPIO_SET |= (1<<0);

delay();

GPIO_CLEAR |= (1<<0);

delay();

}

There are two registers to allow changing more that one pin at a time.  I suggest reading the chip user manual on GPIO at least 3-times.  Then you will start to understand what they are talking about.

You also don't need the read-modify-write sequence above if you are changing all the bits at one time.

0 Kudos
Reply