Select Page

Continuing with using a PIC10F322 as a 555 replacement – Here is a basic Astable XC code.

The output pulses are on PORT.A0

Run down of the code

We do some basic setup to get output on Port.A0, Set the speed of the cpu to 16Mhz.

The code loop, toggles PORT.A0 on and off.

At 16Mhz and no delays, the output pulse is around 1.333Mhz or roughly a 750ns pulse – shown in the logic graph below.

Note in the code I have two NOP instructions – A nop is no operation – it means the CPU sits for 1 instruction cycle and does nothing.

Why two? Because once the code reaches the bottom of the loop – it will execute a JUMP instruction – it takes two cycles for it to execute. In order to get a 50% duty cycle we need to account for this.

Working out the delay for other frequencies

At 16Mhz, the instruction cycle is 4Mhz, or 250ns per instruction (not taking into program branch instructions – these are two cycles)

Need a 1us pulse? Take 1us x 1000 / 250ns. That is 4 instructions – (we are already using 3 instructions) so you will need to add an additional NOP once the port is high and one after the port is low.


 * File:  555_astable.c
 * Author: Jamie Starling - 
 * Created on:  September 7, 2021, 7:45 PM
 * Code/Circuit provided as-is.

#include <xc.h>
#include <stdint.h>

//Device Configuration
#pragma config FOSC = INTOSC  // Oscillator Selection 
#pragma config BOREN = ON    // Brown-out Reset
#pragma config WDTE = OFF    // Watchdog Timer
#pragma config PWRTE = ON    // Power-up Timer
#pragma config MCLRE = OFF   // MCLR Pin Function Select bit->MCLR pin function is digital input, MCLR internally tied to VDD
#pragma config CP = OFF      // Code Protection 
#pragma config LVP = OFF     // Low-Voltage Programming 
#pragma config LPBOR = ON    // Brown-out Reset Selection bits
#pragma config BORV = LO    // Brown-out Reset Voltage Selection
#pragma config WRT = OFF    // Flash Memory Self-Write Protection

//Used to calculate the delay time - Change depending on processor Speed
#define _XTAL_FREQ 16000000  //16Mhz

void setup(void);

void main(void)
        LATAbits.LATA0 = 1;  //Put A.0 High
        /*We call an assembly insuctgion here NOP - no operation it burns 1 CPU cycle
         *We add two - because once the code hits the end, it will execute an ASM JUMP which takes two cpu cycles to complete
         *this gives us a nice square 50% dutycycle wave at 750ns high and low  */
        //Add Delay here if you need something different 
        LATAbits.LATA0 = 0;  //Put A.0 low   
        //AND Add the same Delay here if you need something different for 50%

void setup(void)
    //Disable analog for A0, set as Output, Set to Low
    ANSELAbits.ANSA0 = 0;
    TRISAbits.TRISA0 = 0; //A0 Output
    LATAbits.LATA0 = 0;  //Put A0 low
    //Set the System Clock - You can change this to match the setting you are looking for
    OSCCONbits.IRCF = 0b111;  //Set System Clock to 16Mhz FOSC/4 = 4Mhz

Let’s talk!

I am always looking for oppunities to put my skills to work.
I am always looking to connect with like minded people.

Want to connect – drop me an email