Delay in C for PIC16F88

Thread Starter

Ben_C

Joined Oct 19, 2010
65
Hi everyone,
I was adamant in getting this to work by myself I've been working on it over the past 2 days but really cant figure it out! This is what I want my code to do:
Do nothing until RB1 is high with momentary tactile switch and then when it is, to jump into the loop to blink the LED connected to RB0. I want the loop to go around 5 times (Therefore the LED to turn on 5 times) then exit the loop back to the start and again wait for RB1 to go high.

What it does is go into the loop but is not responsive to my "i <= N". For this code it loops through 9 times where as I only want it to loop 5 times! When I adjust delay settings it will blink for longer/shorter. It just seems i<= 5 has no effect..

I believe it has something to do with Config or Delay ..


Code:
#include <htc.h>
#include <pic.h>
#include <pic16f88.h>
#define _XTAL_FREQ 4000000


int main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;

    int i;

    if (RB1 = 1)
    {
        if (i <= 5)
        {
        RB0 = 1;
        __delay_ms (500);
        RB0 = 0;
        __delay_ms (500);
        i++;
        }
    }
}
 

adam555

Joined Aug 17, 2013
858
You forgot to assign '0' to 'i' when declaring it:

Code:
int i=0;
And you are also assigning '1' to 'RB1' with '=' in the first if, when you should have used the comparator '==':

Code:
if (RB1 == 1)
 

adam555

Joined Aug 17, 2013
858
I think it still won't work; you should have use a for loop instead of the second if:

Code:
int main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;

    if (RB1 == 1)
   {
        for( int i=1; i<=5; i++)
        {
        RB0 = 1;
        __delay_ms (500);
        RB0 = 0;
        __delay_ms (500);
       }
    }
}
 

Thread Starter

Ben_C

Joined Oct 19, 2010
65
Sorry, yes I've edited it so many times I just simply forgot to give a value to it before posting here :p I have tried this and it doesn't work, still blinking 9 times.. :(
 

Thread Starter

Ben_C

Joined Oct 19, 2010
65
Also tried for loop too, and while (RB1 = 1) loop.. I'm missing something with Timer set up, or __delay_ms. __delay_ms is showing as Exclamation mark on MPLABX, but when I put _delay it seems to like it... :s
 
Last edited:

Thread Starter

Ben_C

Joined Oct 19, 2010
65
Screenshot of code, When I debug program and step into it does loop the 5 times, gotta be clock malfunction/incorrect set-up.. Im going bald figuring this out.
 

Attachments

adam555

Joined Aug 17, 2013
858
Also tried for loop too, and while (RB1 = 1) loop.. I'm missing something with Timer set up, or __delay_ms. __delay_ms is showing as Exclamation mark on MPLABX, but when I put _delay it seems to like it... :s

If you use "while (RB1 = 1)" you are assigning 1 to RB1; you are not comparing it.

'=' is to assign,
'==' is to compare.
 

adam555

Joined Aug 17, 2013
858
Just tested this code and works perfectly:

Code:
void main(void)
{
    TRISBbits.TRISB0 = 1;
    ANSELH = 0;
  
    TRISD = 0;
    PORTD=0;

    if (RB0 == 0)
   {
        for( int i=1; i<=5; i++)
        {
        RD0 = 1;
        __delay_ms (500);
        RD0 = 0;
        __delay_ms (500);
       }
    }
}
Maybe you need to configure the ports before using them (e.g. turning off the analog input as I did for my PIC16F887), or maybe your switch is normally 1, and 0 when pressed; like my configuration.
 
Last edited:

adam555

Joined Aug 17, 2013
858
This code will run only one time in a uC.

You'll need to put your if - code in a while(1) - loop.

AFAIK.
Your right; I missed that one. Though it works the same in MPLAB with XC8.

The code I posted above should be:

Code:
int main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;

    while(1)
{
    if (RB1 == 1)
   {
        for( int i=1; i<=5; i++)
        {
        RB0 = 1;
        __delay_ms (500);
        RB0 = 0;
        __delay_ms (500);
       }
    }
}
}
 

Thread Starter

Ben_C

Joined Oct 19, 2010
65
Hmm, analogue isn't associated to these 2 pins, I did try it though to no avail. I've tried this code:


Code:
#include <htc.h>
#include <pic.h>
#include <pic16f88.h>
#define _XTAL_FREQ 4000000


void main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;
    PORTB = 0b00000000;
   
    while(1)
    {
    if (RB1 == 1)
        {
        for( int i=1; i<=5; i++)
        {
        RB0 = 1;
        __delay_ms (500);
        RB0 = 0;
        __delay_ms (500);
        }
        }
    }
}
and nothing. Is it something to do with Timer0, or Config settings? Maybe WDT isnt set correctly.. ? Im running off INTRC btw at 4Mhz
 

Thread Starter

Ben_C

Joined Oct 19, 2010
65
For the above code, it blinks 9 times for this code (notice delay @ 200ms) it blinks 24 times!


Code:
#include <htc.h>
#include <pic.h>
#include <pic16f88.h>
#define _XTAL_FREQ 4000000


void main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;
    PORTB = 0b00000000;
   
    while(1)
    {
    if (RB1 == 1)
        {
        for( int i=1; i<=5; i++)
        {
        RB0 = 1;
        __delay_ms (200);
        RB0 = 0;
        __delay_ms (200);
        }
        }
    }
}
 

adam555

Joined Aug 17, 2013
858
Try disabling WDT, BOREN, MCLR, PWRTEN and using INTRC with I/O port function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin. This way you will make sure none of those are interfering.

It would also be good to test the switch on its own, and see if it's working properly. For example:

Code:
if(RB1 == 1)
    RB0 = 1;
else
    RB0 = 0;
 

Thread Starter

Ben_C

Joined Oct 19, 2010
65
With a little bit of patience, I got it to work! Thanks guys, it was config settings and CLK output. Adam I believe it was because I was using Internal clock I had to use RA7 as output, I couldnt use RB0 as I wasnt using external crystal :D

If anyone else stumbles upon this it's :

Code:
#include <htc.h>
#include <pic16f88.h>
#include <xc.h>

#define _XTAL_FREQ 4000000

#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB0      // CCP1 Pin Selection bit (CCP1 function on RB0)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// CONFIG2
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode enabled)



void main(void)

{
    OSCCON = 0x60;
    TRISB = 0b00000010;
    TRISA = 0b00000000;
    PORTA = 0b00000000;
  
    while(1)
    {
    if (RB1 == 1)
        {
        for( int i=1; i<=8; i++)
        {
        RA7 = 1;
        __delay_ms (500);
        RA7 = 0;
        __delay_ms (500);
        }
        }
    }
}
 
Top