0
\$\begingroup\$

I'm trying to write a code where when a push button is pressed, a whole PORT is toggled.

So I got a push button at PORT E in pin 0, and 8 leds on PORTD, I also got a debugging led on PORT E pin 1.

void main() {

     // Interrupt flags, enable global and external interrupt
     INTCON = 0x90;
     TRISE.F0 = 1;
     TRISE.F1 = 0;
     TRISD= 0x00;

     do {
        if (PORTE.F0 == 1) {
           Delay_ms(100);
           if (PORTE.F0 == 1) {
              LATD ^= 1;
              Delay_ms(1000);
             }
          }
          PORTE.F1 ^= 1;
          Delay_ms(1000);
     } while(1);

}

The problem is that neither thing happens, on push button press is not toggling port D and pin 1 on PORT E isn't blinking as it should.

Just in case I got a 18F4550 microcontroller with 20 Mhz oscillator, coding in C with mikroC IDE's compiler, I let the IDE set up all configuration bits. What have I got wrong?

Simple test.

void main() { 
  TRISD=0; 
  LATD = 0xFF;
  while(1){
    LATD=~LATD;
    Delay_ms(1000)
  } 
}

this makes the leds blink each second.

Update.

I changed the LATD toggling statement to LATD ^= 0xFF; as one answer suggests. But this made it not working. So I'm thinking that definitely the issue about the button push detection statements.

This is how setup bits are set:

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Haven't used PICs in a long time...are you setting the applicable pins on the port to be outputs? \$\endgroup\$ – Nick T Apr 1 '15 at 23:18
  • \$\begingroup\$ You should be using the LAT register for manipulating outputs, not the PORT register (though I think there is a redirect from PORT to LAT when writing anyway) \$\endgroup\$ – Majenko Apr 1 '15 at 23:24
  • \$\begingroup\$ Do you mean port F not port E for the debugging LED and button? Also, how is everything (and I mean everything) wired up? Finally, what are your config bits set up as? \$\endgroup\$ – Majenko Apr 1 '15 at 23:27
  • \$\begingroup\$ Majenko I use simple development board, LEDS and push buttons area actually part of it. I got a 20 Mhz crystal and code it's setup for it. \$\endgroup\$ – diegoaguilar Apr 1 '15 at 23:28
  • \$\begingroup\$ The push button and also LED are at PORT E. Button at pin 0 and led at 1. \$\endgroup\$ – diegoaguilar Apr 1 '15 at 23:29
1
\$\begingroup\$

I see many issues with your code that would likely cause you grief.

Firstly (I dont think this is your main issue), you enable interrupts but have no function to catch them. If an interrupt were to occur, your PIC would likely reset (undefined behavior).

Secondly, when you try to toggle your LATD, you are in fact togling just the lowest bit. When you enter the literal 1, the compiler interprets it as 0x01. If you want to toggle the whole byte, you should xor with 0xFF (255) instead.

Thirdly, you dont seem to set your configuration bits anywhere nor do you configure your oscillator. Without setting these values, you may have a chip running at a very low speed and your Delay might be longer than you expect (you have not provided their definition ether so I cant confirm or deny this hypothesis).

EDIT: I looked into this more and i believe I have found your main issue. If you look at the pinout in the specification sheet for this PIC, you will find that pin RE0 shares a physical pin with an analog input. The default state in PIC micro-controllers is for the analog input to override the digital input. You have to disable the analog input through the ADCON1 register to be able to get digital input (see test code below).

As you seem to have determined that your oscillator is running, I suggest next testing if you can read the button correctly :

void main(){
    TRISD=0;
    ADCON1 = 0x0F;
    LATD =0;
    while(1) LATD = (PORTE & 0x01) ? 0xff : 0x00;
}

You should see your LEDs follow the logic level of your switch.

\$\endgroup\$
  • \$\begingroup\$ I let my IDE so the whole configuration bits setup. It's a 20Mhz oscillator and code has got such setup. \$\endgroup\$ – diegoaguilar Apr 1 '15 at 23:42
  • \$\begingroup\$ I always go the route of proving this to myself. For examplem ith a minimal code of : void main() { TRISD=0; while(1){LATD=~LATD;Delay_ms(1000)} }, do the LEDs blink every two seconds? \$\endgroup\$ – Mathieu L. Apr 1 '15 at 23:46
  • \$\begingroup\$ testing blinking code works .. \$\endgroup\$ – diegoaguilar Apr 1 '15 at 23:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.