Author Topic: switch input to toggle LED[SOLVED]  (Read 3691 times)

0 Members and 1 Guest are viewing this topic.

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
switch input to toggle LED[SOLVED]
« on: May 24, 2016, 09:36:15 am »
Trying to toggle a LED connected to RC0, using a switch which is connected to RB0. The LED is not getting toggled. the switch state is not affecting the results at all.

same code in attached the file
Code: [Select]
#include <xc.h>
#define _XTAL_FREQ 16000000   //using 16MHz external crystal

//BEGIN CONFIG
#pragma config FOSC = HS    // External high speed clock
#pragma config DEBUG = OFF
#pragma config WDT = OFF    // Watchdog timer OFF
#pragma config LVP = OFF    // Single-Supply ICSP OFF
//END CONFIG

void main() {
    RBPU = 0;
    TRISCbits.RC0   = 0; //set Port RB0 as output
    PORTCbits.RC0   = 1; //set Port RB0 to high (turn on LED)
    TRISBbits.RB0   = 1; //Set PORTA0 as input

    for(;;){  //endless loop
            if(PORTBbits.RB0 == 0){  //if push button is pressed
                PORTCbits.RC0 = !PORTCbits.RC0;  //toggle LED
            while(PORTBbits.RB0 == 0);
            }
    }
}

what am I doing wrong ?

compiler: XC8
chip: PIC18F2550


EDIT: changed code to make it easier to read, my original code is in the attached file.
« Last Edit: May 24, 2016, 02:04:35 pm by MAD MACRO »
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: switch input to toggle LED
« Reply #1 on: May 24, 2016, 12:50:37 pm »
So, I gave up on my original code, cuz I thought it might look a bit too complicated, now this one is a few lines only and very easy to read.
still having the same issue.

please, I need help.
 

Offline M_Holden

  • Newbie
  • Posts: 4
  • Country: it
Re: switch input to toggle LED
« Reply #2 on: May 24, 2016, 01:03:53 pm »
Hi,
RCO is one of the secondary oscillator pins, you have to disable it to use this pin.
In MplabX there is an handy configuration bits table in Window-->Pic Memory Views-->Configuration Bits to configure all the configuration bits.
To control the output pin use the LATx registers and not the PORTx.
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: switch input to toggle LED
« Reply #3 on: May 24, 2016, 01:24:01 pm »
first of all you might have an hardware problem
-> is the oscillator running? (simple test, make a program that increments LATB or toggle a led endlessly)
-> is the minimal hardware present? (i.e.: you have to have a cap for vusb present all the time. refer to the datasheet)
then, are those all the configuration words? it's been many years since i had to use a 2550 but it seems like they're too few..
Anyway i always hat bad luck in reading the state of a pin directly in C. especially when i have to read a ton of pins it's safer tp sample the port and then analyze it.. something like
Code: [Select]
unsigned char tempb,changedb,oldb = 0;
while(1) {
  tempb = PORTB;
  changedb = tempb ^ oldb;
  if (changedb) {          //new state of the port is different than previous
    if (changedb & 1) {    //rising or falling edge on RB0
      if (tempb & 1) {            //i'm interested in the rising edge on RB0
        LATCbits.LATC0 ^= 1  //toggle latc1
      }
    }
  }
  oldb = tempb;
}
there are of course more efficient ways to do this but i'd do it in assembly as it become a handful ot BTFSS/BTFSC instructions..
« Last Edit: May 24, 2016, 01:35:00 pm by JPortici »
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: switch input to toggle LED
« Reply #4 on: May 24, 2016, 01:30:41 pm »
Hi,
RCO is one of the secondary oscillator pins, you have to disable it to use this pin.
In MplabX there is an handy configuration bits table in Window-->Pic Memory Views-->Configuration Bits to configure all the configuration bits.
To control the output pin use the LATx registers and not the PORTx.

RC0 is working fine without the If() statement, and the led gets toggled just fine
I'm using sublime text editor and a make file to compile.
I was using LATx registers in my original code, read the attached file.
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: switch input to toggle LED
« Reply #5 on: May 24, 2016, 01:37:53 pm »
first of all you might have an hardware problem
-> is the oscillator running? (simple test, make a program that increments LATB or toggle a led endlessly)
-> is the minimal hardware present? (i.e.: you have to have a cap for vusb present all the time. refer to the datasheet)
then, are those all the configuration words? it's been many years since i had to use a 2550 but it seems like they're too few..
Anyway i always hat bad luck in reading the state of a pin directly in C. especially when i have to read a ton of pins it's safer tp sample the port and then analyze it.. something like
Code: [Select]
unsigned char tempb,changedb,oldb = 0;
while(1) {
  tempb = PORTB;
  changedb = tempb ^ oldb;
  if (changedb) {          //new state of the port is different than previous
    if (changedb & 1) {    //rising or falling edge on RB0
      if (tempb & 1) {            //i'm interested in the rising edge on RB0
        LATCbits.LATC0 ^= 1  //toggle latc1
      }
    }
  }
  oldb = tempb;
}
there are of course more efficient ways to do this but i'd do it in assembly ad it became a handful of bit tests instructions..
The oscillator is running, I tried the code without the if statement and it toggled just fine.
yes, I have a 330nF cap from vsub to ground.

the configuration defaults seemed just fine http://gputils.sourceforge.net/html-help/PIC18F2550-conf.html
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: switch input to toggle LED
« Reply #6 on: May 24, 2016, 01:43:08 pm »
yes. however, i would advise against leaving the default values, it's not a good practice.
the problem of course lies in the "if" statement. you have to check what the hell is the compiler's outputing
but as i said putting the input pins directly into an if statement never worked reliably for me. a lot happens inside an if statement.
Sampling the port and using that byte inside your if statement should resolve all of your problems

(by the way what was all that abstracion rubbish in the attached file? plain C is already too abstract for an 8 bit PIC)
« Last Edit: May 24, 2016, 01:44:41 pm by JPortici »
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: switch input to toggle LED
« Reply #7 on: May 24, 2016, 01:54:59 pm »
yes. however, i would advise against leaving the default values, it's not a good practice.
the problem of course lies in the "if" statement. you have to check what the hell is the compiler's outputing
but as i said putting the input pins directly into an if statement never worked reliably for me. a lot happens inside an if statement.
Sampling the port and using that byte inside your if statement should resolve all of your problems

(by the way what was all that abstracion rubbish in the attached file? plain C is already too abstract for an 8 bit PIC)

ok, I'll try to change the relevant ones.
how is the compiler going to tell me about the if casing trouble in the chip while running ? the compiler gives a clear and detailed output in the terminal when I compile.
I've tried to replace the "abstracion rubbish" if line with "if(PORTBbits.RB0 == 0)" , same result.
and that abstracion rubbish is what's going to save me when I port the HD44780U LCD driver. Generally speaking, It might seem as a big overhead, but later on, it's very helpful

I don't have to sample it, I think it's already sampled enough with "PORTBbits.RB0" .
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: switch input to toggle LED
« Reply #8 on: May 24, 2016, 01:58:38 pm »
Port B has analog functionality on several pins which disables digital input.
Stick this in the initialisation section of main().
Code: [Select]
ADCON1=0x0F; // Make all ADC ANx pins digital
CMCON=0x07; // Make all Comparator CMx pins digital

N.B always toggle the LAT bit not the port bit to avoid RMW problems

I've never had any problems reading pins directly in an if(), as long as I don't get crazy with the boolean algebra, as nasty things happen if you have an expression with sub-expressions containing terms PIN and !PIN if PIN changes state between the evaluation of the two sub-expressions.   However, if you need to minimise timing skew or if you need to use a pin state repeatedly, its worth reading all input ports into variables then picking them apart.   There's also a macro/pointers trick you can do to make your variable copy of the port look like a port pins struct to make it easier to pick apart so if you need that, ask!
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: switch input to toggle LED
« Reply #9 on: May 24, 2016, 02:03:05 pm »
Port B has analog functionality on several pins which disables digital input.
Stick this in the initialisation section of main().
Code: [Select]
ADCON1=0x0F; // Make all ADC ANx pins digital
CMCON=0x07; // Make all Comparator CMx pins digital

N.B always toggle the LAT bit not the port bit to avoid RMW problems

I've never had any problems reading pins directly in an if(), as long as I don't get crazy with the boolean algebra, as nasty things happen if you have an expression with sub-expressions containing terms PIN and !PIN if PIN changes state between the evaluation of the two sub-expressions.   However, if you need to minimise timing skew or if you need to use a pin state repeatedly, its worth reading all input ports into variables then picking them apart.   There's also a macro/pointers trick you can do to make your variable copy of the port look like a port pins struct to make it easier to pick apart so if you need that, ask!

FANTASTIC, this worked just fine with my original code.

thanks alot  :)

and yes, i'm asking about them delicious macros you talking about.  :popcorn:
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: switch input to toggle LED[SOLVED]
« Reply #10 on: May 24, 2016, 02:23:00 pm »
The gnarly macro looks like:
Code: [Select]
#define sPORTAbits (*(PORTAbits_t * volatile)&sPORTA)See the Microchip forum thread Using PORTAbits_t to create a shadow variable for the port A?
The usual reason to do this is as a workaround for the RMW effect on baseline and standard midrange PICs, but the same sort of macro can equally well be used when you need to read inputs in bulk then pick out pin states later.  It looks horrible but the compiler pre-evaluates it resolving all the pointers so it produces pretty good code.

Also see RMW and solutions for it for why you should *ALWAYS* use the LAT SFRs for output on any PIC that has them.
« Last Edit: May 25, 2016, 01:23:20 pm by Ian.M »
 
The following users thanked this post: MAD MACRO


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf