I recently converted to Microchip Tech PIC micro-controllers after using AVR from Atmel, I found myself enjoying the learning process and challenges that came with it. Getting my head around MPLAB is an on going process. I often see people bag MPLAB but honestly, it works. It's not as nice as AVR Studio (which I'm use to given that I use Visual Studio too)

Developing for desktop applications then moving to micro controllers, I realised just how much more there was to learn and just how much some development environments hand to the developer, its easy to forget the back ground code that goes into a lot of functions. Moving to Microchip PIC / MPLAB X has meant that libraries that were otherwise provided by some IDE's are not there so it means creating them. That's not a bad thing I don't think. At the end of the day it's all part of learning. 

Anyway, I started to use 7 segment LED's and realised that running out of outputs on a smaller chip would happen really quick. I've played a little with Multiplexing and Charlieplexing (I recommend you Google both), however I used shift registers on Arduino and AVR in the past for LCD screens and LED's so figured, can't be that hard for the PIC.

Well, this is what I came up with. After putting a screen shot on G+ it has been slightly modified from the original and I'm sure there is still room for improvement. But it works for me on MPLAB X with XC8 on a PIC18F2550, though it should be easy enough to modify for any PIC micro-controller.

simply include the file, initialise_74HC595(); and then write_74HC595(LED_numbers[5]); to display the number 5 for example.

I hope this helps others out in their learning process, Understanding Bitwise operators is going to make life easier too. I have this same code but for Atmel AVR Studio if anyone is wanting an AVR version.

/* 
 *      File: KJ_74HC595.h
 *    Author: Kim Jansen
 *   Created: 07 October 2013, 2:23 PM
 *   Licence: GNU General Public License (GPL) version 3
 */
#ifndef KJ_74HC595_H
#define	KJ_74HC595_H
/* If you change the below LAT bits, change the TRIS bits
 * in the initialise_74HC595() routine lower down too.
*/
#define DS_pin LATCbits.LATC0    // LAT for DS_pin (14)
#define SHCP_pin LATCbits.LATC1  // LAT for SHCP_pin (11)
#define STCP_pin LATCbits.LATC2  // LAT for STCP_pin (12)
char LED_numbers[10] =
{
    	0b11000000, // 0 (Common Anode 7 Segment LED)
	0b11111001, // 1 (A wired to Q0, B to Q1, C to Q2...G to Q6)
	0b10100100, // 2 (decimal to Q7)
	0b10110000, // 3
	0b10011001, // 4
	0b10010010, // 5
	0b10000010, // 6
	0b11111000, // 7
	0b10000000, // 8
	0b10010000  // 9
};
void initalise_74HC595()   // Call this in your main to setup the port.
{
    TRISCbits.TRISC0 = 0;  // TRIS for DS_pin
    TRISCbits.TRISC1 = 0;  // TRIS for SHCP_pin
    TRISCbits.TRISC2 = 0;  // TRIS for STCP_pin
}
// You shouldn't need to edit past here :)
void pulse_shift_clock()
{
	SHCP_pin = 1; // Set SHCP High
	SHCP_pin = 0; // Set SHCP Low
}
void write_74HC595(int databyte)
{
	STCP_pin = 0; // Set the latch pin low
	for(int databits=0; databits<8; databits++)
	{
		if(databyte & 0b10000000)
		{
                    DS_pin = 1; // Set the data pin high
		}
		else
		{
                    DS_pin = 0;
		}
		pulse_shift_clock();
		databyte <<= 1;
	}
	STCP_pin = 1; // Set the latch pin high
}
#endif	/* KJ_74HC595_H */