while condition loop problem with xc8

Thread Starter

hunterage2000

Joined May 2, 2010
487
Hello all,

I am trying to increment a while loop and turn on and off an LED with MPLAB X IDE and XC8 compiler. I think its just a standard C conditionl statement, the clean and build comes back as error-free but the LED is initially off, it flashes on for a quarter second then off then back on and stays on.

Im not sure why its doing that. It should flash on, wait a second, flash off wait a second ten times.

Rich (BB code):
#include <xc.h>
#include <delays.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 20000000

int main(void) {

TRISB = 0x00;

int k;

k = 0;
while(k < 10)
{
    PORTB = 0xFF;
    _delay(20000000);
     PORTB = 0x00;
    _delay(20000000);
    k++;
}

return 0;
}
 

tshuck

Joined Oct 18, 2012
3,534
Another thing to note is that you should never return from a main loop in a microcontroller. The behavior is erratic after the PC hits the end of the program-where does it go? No one knows!

You should always stuff your code in a while(1) loop, even if there's nothing in it. It's about the only good use of an infinite loop, as it keeps your uC's behavior predictable.

What processor is this? And have your configuration bits and ADCON1, to set the PORTB pins to digital I/O(if applicable)?
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
Yeah I tried everyway and I tried a for loop but it just isnt working. Theres no ADCON1 associated with PORTB but there is an OPTION_REG.
 

Brownout

Joined Jan 10, 2012
2,390
Are you sure portB is connected to the LED's?
What is the processor?
What is the dev board?
Have you been able to control LED's at all?

As a debug, first try to just turn on a particular LED. Don't return at the end of your program. Use "while(1)" to enter an infinite loop. Try to turn on each LED one at a time, changing the value in your program and re-compiling. Only then will you know you're setting think up correctly.
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
Yeah TRISB has set PORTB to output, I have checked each pin with a multimeter and the voltage is constant at 5V except RB3/PGM and is not switching on and off. When the LED is connected, it turns on the start and stays on instead of turning on and off for second. I am using a PICF16877A with no dev board.

The LEDS work with

Rich (BB code):
     while(1)
      {    
  PORTB = 0xFF;
  _delay(2000000);
  PORTB = 0x00;
  _delay(2000000);
      }
This is why I dont really understand why the while loop doesnt work. Also I tried the for loop which didnt work.
 

tshuck

Joined Oct 18, 2012
3,534
Did you try adding a while(1) after your counting section?

You can try this:
Rich (BB code):
#include <xc.h>
#include <delays.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

//set your configuration bits!

#define _XTAL_FREQ 20000000

void main(void) {

TRISB = 0x00;

int k = 0;
while(k < 10)
{
    PORTB = 0xFF;
    _delay(20000000);
     PORTB = 0x00;
    _delay(20000000);
    k++;
}
while(1);//wait forever
}
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
I have tried the code and it still does the same thing, I have looked at the XC8 guide and it just isnt beginner friendly. The ways things are going I may have to go back to Arduino.
 

tshuck

Joined Oct 18, 2012
3,534
To be clear, you do have a crystal attached, right? Also, do you have a resistor(~10kΩ) from Vpp to Vdd?

You should also set your configuration bits...
 

Brownout

Joined Jan 10, 2012
2,390
I'll try your code when I get back home tonight. But we are using different processors, so I'm not sure how much good it will do. Maybe I can make mine fail, and debug the problem.
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
Yeah everything is setup correctly, I blinked the LED using:

Rich (BB code):
  while(1)       {       PORTB = 0xFF;   _delay(2000000);   PORTB = 0x00;   _delay(2000000);       }
 

tshuck

Joined Oct 18, 2012
3,534
If you leave it alone for a while, does your LED turn off, I didn't look at it before, but I think your delays are HUGE!

Try this code:
Rich (BB code):
#include <xc.h>
#include <delays.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

//set your configuration bits!

#define _XTAL_FREQ 20000000

void main(void) {

TRISB = 0x00;
volatile unsigned int j = 0;
volatile int k = 0;
while(k < 10)
{
    PORTB = 0xFF;
    for(j=0;j<64000;j++);
    for(j=0;j<64000;j++);
    PORTB = 0x00;
    for(j=0;j<64000;j++);
    for(j=0;j<64000;j++);
    k++;
}
while(1);//wait forever
}
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
Yeah they turn off at loads of different times, Not what sure what thats about. When I didnt use a loop the LED flashes on and off for 1 sec = 20000000 and the recent post I used PORTB's RB2 pin and set the delay as 2 seconds = 40000000.

Im not sure why I cant use __delay_ms(), the guide says nothing about it only being used on the 18 series.

Ive looked at that many sources I cant seem to pin down a source that gives me the tutorials I need. The closest good source I found is here:

http://morrish.ca/beginner/digital.php

and even on this there is the ANSEL / ANSELH commands to disable a pin:

ANSELbits.ANS5 = 0; //disable AN5

also this guy uses the __delay_ms(); command in this code using only xc.h and a PIC16F690.

What I need is access to the correct header files with such headers as PWM, ADC etc as they are not in my libraries.
 

tshuck

Joined Oct 18, 2012
3,534
Yeah they turn off at loads of different times, Not what sure what thats about. When I didnt use a loop the LED flashes on and off for 1 sec = 20000000 and the recent post I used PORTB's RB2 pin and set the delay as 2 seconds = 40000000.

Im not sure why I cant use __delay_ms(), the guide says nothing about it only being used on the 18 series.

Ive looked at that many sources I cant seem to pin down a source that gives me the tutorials I need. The closest good source I found is here:

http://morrish.ca/beginner/digital.php

and even on this there is the ANSEL / ANSELH commands to disable a pin:

ANSELbits.ANS5 = 0; //disable AN5

also this guy uses the __delay_ms(); command in this code using only xc.h and a PIC16F690.

What I need is access to the correct header files with such headers as PWM, ADC etc as they are not in my libraries.
Yeah, I've had a bit of trouble myself, migrating from the Hi-Tech compiler to the XC8, I may just go back to it, but I'm moving out of 8-bit uCs, so the point may be moot.

The XC User guide defines __delay_ms(), __delay_us() and _delay(), but when I go into the delays file, I see the message I posted in the other thread:confused:

Perhaps this question should be brought up over on Microchip's forums...
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
when you switched from hi-tech to xc8, how did you find the xc8 C keywords? like I found the keywords TRIS and PORT but the same source didnt show how to set individual bits like TRISBbits.TRISB2 and PORTBbits.RB2 where I found it in another source.
 

tshuck

Joined Oct 18, 2012
3,534
when you switched from hi-tech to xc8, how did you find the xc8 C keywords? like I found the keywords TRIS and PORT but the same source didnt show how to set individual bits like TRISBbits.TRISB2 and PORTBbits.RB2 where I found it in another source.
WELL TRIS and PORT are PIC specific, it stands to reason that any compiler should have those, as they refer to a specific register, however they are defined in the header file for the chip you are using. So, Find the 16f877a.h(or whatever it's called) in your xc8 folder and look at teh way the bits are addressed individually....

XC is based off of Hi-Tech's compiler, so it should be similar...
 

JBM

Joined Feb 4, 2016
15
If you leave it alone for a while, does your LED turn off, I didn't look at it before, but I think your delays are HUGE!

Try this code:
Rich (BB code):
#include <xc.h>
#include <delays.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

//set your configuration bits!

#define _XTAL_FREQ 20000000

void main(void) {

TRISB = 0x00;
volatile unsigned int j = 0;
volatile int k = 0;
while(k < 10)
{
    PORTB = 0xFF;
    for(j=0;j<64000;j++);
    for(j=0;j<64000;j++);
    PORTB = 0x00;
    for(j=0;j<64000;j++);
    for(j=0;j<64000;j++);
    k++;
}
while(1);//wait forever
}
Hello
I had a similar problem with the code but the above code works fine, can u explain me the code
 

ErnieM

Joined Apr 24, 2011
8,377
Hi JBM. You really should start your own thread with a new question. There you can reference the old thread.

Line 16 sets up a loop for 10 times.
L18 turns the led on or off depending on the wiring. The next 2 lines make a delay.
Lines 21-23 do the same after changing the led.
Line 24 increments the loop counter so you stop at 10.

Line 26 is a tight loop so nothing else can be done till the device gets a reset.
 
Top