0

I am currently studying on a LPC3141 development board. I am trying to turn off a single GPIO pin while leaving the others in the same states as they were. My problem is that I can turn them on individually but when i want to turn off just one pit it makes a "bus reset" and turns them all off. I cannot figure out why does it reset all of them when I use bit shifting. Here is an example of my code that does this:

#define PINS (*((volatile unsigned int *)0x130031C0))
#define MODE0 (*((volatile unsigned int *)0x130031D0)) 
#define MODE0_SET (*((volatile unsigned int *)0x130031D4))
#define MODE0_RESET (*((volatile unsigned int *)0x130031D8))

#define MODE1 (*((volatile unsigned int *)0x130031E0))
#define MODE1_SET (*((volatile unsigned int *)0x130031E4))
#define MODE1_RESET (*((volatile unsigned int *)0x130031E8))

void delay (void);

void c_entry(void){

    //Prg gpio pins (glej user manual str 312-318
    //Bit manipulation (spremenim samo 1 bit v registru inne celega)
    MODE1 = MODE1 | (0x1 << 6); 
    MODE1 = MODE1 | (0x1 << 8);

    while(1){
        MODE0 = MODE0 | (0x1 << 6);
        MODE0 = MODE0 | (0x1 << 8);
        delay();
        MODE1 = MODE1 | (0x1 << 6);
        MODE1 = MODE1 | (0x1 << 8);
        MODE0 = MODE0 & !(0b1000000);
        delay();
    }
}

void delay (void){
    volatile int stej = 1000000;
    while(stej){
    stej = stej - 1;
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    I voted to *Improve*. I think its a good question, but you should improve the formatting so its easy on the site's readers. – jww Jun 12 '15 at 10:45
  • It does reset the internal bus?? So I would say it is an access violation, acces an address where no register is located, etc. Or what do you mena by "bus reset"?? – too honest for this site Jun 12 '15 at 12:19
  • possible duplicate of [How do you set, clear and toggle a single bit in C/C++?](http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c-c) – too honest for this site Jun 12 '15 at 12:23

1 Answers1

5

You're using the wrong operator when you want to clear a bit - you want the bitwise complement operator ~, not the logical NOT operator !.

Note: bitwise operators, as their name implies, operate on individual bits within a value, whereas logical operators treat a value as a single true/false quantity (0 = false, everything else = true). Bitwise operators: &, |, ^, ~. Logical operators: &&, ||, !.

So for example your line:

MODE0 = MODE0 & !(0b1000000);

should be:

MODE0 = MODE0 & ~(0b1000000);

or more succinctly/consistently:

MODE0 &= ~(0x1 << 6);
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Whats the difference between those two... Can you provide me an example? Ty – ssi.elektrotehnik Jun 12 '15 at 10:42
  • 5
    This is really basic stuff and should be covered quite early on in whatever book you are using to learn C from (there may be a chapter or section titled `Operators`). Anyway, I'll add some more info to the answer, but I do recommend a little more self-study before you go too much further. – Paul R Jun 12 '15 at 10:44
  • Ty... I find your advice really useful, as i am new to microcontrollers. Have a nice day! – ssi.elektrotehnik Jun 12 '15 at 10:54
  • You're welcome! One further tip: check out the list of C books here on StackOverflow: http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list – Paul R Jun 12 '15 at 10:55
  • @ssi.elektrotehnik: That is not microcontroller-specific, but regular C operators. (Sidenote: is the missing "c" in your name intended?) – too honest for this site Jun 12 '15 at 12:21
  • the logical operator ! takes the whole value and logically inverts it. So a zero is defined as false in C and non-zero defined as true so !0b1000000 means evaluate the whole number 0b100000 which is not zero so it is true, then invert that to a false which is zero, now you do a bitwise and with zero, anything anded with zero is zero so the MODE0 register becomes all zeros, all the bits get cleared. A bitwise not operator is going to look bit by bit ~0b1000000 is going to invert on a bit by bit basis giving 0b0111111 and with that and the other bits are not modified – old_timer Jun 12 '15 at 15:02
  • 1
    @dwelch: note that for boolean operators, "true" will result in integer `1` as per the standard. Interpretation of "non zero" is just for evaluation and is actually a coercion rule (int to bool). Otherwise, boolean operators would not be compatible with integers - as typical in other languages like The Pascal-family. – too honest for this site Jun 12 '15 at 15:35
  • I have seen compilers generate all ones for a true (-1) instead of a 1 (mostly zeros and one 1). I guess they were non standards compliant. – old_timer Jun 12 '15 at 17:26