switch input to toggle LED[SOLVED] - Page 1
Forum section: electronics / beginners

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 09:36:15 am
content: 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 fileCode:#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 CONFIGvoid main() {RBPU = 0;TRISCbits.RC0 = 0; //set Port RB0 as outputPORTCbits.RC0 = 1; //set Port RB0 to high (turn on LED)TRISBbits.RB0 = 1; //Set PORTA0 as inputfor(;;){ //endless loopif(PORTBbits.RB0 == 0){ //if push button is pressedPORTCbits.RC0 = !PORTCbits.RC0; //toggle LEDwhile(PORTBbits.RB0 == 0);}}}what am I doing wrong ?compiler: XC8chip: PIC18F2550EDIT: changed code to make it easier to read, my original code is in the attached file.

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 12:50:37 pm
content: 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.

author: M_Holden
author_rank: Newbie
timestamp: May 24, 2016, 01:03:53 pm
content: 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.

author: JPortici
author_rank: Super Contributor
timestamp: May 24, 2016, 01:24:01 pm
content: 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 likeCode:unsigned char tempb,changedb,oldb = 0;while(1) {tempb = PORTB;changedb = tempb ^ oldb;if (changedb) { //new state of the port is different than previousif (changedb & 1) { //rising or falling edge on RB0if (tempb & 1) { //i'm interested in the rising edge on RB0LATCbits.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..

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 01:30:41 pm
content: Quote from: M_Holden on May 24, 2016, 01:03:53 pmRC0 is working fine without the If() statement, and the led gets toggled just fineI'm using sublime text editor and a make file to compile.I was using LATx registers in my original code, read the attached file.

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 01:37:53 pm
content: Quote from: JPortici on May 24, 2016, 01:24:01 pmThe 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 finehttp://gputils.sourceforge.net/html-help/PIC18F2550-conf.html

author: JPortici
author_rank: Super Contributor
timestamp: May 24, 2016, 01:43:08 pm
content: 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 outputingbut 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)

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 01:54:59 pm
content: Quote from: JPortici on May 24, 2016, 01:43:08 pmok, 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 helpfulI don't have to sample it, I think it's already sampled enough with "PORTBbits.RB0" .

author: Ian.M
author_rank: Super Contributor
timestamp: May 24, 2016, 01:58:38 pm
content: Port B has analog functionality on several pins which disables digital input.Stick this in the initialisation section of main().Code:ADCON1=0x0F; // Make all ADC ANx pins digitalCMCON=0x07; // Make all Comparator CMx pins digitalN.B always toggle the LAT bit not the port bit to avoid RMW problemsI'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!

author: MAD MACRO
author_rank: Regular Contributor
timestamp: May 24, 2016, 02:03:05 pm
content: Quote from: Ian.M on May 24, 2016, 01:58:38 pmFANTASTIC, this worked just fine with my original code.thanks alotand yes, i'm asking about them delicious macros you talking about.

author: Ian.M
author_rank: Super Contributor
timestamp: May 24, 2016, 02:23:00 pm
content: The gnarly macro looks like:Code:#define sPORTAbits (*(PORTAbits_t * volatile)&sPORTA)See the Microchip forum threadUsing 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 seeRMW and solutions for itfor why you should *ALWAYS* use the LAT SFRs for output on any PIC that has them.