Author Topic: PIC12F509 programming - newby question.  (Read 2408 times)

0 Members and 1 Guest are viewing this topic.

Offline coolyotaTopic starter

  • Contributor
  • Posts: 18
  • Country: au
PIC12F509 programming - newby question.
« on: March 02, 2019, 11:43:40 am »
Hello forum :)

I am new to PIC programming so bear with me...

I am trying to make a simple LED flashing with PIC12F509 PIC, following the Gooligum tutorial.  I tried using the following code:

Code: [Select]
#include <xc.h>
#define _XTAL_FREQ 4000000  //Oscillator frequency for _delay()

/***** CONFIGURATION *****/
// int reset, no code protect, no watchdog, int RC clock
__CONFIG(MCLRE_OFF & CP_OFF & WDT_OFF & OSC_IntRC);


/***** MAIN PROGRAM *****/
void main()
{
    // Initialisation
    TRIS = 0b111101;            // configure GP1 (only) as an output

    // Main loop
    for (;;)
    {
        GPIObits.GP1 =   1;
        __delay_ms(100);
       
        GPIObits.GP1 =   0;
        __delay_ms(800);
    } 
}


My idea was to display a simple flashing LED, but as above it didn't work either.

Next up, DMM test on PIN 6 and VSS. Registering 0V.
PIN VDD and VSS = 4.54V.


Not sure where to head from here. Could you please help?

Thank you.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12863
Re: PIC12F509 programming - newby question.
« Reply #1 on: March 02, 2019, 02:11:39 pm »
I assume you didn't get any warning or error messages when you built the code or programmed the PIC.  I also assume you are attempting to test the code while the programmer is still connected, and probably powering your PIC.  If my assumptions are wrong, please correct me.   Also for the record, what programmer are you usiing?

Lets start by moving the LED to GP2 (pin 5), so there is no possibility that the ICSP programmer might be holding the pin low.
Three software changes are required, one in the initialisation:
   TRIS = 0b111011;
and both occurrences of GPIObits.GP1 change to GPIObits.GP2.

 
The following users thanked this post: coolyota

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2550
  • Country: us
Re: PIC12F509 programming - newby question.
« Reply #2 on: March 02, 2019, 04:31:17 pm »
And make your 'ON' time much longer.  A 100ms flash can be very hard to see.

Start by changing the 'ON' time from __delay_ms(100)  to  __delay(1000) 

and the 'OFF' time from  __delay_ms(800)  to  __delay_ms(2000)

You can set your desired timing after you get it working.


If you still have problems, I always set the configuration bits via MPLAB memory view and copy to my main function.

Code: [Select]
// CONFIG
#pragma config OSC = IntRC      // Oscillator Selection bits (internal RC oscillator)
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection off)
#pragma config MCLRE = OFF      // GP3/MCLR Pin Function Select bit (GP3/MCLR pin function is digital input, MCLR internally tied to VDD)
« Last Edit: March 02, 2019, 04:45:11 pm by MarkF »
 
The following users thanked this post: coolyota

Offline mariush

  • Super Contributor
  • ***
  • Posts: 5029
  • Country: ro
  • .
Re: PIC12F509 programming - newby question.
« Reply #3 on: March 02, 2019, 07:40:28 pm »
Also sometimes the __delay macros just don't work, even if you set the _XTAL_FREQ variable.

So I wrote my own functions some time ago, but they're for 16 Mhz clock (built in more powerful PIC16f micros). 

The delay_ms function below would still work reasonably well at 4 Mhz, without making any changes inside it.
You'd just have to say 25ms instead of 100ms for example, to delay for 100ms,  since most of the work is done by that asm(goto $+1) which takes 2 us at 4Mhz while it uses 0.5us at 16 Mhz, so basically if you say delay_ms(25) in your code, the function will more or less delay for four times as much compared to when running at 16 Mhz.
It won't be super accurate because that delay_4tcy will now delay for 4 us instead of 1us, so for every loop, the function will delay an extra 3us plus a couple us more in the while loops and that adds up if the number of ms is high etc etc

delay.h

Code: [Select]
// Delay routines for 16 Mhz clock.
//
// 16 Mhz = 4 Hz per cycle = 4 operations/cycles per uS
//

#ifndef __DELAYH_INIT

#define __DELAYH_INIT

#define delay_1tcy()    asm("nop")
#define delay_2tcy()    asm("goto $+1")
#define delay_4tcy()    asm("goto $+1");asm("goto $+1");
#define delay_10tcy()   delay_2tcy();delay_4tcy();delay_4tcy();

#define delay_500ns()   delay_2tcy()
#define delay_1us()     delay_4tcy()
#define delay_4us()     delay_1us();delay_1us();delay_1us();delay_1us();
#define delay_5us()     delay_4us();delay_1us();
#define delay_10us()    delay_5us();delay_5us();

#define delay_5ms()     delay_ms(5);
#define delay_10ms()    delay_ms(10);
#define delay_25ms()    delay_ms(25);
#define delay_50ms()    delay_ms(50);
#endif

extern void delay_25us();
extern void delay_50us();
extern void delay_100us();

extern void delay_1ms();

//extern void delay_10ms();
//extern void delay_25ms();
//extern void delay_50ms();

extern void delay_ms(unsigned char ms);

delay.c

Code: [Select]
/*
 * Hi-Tech C has internal macros : __delay(cycles), __delay_us(uS), __delay_ms(mS)
 *
 * The routines below are precomputed for 16 Mhz clock.
 */
#include "delay.h"


void delay_25us(){
    // function call and return is 4 cycles, on 16Mhz that's 1us
    // so delay for 24us here
    delay_10us();
    delay_10us();
    delay_4us();
}

void delay_50us(){
    delay_10us();
    delay_10us();
    delay_10us();
    delay_10us();
    delay_5us();
    delay_4us();
}

void delay_100us(){
    delay_50us();
    delay_10us();
    delay_10us();
    delay_10us();
    delay_10us();
    delay_5us();
    delay_4us();
}

void delay_1ms(){

    unsigned char n = 248;
    do {
    asm("goto $+1"); asm("goto $+1"); asm("goto $+1");
    asm("goto $+1"); asm("goto $+1"); asm("goto $+1");
    asm("nop");
    // decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)
    // goto loop start = 2 cycles

    } while(--n);

    // = 16 cycles x [n+1] + 1 (from last decfsz) - 2 (last goto is skipped)
    // 249x16+1-2 = 3983 cycles (1 = decfsz ), -2 for last goto
    // + 1        = 3984 cycles (assignment of 248 to n)
    // + 4        = 3988 cycles (function call and return)
    delay_2tcy();   // = 3990 cycles
    delay_10tcy();  // = 4000 cycles
}


// Delay up to 255 milliseconds - approximately (ms + 19 cycles).
// ms can be in range 0 to 255
void delay_ms(unsigned char ms) {
    unsigned char n;
    while(ms--) {    // time in cycles for the inner loop including
        n = 249;     // cycles = 19+16*ms*[1+n]
                     // cycles = 4000*ms + 19 for 16MHz clock
                     // cycles = 2000*ms + 19 for 8MHz clock
        delay_4tcy();
        do {
            asm("goto $+1");
            asm("goto $+1");
            asm("goto $+1");
            asm("goto $+1");
            asm("goto $+1");
            asm("goto $+1");
            asm("nop");
            // decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)
            // goto loop start  - 2 cycles

        } while(--n);
        // = 16 cycles x [n+1] + 1 (from last decfsz)
    }
}
« Last Edit: March 02, 2019, 07:42:13 pm by mariush »
 
The following users thanked this post: coolyota

Offline coolyotaTopic starter

  • Contributor
  • Posts: 18
  • Country: au
Re: PIC12F509 programming - newby question.
« Reply #4 on: March 03, 2019, 12:01:33 am »
I assume you didn't get any warning or error messages when you built the code or programmed the PIC.  I also assume you are attempting to test the code while the programmer is still connected, and probably powering your PIC.  If my assumptions are wrong, please correct me.   Also for the record, what programmer are you usiing?

Lets start by moving the LED to GP2 (pin 5), so there is no possibility that the ICSP programmer might be holding the pin low.
Three software changes are required, one in the initialisation:
   TRIS = 0b111011;
and both occurrences of GPIObits.GP1 change to GPIObits.GP2.

No error, both the build and upload to PIC uC were successful.

My environment is as follows:



If you still have problems, I always set the configuration bits via MPLAB memory view and copy to my main function.
Nice tip, learned something new today!

Changed the code to make LED turns on instead of blinking.
Code: [Select]

#include <xc.h>
#define true 1
#define false 0

//CONFIGURATION
// CONFIG
#pragma config OSC = IntRC      // Oscillator Selection bits (internal RC oscillator)
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection off)
#pragma config MCLRE = OFF      // GP3/MCLR Pin Function Select bit (GP3/MCLR pin function is digital input, MCLR internally tied to VDD)

//GLOBAL VARIABLES

void main(void) {
    //Set GP2 = OUTPUT. 0 = output, 1 = input
    TRIS = 0b111101;
   
    //Infinite loop
    for (;;){
        GPIO = 0b000010;     
    }
   
}


Success!

Using "pragma" configuration bits made a difference.

Thank you all for helping  :-+
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf