Microcontrollers Programming | Sample Programs

HomeMicrocontroller Programming | Course HomeMicrocontrollers Programming | Sample Programs 

Microcontrollers Programming – Sample Programs

Microcontroller programming examples or the sample programs is the first step you take to transition from theory to practical. These sample programs typically demonstrated in a classroom will ensure you are able to immediately see it running in front of your eyes. Added to that our mentors will provide you some Microcontroller exercises where you will be modifying the code in the class itself. By doing this fill-in-the-blank approach, will take out your fear of coding. Gear up to learn some microcontroller programming examples and implement them!

Sample Programs

Brief:

A simple program to control (Toggle) the LED Array connected at PORTB using byte option.
 

Source Code:

 

main.c

 


/*------------------------------------------------------------------------------------------------- 
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : LED Array - Byte Access
 *   Description    : A simple program to control (Toggle) the LED Array connected at PORTB
 *                    using byte option.
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"

static void init_config(void)
{
	ADCON1 = 0x0F;

	LED_ARRAY = OFF;
	
	TRISB = 0x00;
}

void main(void)
{
	unsigned long i;

	init_config();

	while (1)
	{
		LED_ARRAY = 0x55;
		for (i = 1000000; i--; );

		LED_ARRAY = 0xAA;
		for (i = 1000000; i--; );
	}
}

main.h


#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC		= XT
#pragma config WDT		= OFF
#pragma config BOREN		= OFF
#pragma config PBADEN		= OFF
#pragma config LVP		= OFF

#define LED_ARRAY		PORTB

#define OFF			0x00

#endif

Microcontroller Programming Example Output:

 

Brief:

A simple program to control (Toggle) a LED connected at RBO of PORTB.

Source Code:

 

main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : LED Array - Bit Access
 *   Description    : A simple program to control (Toggle) a LED connected at RBO of PORTB
 *   Tools	    : Compiler - xc8 (V1.36 Light Mode) 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"

static void init_config(void)
{
	ADCON1 = 0x0F;

	LED1 = OFF;
	
	TRISB0 = 0;
}

void main(void)
{
	unsigned long i;

	init_config();

	while (1)
	{
		LED1 = ON;
		for (i = 1000000; i--; );

		LED1 = OFF;
		for (i = 1000000; i--; );
	}
}
 
main.h
#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#define LED1				RB0

#define ON				1
#define OFF				0

#endif

#endif

Microcontrollers programming Example output:

Brief:

An example code to demonstarte the digital keypad using tactile keys. The example demonstrates state change detection.
 

Source Code:

 

digital_keypad.c

 /*-------------------------------------------------------------------------------------------------			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : digital_keypad.c
 *   Title          : Digital Keypad - Level Triggering
 *   Description    : A digital keypad module providing both level and edge triggering
 *                    functions
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

void init_digital_keypad(void)
{
	TRISC = TRISC | INPUT_PINS;
}

unsigned char read_digital_keypad(unsigned char detection_type)
{
	static unsigned char once = 1;

	if (detection_type == STATE_CHANGE)
	{
		if (((KEY_PORT & INPUT_PINS) != ALL_RELEASED) && once)
		{
			once = 0;

			return (KEY_PORT & INPUT_PINS);
		}
		else if ((KEY_PORT & INPUT_PINS) == ALL_RELEASED)
		{
			once = 1;
		}
	}
	else if (detection_type == LEVEL)
	{
		return (KEY_PORT & INPUT_PINS);
	}

	return 0xFF;
}

digital_keypad.h

#ifndef DIGITAL_KEYPAD_H											  	    
#define DIGITAL_KEYPAD_H

#define LEVEL				0
#define STATE_CHANGE			1

#define SWITCH1				0x0E
#define SWITCH2				0x0D
#define SWITCH3				0x0B
#define SWITCH4				0x07
#define ALL_RELEASED			0x0F

#define INPUT_PINS			0x0F

#define KEY_PORT			PORTC

void init_digital_keypad(void);
unsigned char read_digital_keypad(unsigned char detection_type);

#endif

main.c

*------------------------------------------------------------------------------------------------- 
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Digital Keypad - Level Detection
 *   Description    : An example code to demonstarte the digital keypad using tactile keys.
 *                    The example demonstrates level trigged operation
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

void glow_on_press(unsigned char key)
{
	if (key == SWITCH1)
	{
		LED1 = ON;
	}
	else
	{
		LED1 = OFF;
	}
}

static void init_config(void)
{
	ADCON1 = 0x0F;

	LED1 = OFF;
	TRISB0 = 0;

	init_digital_keypad();
}

void main(void)
{
	unsigned char key;

	init_config();

	while (1)
	{
		key = read_digital_keypad(LEVEL);
		glow_on_press(key);
	}
}

main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

/* The name LED1 is based on the legend in eCee Board */
#define LED1				RB0

#define ON				1
#define OFF				0

#endif


 

Microcontroller programming Example output:

Brief:

An example code to demonstrate the digital keypad using tactile keys. The example demonstrates level trigged operation.

 

Source Code:

digital_keypad.c

 

/*-------------------------------------------------------------------------------------------------			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : digital_keypad.c
 *   Title          : Digital Keypad - Level Triggering
 *   Description    : A digital keypad module providing both level and edge triggering
 *                    functions
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

void init_digital_keypad(void)
{
	TRISC = TRISC | INPUT_PINS;
}

unsigned char read_digital_keypad(unsigned char detection_type)
{
	static unsigned char once = 1;

	if (detection_type == STATE_CHANGE)
	{
		if (((KEY_PORT & INPUT_PINS) != ALL_RELEASED) && once)
		{
			once = 0;

			return (KEY_PORT & INPUT_PINS);
		}
		else if ((KEY_PORT & INPUT_PINS) == ALL_RELEASED)
		{
			once = 1;
		}
	}
	else if (detection_type == LEVEL)
	{
		return (KEY_PORT & INPUT_PINS);
	}

	return 0xFF;
}

 

digital_keypad.h

#ifndef DIGITAL_KEYPAD_H											  	 
#define DIGITAL_KEYPAD_H

#define LEVEL				0
#define STATE_CHANGE			1

#define SWITCH1				0x0E
#define SWITCH2				0x0D
#define SWITCH3				0x0B
#define SWITCH4				0x07
#define ALL_RELEASED			0x0F

#define INPUT_PINS			0x0F

#define KEY_PORT			PORTC

void init_digital_keypad(void);
unsigned char read_digital_keypad(unsigned char detection_type);

#endif


main.c

 /*-------------------------------------------------------------------------------------------------			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Digital Keypad - State Change Detection
 *   Description    : An example code to demonstarte the digital keypad using tactile keys.
 *                    The example demonstrates state change detection
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

void state_change_detection(unsigned char key)
{
	if (key == SWITCH1)
	{
		LED1 = !LED1;
	}
}

static void init_config(void)
{
	ADCON1 = 0x0F;

	LED1 = OFF;
	TRISB0 = 0;

	init_digital_keypad();
}

void main(void)
{
	unsigned char key;
	unsigned int i;

	init_config();

	while (1)
	{
		key = read_digital_keypad(STATE_CHANGE);
		state_change_detection(key);
		/* A delay to suppress key bounce */
		for (i = 50000; i--; );
	}
}


main.h

#ifndef DIGITAL_KEYPAD_H											  	    
#ifndef MAIN_H       												 	 
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

/* The name LED1 is based on the legend in eCee Board */
#define LED1				RB0

#define ON				1
#define OFF				0

#endif


Microcontrollers programming Example output:

Brief:

A simple program to demonstrate Seven Segment Display.
 

Source Code:

main.c

/*------------------------------------------------------------------------------------------------- 			    
  *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Seven Segment Display
 *   Description    : A simple program to demonstrate Seven Segment Display
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "ssd_display.h"

const unsigned char digits[] = {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};
static unsigned char ssd[MAX_SSD_CNT];

void init_config(void)
{
	init_ssd_control();
}

void main(void)
{
	init_config();

	while (1)
	{
          ssd[3] = ZERO;
          ssd[2] = ONE;
          ssd[1] = TWO;
          ssd[0] = THREE;
	  display(ssd);
	}
}

 

main.h

#ifndef MAIN_H														     
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#endif

ssd_display.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : ssd_display.c
 *   Title          : Seven Segment Display Driver
 *   Description    : A module to drive Seven Segment Display 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "ssd_display.h"

void init_ssd_control(void)
{
	/* Setting PORTB as output for Data Lines */
	TRISD = 0x00;
	/* Setting SSD Enable lines as output */
	TRISA = TRISA & 0xF0;

	/* Switching OFF all the SSDs to start with */
	SSD_CNT_PORT = SSD_CNT_PORT & 0xF0;
}

/* Better if implemented in timer handler */
void display(unsigned char data[])
{
	unsigned int wait;
	unsigned char data_bit;
	unsigned char digit;

	for (digit = 0; digit < MAX_SSD_CNT; digit++)
	{
		SSD_DATA_PORT = data[digit];
		SSD_CNT_PORT = (SSD_CNT_PORT & 0xF0) | (0x01 << digit);

		for (wait = 1000; wait--; );
	}
}


ssd_display.c

#ifndef SSD_DISPLAY_H  													    
#define SSD_DISPLAY_H  

#define MAX_SSD_CNT			4

#define HIGH				1
#define LOW				0

/* This values are for common cathode display */
#define ZERO				0xE7
#define ONE				0x21
#define TWO				0xCB
#define THREE				0x6B
#define FOUR				0x2D
#define FIVE				0x6E
#define SIX				0xEE
#define SEVEN				0x23
#define EIGHT				0xEF
#define NINE				0x6F
#define DOT				0x10
#define BLANK				0x00
/* Need to fill All others */
#define M_ONE				0x9D
#define MINUS				0xFD

#define MAX_SSD_CNT			4
#define MAX_COUNT			9

#define COUNT_ADDR			0x00

#define SSD_DATA_PORT			PORTD
#define SSD_CNT_PORT			PORTA

void init_ssd_control(void);
void display(unsigned char data[]);

#endif

 

Microcontroller programming Example output: 

Brief:

A simple program to demonstrate external interrupt at INT pin.

Source Code:

external_interrupt.c

 

 /*-------------------------------------------------------------------------------------------------			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : external_interrupt.c
 *   Title          : External Interrupt Configuration
 *   Description    : A configuration function to detect rising edge signal
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "external_interrupt.h"

void init_external_interrupt(void)
{
	INTEDG0 = 1;
	INT0F = 0;
	INT0E = 1;
}

 

external_interrupt.h

#ifndef EXTERNAL_INTERRUPT_H							            
#define EXTERNAL_INTERRUPT_H 

void init_external_interrupt(void);

#endif


isr.c

/*------------------------------------------------------------------------------------------------- 			   
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : isr.c
 *   Title          : Interrupt Service Routine
 *   Description    : Signal registration happens here
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "isr.h"

bit key_detected;

void interrupt isr(void)
{
	if (INT0F == 1)
	{
		key_detected = 1;

		INT0F = 0;
	}
}


isr.h

#ifndef ISR_H														   
#define ISR_H

#endif


main.c

/*------------------------------------------------------------------------------------------------- 
*   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : External Interrupts
 *   Description    : A simple program to demonstarte external interrupt at INT pin
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "external_interrupt.h"
#include "isr.h"

extern bit key_detected;

static void init_config(void)
{
	ADCON1 = 0x0F;

	TRISB7 = 0;
	TRISB0 = 1;

	init_external_interrupt();

	GIE = 1;
}

void main(void)
{
	unsigned short wait;

    init_config();

    while (1)
    {
		if (key_detected)
		{
			key_detected = 0;
			LED8 = !LED8;
		}

		for (wait = 10000; wait--; );
    }
}


main.h

#ifndef MAIN_H
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

/* The name LED1 is based on the legend in eCee Board */
#define LED8				RB7

#define ON					
#define OFF					

#endif


Microcontrollers programming Example output: 

Brief:

A program demonstrating Software PWM (Bit Banged).
 
Source Code:
 

digital_keypad.c

 

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : digital_keypad.c
 *   Title          : Digital Keypad - Level Triggering
 *   Description    : A digital keypad module providing both level and edge triggering
 *                    functions
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

void init_digital_keypad(void)
{
	TRISC = TRISC | INPUT_PINS;
}

unsigned char read_digital_keypad(unsigned char detection_type)
{
	static unsigned char once = 1;

	if (detection_type == STATE_CHANGE)
	{
		if (((KEY_PORT & INPUT_PINS) != ALL_RELEASED) && once)
		{
			once = 0;

			return (KEY_PORT & INPUT_PINS);
		}
		else if ((KEY_PORT & INPUT_PINS) == ALL_RELEASED)
		{
			once = 1;
		}
	}
	else if (detection_type == LEVEL)
	{
		return (KEY_PORT & INPUT_PINS);
	}

	return 0xFF;
}


digital_keypad.h

#ifndef DIGITAL_KEYPAD_H   					
#define DIGITAL_KEYPAD_H

#define LEVEL					0
#define STATE_CHANGE			1

#define SWITCH1					0x0E
#define SWITCH2					0x0D
#define SWITCH3					0x0B
#define SWITCH4					0x07
#define ALL_RELEASED			0x0F

#define INPUT_PINS				0x0F

void init_digital_keypad(void);
unsigned char read_digital_keypad(unsigned char detection_type);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Clock I/O - PWM
 *   Description    : A program demonstrating Software PWM (Bit Banged) 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "digital_keypad.h"

#define PERIOD	100

void software_pwm(void)
{
	unsigned char key;
	static unsigned short wait = 0;
	static unsigned char prog_cycle;
	static unsigned char duty_change = 50;

	key = read_digital_keypad(LEVEL);

	if (!wait--)
	{
		wait = 10000;

		if (key == SWITCH1)
		{
			if (duty_change != PERIOD)
			{
				duty_change++;
			}
		}

		if (key == SWITCH2)
		{
			if (duty_change != 0)
			{
				duty_change--;
			}
		}
	}

	if (prog_cycle < duty_change)
	{
		LED1 = ON;
	}
	else
	{
		LED1 = OFF;
	}

	if (prog_cycle++ == PERIOD)
	{
		prog_cycle = 0;
	}
}

static void init_config(void)
{
	ADCON1 = 0x0F;

	LED1 = OFF;
	
	TRISB0 = 0;

	init_digital_keypad();
}

void main(void)
{
	init_config();

	while (1)
	{
		software_pwm();
	}
}


main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#define LED1				RB0

#define KEY_PORT			PORTC

#define ON				1
#define OFF				0

#endif

Microcontroller programming Example output: 

Brief:

A code to demonstrate the working of Timer module.
 

Source Code:

isr.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : isr.c
 *   Title          : Timer Module - Timer 0 ISR
 *   Description    : An ISR code to generate 1 second timing
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"

void interrupt isr(void)
{
	static unsigned short count;

	if (TMR0IF)
	{
		TMR0 = TMR0 + 8;

		if (count++ == 20000)
		{
			count = 0;
			LED1 = !LED1;
		}

		TMR0IF = 0;
	}
}


isr.h

#ifndef ISR_H														   
#define ISR_H

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Timer Module - Timer 0
 *   Description    : A code to demonstrate the working of Timer module 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "timer0.h"

void init_config(void)
{
	/* Clear old content */
	PORTB = 0x00;

	/* Set PORTB as a Output */
	TRISB = 0x00;

	/* Config PORTB as digital */
	ADCON1 = 0x0F;

	init_timer0();

	/* Global Interrupt Enable */
	GIE = 1;
}

void main(void)
{
	init_config();

	while (1)
	{
		;
	}
}


main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#define LED1				RB0

#define KEY_PORT			PORTC

#define ON				1
#define OFF				0

#endif


timer0.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : timer0.c
 *   Title          : Timer Module - Timer 0 Initialiation
 *   Description    : A initialization code to enable timer 0 module
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "timer0.h"

void init_timer0(void)
{
	/*
	 * Setting instruction cycle clock (Fosc / 4) as the source of
	 * timer0
	 */
	T0CS = 0;

	TMR0 = 6;

	/* Clearing timer0 overflow interrupt flag bit */
	T0IF = 0;

	/* Enabling timer0 overflow interrupt */
	TMR0IE = 1;
}


timer0.h

#ifndef TIMER0_H												
#define TIMER0_H

void init_timer0(void);

#endif

 

Microcontrollers programming Example output:

Brief:

Module to make CLCD work in 8 bit mode.
 

Source Code:

clcd.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : clcd.c
 *   Title          : CLCD Driver
 *   Description    : Module to make CLCD work in 8 bit mode
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"

void clcd_write(unsigned char byte, unsigned char control_bit)
{
	CLCD_RS = control_bit;
	CLCD_PORT = byte;

	/* Should be atleast 200ns */
	CLCD_EN = HI;
	CLCD_EN = LO;

	PORT_DIR = INPUT;
	CLCD_RW = HI;
	CLCD_RS = INSTRUCTION_COMMAND;

	do
	{
		CLCD_EN = HI;
		CLCD_EN = LO;
	} while (CLCD_BUSY);

	CLCD_RW = LO;
	PORT_DIR = OUTPUT;
}

void init_clcd()
{
	/* Set PortD as output port for CLCD data */
	TRISD = 0x00;
	/* Set PortC as output port for CLCD control */
	TRISC = TRISC & 0xF8;

	CLCD_RW = LO;

	TWO_LINE_5x7_MATRIX_8_BIT;
	CURSOR_HOME;
	DISP_ON_AND_CURSOR_OFF;
	CLEAR_DISP_SCREEN;
}

void clcd_print(const unsigned char *data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	while (*data != '\0')
	{
		clcd_write(*data++, DATA_COMMAND);
	}
}

void clcd_putch(const unsigned char data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	clcd_write(data, DATA_COMMAND);
}


clcd.h

#ifndef CLCD_H														    
#define CLCD_H

#define HI				1
#define LO				0

#define INPUT				0xFF
#define OUTPUT				0x00

#define DATA_COMMAND			1
#define INSTRUCTION_COMMAND		0

#define LINE1(x)			(0x80 + (x))
#define LINE2(x)			(0xC0 + (x))

#define TWO_LINE_5x7_MATRIX_8_BIT	clcd_write(0x38, INSTRUCTION_COMMAND)
#define CLEAR_DISP_SCREEN		clcd_write(0x01, INSTRUCTION_COMMAND)
#define CURSOR_HOME			clcd_write(0x02, INSTRUCTION_COMMAND)
#define DISP_ON_AND_CURSOR_OFF		clcd_write(0x0C, INSTRUCTION_COMMAND)

#define CLCD_PORT			PORTD
#define CLCD_EN				RC2
#define CLCD_RS				RC1
#define CLCD_RW				RC0
#define CLCD_BUSY			RD7
#define PORT_DIR			TRISD7

void init_clcd(void);
void clcd_print(const unsigned char *data, unsigned char addr);
void clcd_putch(const unsigned char data, unsigned char addr);
void clcd_write(unsigned char bit_values, unsigned char control_bit);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : CLCD - Character Liquid Crystal Display
 *   Description    : A code to demonstrate the working of CLCD module
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"

static void init_config(void)
{
    init_clcd();
}

void main(void)
{
    init_config();

    while (1)
    {
        clcd_putch('H', LINE1(0)); 
        clcd_print("Hello", LINE2(4)); 
    }
}/pre>

main.h
#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#define OFF				0xFF

#endif

 

 

Microcontrollers programming Example output:

Brief:

A simple program to demonstrate the scanning of Matrix Keypad using tactile switches.
 

Source Code:

clcd.c

/*------------------------------------------------------------------------------------------------- 			    
*   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : clcd.c
 *   Title          : CLCD Driver
 *   Description    : Module to make CLCD work in 8 bit mode
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"

void clcd_write(unsigned char byte, unsigned char control_bit)
{
	CLCD_RS = control_bit;
	CLCD_PORT = byte;

	/* Should be atleast 200ns */
	CLCD_EN = HI;
	CLCD_EN = LO;

	PORT_DIR = INPUT;
	CLCD_RW = HI;
	CLCD_RS = INSTRUCTION_COMMAND;

	do
	{
		CLCD_EN = HI;
		CLCD_EN = LO;
	} while (CLCD_BUSY);

	CLCD_RW = LO;
	PORT_DIR = OUTPUT;
}

void init_clcd()
{
	/* Set PortD as output port for CLCD data */
	TRISD = 0x00;
	/* Set PortC as output port for CLCD control */
	TRISC = TRISC & 0xF8;

	CLCD_RW = LO;

	TWO_LINE_5x7_MATRIX_8_BIT;
	CURSOR_HOME;
	DISP_ON_AND_CURSOR_OFF;
	CLEAR_DISP_SCREEN;
}

void clcd_print(const unsigned char *data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	while (*data != '\0')
	{
		clcd_write(*data++, DATA_COMMAND);
	}
}

void clcd_putch(const unsigned char data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	clcd_write(data, DATA_COMMAND);
}


clcd.h

#ifndef CLCD_H														    
#define CLCD_H

#define HI				1
#define LO				0

#define INPUT				0xFF
#define OUTPUT				0x00

#define DATA_COMMAND			1
#define INSTRUCTION_COMMAND		0

#define LINE1(x)			(0x80 + (x))
#define LINE2(x)			(0xC0 + (x))

#define TWO_LINE_5x7_MATRIX_8_BIT	clcd_write(0x38, INSTRUCTION_COMMAND)
#define CLEAR_DISP_SCREEN		clcd_write(0x01, INSTRUCTION_COMMAND)
#define CURSOR_HOME			clcd_write(0x02, INSTRUCTION_COMMAND)
#define DISP_ON_AND_CURSOR_OFF		clcd_write(0x0C, INSTRUCTION_COMMAND)

#define CLCD_PORT			PORTD
#define CLCD_EN				RC2
#define CLCD_RS				RC1
#define CLCD_RW				RC0
#define CLCD_BUSY			RD7
#define PORT_DIR			TRISD7

void init_clcd(void);
void clcd_print(const unsigned char *data, unsigned char addr);
void clcd_putch(const unsigned char data, unsigned char addr);
void clcd_write(unsigned char bit_values, unsigned char control_bit);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
*   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Matrix Keypad
 *   Description    : A simple program to demonstrate the scanning of Matrix Keypad using
 *   		      tactile switches
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "matrix_keypad.h"
#include "clcd.h"

void check_matrix_keypad(void)
{
	unsigned char key;
	unsigned short i;

	key = read_switches(LEVEL_CHANGE);

	if (key != ALL_RELEASED)
	{
		clcd_print("Key ", LINE2(1));
		clcd_putch('0' + (key / 10), LINE2(5));
		clcd_putch('0' + (key % 10), LINE2(6));
		clcd_print(" Pressed ", LINE2(7));

		RB0 = !RB0;

		for (i = 50000; i--; );
	}
	else
	{
		//clcd_print(" No Key Pressed ", LINE2(0));
	}
}

void init_config(void)
{
	init_matrix_keypad();
	init_clcd();

	clcd_print(" Matrix  Keypad ", LINE1(0));
}

void main(void)
{
	init_config();

	while(1)
	{
		check_matrix_keypad();
	}
}


main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#endif


matrix_keypad.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#endif

 

Microcontrollers programming Example output:

Brief:

A simple program to demonstrate reading Analog Inputs.

Source Code:

adc.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : adc.c
 *   Title          : ADC Driver
 *   Description    : Module to scan analog channel 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "adc.h"

void init_adc(void)
{
	/* Selecting right justified ADRES Registers order */
	ADFM = 1;

	/* 
	 * Acqusition time selection bits 
	 * Set for 4 Tad
	 */
	ACQT2 = 0;
	ACQT1 = 1;
	ACQT0 = 0;

	/*
	 * Selecting the conversion clock of Fosc / 32 -> 1.6usecs -> 1Tad
	 * Our device frequency is 20 MHz
	 */
	ADCS0 = 0;
	ADCS1 = 1;
	ADCS2 = 0;

	/* Stop the conversion to start with */
	GODONE = 0;

	/* Selecting the channel */
	CHS2 = 1;

	/* Voltage reference bit as VSS */
	VCFG1 = 0;
	/* Voltage reference bit as VDD */
	VCFG0 = 0;

	/* Just clearing the ADRESH & ADRESL registers, for time pass */
	ADRESH = 0;
	ADRESL = 0;

	/* Turn ON the ADC module */
	ADON = 1;
}

unsigned short read_adc(unsigned char channel)
{
	unsigned short reg_val;

	/* Set the required channel */
	ADCON0 = (ADCON0 & 0xC3) | (channel << 2);
	/* Set the required pin as analog pin */
	ADCON1 = (ADCON1 & 0xF0) | (0x0E - channel);

	/* Start the conversion */
	GO = 1;
	while (GO);
	reg_val = (ADRESH << 8) | ADRESL; 

	return reg_val;
}


adc.h

#ifndef ADC_H														    
#define ADC_H

#define CHANNEL0		0x00
#define CHANNEL1		0x01
#define CHANNEL2		0x02
#define CHANNEL3		0x03
#define CHANNEL4		0x04
#define CHANNEL5		0x05
#define CHANNEL6		0x06
#define CHANNEL7		0x07
#define CHANNEL8		0x08
#define CHANNEL9		0x09
#define CHANNEL10		0x0A

void init_adc(void);
unsigned short read_adc(unsigned char channel);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Analog to Digital Convertor
 *   Description    : A simple program to demonstrate reading Analog Inputs
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "adc.h"

void glow_led(unsigned short adc_reg_val)
{
	unsigned char i;

	if (adc_reg_val > 512)
	{
		LED1 = ON;
	}
	else
	{
		LED1 = OFF;
	}
}

static void init_config(void)
{
	LED1 = OFF;

	TRISB0 = 0;

	init_adc();
}

void main(void)
{
	unsigned short adc_reg_val;

	init_config();

	while (1)
	{
		adc_reg_val = read_adc(CHANNEL4);
		glow_led(adc_reg_val);
	}
}


main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define ON   1
#define OFF  0

#define LED1 RB0

#endif

 

Microcontrollers programming Example output:

Brief:

A simple program to demonstrate host and target communication using UART.
 

Source Code:

main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Universal Asynchronus Receive Transmit
 *   Description    : A simple program to demonstrate host and target communication
 *   		      using UART
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "uart.h"

void init_config(void)
{
	init_uart();

	puts("Emertxe Information Technologies. Press any key to continue\n\r");
	getch();
}

void main(void)
{
	init_config();

	puts("Welcome. This is UART Test Code.\n\r");
	puts("You should get back whatever you type:\n\r");

	while (1)
	{
		getche();
	}
}


main.h

#ifndef CLCD_H														    
#define CLCD_H

#define HI				1
#define LO				0

#define INPUT				0xFF
#define OUTPUT				0x00

#define DATA_COMMAND			1
#define INSTRUCTION_COMMAND		0

#define LINE1(x)			(0x80 + (x))
#define LINE2(x)			(0xC0 + (x))

#define TWO_LINE_5x7_MATRIX_8_BIT	clcd_write(0x38, INSTRUCTION_COMMAND)
#define CLEAR_DISP_SCREEN		clcd_write(0x01, INSTRUCTION_COMMAND)
#define CURSOR_HOME			clcd_write(0x02, INSTRUCTION_COMMAND)
#define DISP_ON_AND_CURSOR_OFF		clcd_write(0x0C, INSTRUCTION_COMMAND)

#define CLCD_PORT			PORTD
#define CLCD_EN				RC2
#define CLCD_RS				RC1
#define CLCD_RW				RC0
#define CLCD_BUSY			RD7
#define PORT_DIR			TRISD7

void init_clcd(void);
void clcd_print(const unsigned char *data, unsigned char addr);
void clcd_putch(const unsigned char data, unsigned char addr);
void clcd_write(unsigned char bit_values, unsigned char control_bit);

#endif


uart.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : uart.c
 *   Title          : UART Driver
 *   Description    : Module to drive UART peripheral
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "uart.h"

void init_uart(void)
{
	/* Serial initialization */
	RX_PIN = 1;
	TX_PIN = 0;

	/* TXSTA:- Transmitor Status and control Register */
	
	/* Clock selection control bit */	
	CSRC = 0;
	/* 9bit TX enable or disable bit */ 
	TX9 = 0;
	/* UART Tarsmition enable bit */
	TXEN = 1;
	/* Synchronous or Asynchronous mode selection */
	/* Asynchronous */
	SYNC = 0;
	/* Send the Break character bit */
	SENDB = 0;
	/* Low or High baud rate selection bit */
	/* High Baud Rate */
	BRGH = 1;
	/* Trasmiter Shift register status bit */ 
	TRMT = 0;
	/* 9th bit trasmite data */
	TX9D = 0;

	/* RCSTA :- Recepition Status and control Register */
	
	/* TX/RC7 and RX/RC6 act as serial port */ 
	SPEN = 1;
	/* 9bit RX enable or disable bit */
	RX9 = 0;
	/* Single reception enable or disable */
	SREN = 0;
	/* Continous reception enable or disable */ 
	CREN = 1;
	/* Adress detection enable bit */	
	ADDEN = 0;
	/* Frame error bit */
	FERR = 0;
	/* Overrun error bit */ 
	OERR = 0;
	/* 9th bit received bit */
	RX9D = 0;

	/* BAUDCTL:- Baud rate control register */

	/* Auto baud detection overflow bit */
	ABDOVF = 0;
	/* Receive idle flag bit */
	RCIDL = 1;
	/* Synchronous clock polarity selecton bit */ 
	SCKP = 0;
	/* 16bit baud generate bit */ 
	BRG16 = 0;
	/* Wakeup enable bit */
	WUE = 0;
	/* Auto baud detect enable bit */
	ABDEN = 0;

	/* Baud Rate Setting Register */
	/* Set to 10 for 115200, 64 for 19200 and 129 for 9600 */
	SPBRG = 129;

	/* TX interrupt enable bit */
	TXIE = 1;
	/* TX interrupt flag bit */
	TXIF = 0;
	/* RX interrupt enable bit */
	RCIE = 1;
	/* RX interrupt enable bit */
	RCIF = 0;
}

void putch(unsigned char byte) 
{
	/* Output one byte */
	/* Set when register is empty */
	while(!TXIF)
	{
		continue;
	}
	TXREG = byte;
}

int puts(const char *s)
{
	while(*s)		
	{
		putch(*s++);	
	}

	return 0;
}

unsigned char getch(void)
{
	/* Retrieve one byte */
	/* Set when register is not empty */
	while(!RCIF)
	{
		continue;
	}

	return RCREG;
}

unsigned char getche(void)
{
	unsigned char c;

	putch(c = getch());

	return (c);
}


uart.h

#ifndef SCI_H													 	   
#define SCI_H

#define RX_PIN					TRISC7
#define TX_PIN					TRISC6

void init_uart(void);
void putch(unsigned char byte);
int puts(const char *s);
unsigned char getch(void);
unsigned char getch_with_timeout(unsigned short max_time);
unsigned char getche(void);

#endif

 

Microcontroller programming Example output: 

Brief:

An application to intract with DS1307 RTC using I2C protocol.
 

Source Code:

clcd.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : clcd.c
 *   Title          : CLCD Driver
 *   Description    : Module to make CLCD work in 8 bit mode
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"

void clcd_write(unsigned char byte, unsigned char control_bit)
{
	CLCD_RS = control_bit;
	CLCD_PORT = byte;

	/* Should be atleast 200ns */
	CLCD_EN = HI;
	CLCD_EN = LO;

	PORT_DIR = INPUT;
	CLCD_RW = HI;
	CLCD_RS = INSTRUCTION_COMMAND;

	do
	{
		CLCD_EN = HI;
		CLCD_EN = LO;
	} while (CLCD_BUSY);

	CLCD_RW = LO;
	PORT_DIR = OUTPUT;
}

void init_clcd()
{
	/* Set PortD as output port for CLCD data */
	TRISD = 0x00;
	/* Set PortC as output port for CLCD control */
	TRISC = TRISC & 0xF8;

	CLCD_RW = LO;

	TWO_LINE_5x7_MATRIX_8_BIT;
	CURSOR_HOME;
	DISP_ON_AND_CURSOR_OFF;
	CLEAR_DISP_SCREEN;
}

void clcd_print(const unsigned char *data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	while (*data != '\0')
	{
		clcd_write(*data++, DATA_COMMAND);
	}
}

void clcd_putch(const unsigned char data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	clcd_write(data, DATA_COMMAND);
}


clcd.h

#ifndef CLCD_H													   
#define CLCD_H

#define HI				1
#define LO				0

#define INPUT				0xFF
#define OUTPUT				0x00

#define DATA_COMMAND			1
#define INSTRUCTION_COMMAND		0

#define LINE1(x)			(0x80 + (x))
#define LINE2(x)			(0xC0 + (x))

#define TWO_LINE_5x7_MATRIX_8_BIT	clcd_write(0x38, INSTRUCTION_COMMAND)
#define CLEAR_DISP_SCREEN		clcd_write(0x01, INSTRUCTION_COMMAND)
#define CURSOR_HOME			clcd_write(0x02, INSTRUCTION_COMMAND)
#define DISP_ON_AND_CURSOR_OFF		clcd_write(0x0C, INSTRUCTION_COMMAND)

#define CLCD_PORT			PORTD
#define CLCD_EN				RC2
#define CLCD_RS				RC1
#define CLCD_RW				RC0
#define CLCD_BUSY			RD7
#define PORT_DIR			TRISD7

void init_clcd(void);
void clcd_print(const unsigned char *data, unsigned char addr);
void clcd_putch(const unsigned char data, unsigned char addr);
void clcd_write(unsigned char bit_values, unsigned char control_bit);

#endif


ds1307.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : ds1307.c
 *   Title          : DS1307 RTC Driver
 *   Description    : Module to communicate with DS1307 
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "ds1307.h"
#include "i2c.h"

/* 
 * DS1307 Slave address
 * D0  -  Write Mode
 * D1  -  Read Mode
 */

void init_ds1307(void)
{
	unsigned char dummy;

	/* Setting the CH bit of the RTC to Stop the Clock */
	dummy = read_ds1307(SEC_ADDR);
	write_ds1307(SEC_ADDR, dummy | 0x80); 

	/* Seting 12 Hr Format */
	dummy = read_ds1307(HOUR_ADDR);
	write_ds1307(HOUR_ADDR, dummy | 0x40); 

	/* 
	 * Control Register of DS1307
	 * Bit 7 - OUT
	 * Bit 6 - 0
	 * Bit 5 - OSF
	 * Bit 4 - SQWE
	 * Bit 3 - 0
	 * Bit 2 - 0
	 * Bit 1 - RS1
	 * Bit 0 - RS0
	 * 
	 * Seting RS0 and RS1 as 11 to achive SQW out at 32.768 KHz
	 */ 
	write_ds1307(CNTL_ADDR, 0x93); 

	/* Clearing the CH bit of the RTC to Start the Clock */
	dummy = read_ds1307(SEC_ADDR);
	write_ds1307(SEC_ADDR, dummy & 0x7F); 

}

void write_ds1307(unsigned char address, unsigned char data)
{
	i2c_start();
	i2c_write(SLAVE_WRITE);
	i2c_write(address);
	i2c_write(data);
	i2c_stop();
}

unsigned char read_ds1307(unsigned char address)
{
	unsigned char data;

	i2c_start();
	i2c_write(SLAVE_WRITE);
	i2c_write(address);
	i2c_rep_start();
	i2c_write(SLAVE_READ);
	data = i2c_read();
	i2c_stop();

	return data;
}


ds1307.h

#ifndef Ds1307_H													    
#define Ds1307_H

#define SLAVE_READ		0xD1
#define SLAVE_WRITE		0xD0

#define SEC_ADDR		0x00
#define MIN_ADDR		0x01
#define HOUR_ADDR		0x02
#define DAY_ADDR		0x03
#define DATE_ADDR		0x04
#define MONTH_ADDR		0x05
#define YEAR_ADDR		0x06
#define CNTL_ADDR		0x07

void init_ds1307(void);
void write_ds1307(unsigned char address1,  unsigned char data);
unsigned char read_ds1307(unsigned char address1);

#endif


i2c.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : i2c.c
 *   Title          : I2C Driver
 *   Description    : Module containing the I2C driver function
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"

void init_i2c(void)
{
	/* Set SCL and SDA pins as inputs */
	TRISC3 = 1;
	TRISC4 = 1;
	/* Set I2C master mode */
	SSPCON1 = 0x28;

	SSPADD = 0x30;
	/* Use I2C levels, worked also with '0' */
	CKE = 0;
	/* Disable slew rate control  worked also with '0' */
	SMP = 1;
	/* Clear SSPIF interrupt flag */
	SSPIF = 0;
	/* Clear bus collision flag */
	BCLIF = 0;
}

void i2c_idle(void)
{
	while (!SSPIF);
	SSPIF = 0;
}

void i2c_ack(void)
{
	if (ACKSTAT)
	{
		/* Do debug print here if required */
	}
}

void i2c_start(void)
{
	SEN = 1;
	i2c_idle();
}

void i2c_stop(void)
{
	PEN = 1;
	i2c_idle();
}

void i2c_rep_start(void)
{
	RSEN = 1;
	i2c_idle();
}

void i2c_write(unsigned char data)
{
	SSPBUF = data;
	i2c_idle();
}

void i2c_rx_mode(void)
{
	RCEN = 1;
	i2c_idle();
}

void i2c_no_ack(void)
{
	ACKDT = 1;
	ACKEN = 1;
}

unsigned char i2c_read(void)
{
	i2c_rx_mode();
	i2c_no_ack();

	return SSPBUF;
}


i2c.h

#ifndef I2C_H														   
#define I2C_H

void init_i2c(void);
void i2c_start(void);
void i2c_rep_start(void);
void i2c_stop(void);
void i2c_write(unsigned char data);
unsigned char i2c_read(void);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
  *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : DS1307 RTC
 *   Description    : An application to intract with DS1307 RTC using I2C protocol
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"
#include "ds1307.h"
#include "i2c.h"

unsigned char clock_reg[3];
unsigned char calender_reg[4];
unsigned char time[9];
unsigned char date[11];

void display_date(void)
{
	clcd_print(date, LINE2(3));
}

void display_time(void)
{
	clcd_print(time, LINE2(2));

	if (clock_reg[0] & 0x40)
	{
		if (clock_reg[0] & 0x20)
		{
			clcd_print("PM", LINE2(12));
		}
		else
		{
			clcd_print("AM", LINE2(12));
		}
	}
}

static void get_time(void)
{
	clock_reg[0] = read_ds1307(HOUR_ADDR);
	clock_reg[1] = read_ds1307(MIN_ADDR);
	clock_reg[2] = read_ds1307(SEC_ADDR);

	if (clock_reg[0] & 0x40)
	{
		time[0] = '0' + ((clock_reg[0] >> 4) & 0x01);
		time[1] = '0' + (clock_reg[0] & 0x0F);
	}
	else
	{
		time[0] = '0' + ((clock_reg[0] >> 4) & 0x03);
		time[1] = '0' + (clock_reg[0] & 0x0F);
	}
	time[2] = ':';
	time[3] = '0' + ((clock_reg[1] >> 4) & 0x0F);
	time[4] = '0' + (clock_reg[1] & 0x0F);
	time[5] = ':';
	time[6] = '0' + ((clock_reg[2] >> 4) & 0x0F);
	time[7] = '0' + (clock_reg[2] & 0x0F);
	time[8] = '\0';
}

static void get_date(void)
{
	calender_reg[0] = read_ds1307(YEAR_ADDR);
	calender_reg[1] = read_ds1307(MONTH_ADDR);
	calender_reg[2] = read_ds1307(DATE_ADDR);
	calender_reg[3] = read_ds1307(DAY_ADDR);

	date[0] = '2';
	date[1] = '0';
	date[2] = '0' + ((calender_reg[0] >> 4) & 0x0F);
	date[3] = '0' + (calender_reg[0] & 0x0F);
	date[4] = '-';
	date[5] = '0' + ((calender_reg[1] >> 4) & 0x0F);
	date[6] = '0' + (calender_reg[1] & 0x0F);
	date[7] = '-';
	date[8] = '0' + ((calender_reg[2] >> 4) & 0x0F);
	date[9] = '0' + (calender_reg[2] & 0x0F);
	date[10] = '\0';
}

void init_config(void)
{
	init_clcd();
	init_i2c();
	init_ds1307();

	clcd_print("  DS1307  TEST  ", LINE1(0));
}

void main(void)
{
	init_config();

	while (1)
	{
#if 1
		get_time();
		display_time();
#else
		get_date();
		display_date();
#endif
	}
}


main.h

#ifndef MAIN_H												
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC			= XT
#pragma config WDT			= OFF
#pragma config BOREN			= OFF
#pragma config PBADEN			= OFF
#pragma config LVP			= OFF

#endif

 

Microcontrollers programming Example output:

Brief:

A simple application demonstrating CAN communication using loop back method.
 

Source Code:

can.c

 

/*-------------------------------------------------------------------------------------------------
* Author : Emertxe (https://emertxe.com)
* Date : Wed 24 Mar 2021 16:00:04 IST
* File : can.c
* Title : CAN Driver
* Description : CAN Driver Module to communicate on a network using different modes
*-----------------------------------------------------------------------------------------------*/

#include "can.h"
#include "main.h"
#include "clcd.h"

/* Global Variables */
unsigned char can_payload[13];

typedef enum _CanOpMode
{
e_can_op_mode_bits = 0xE0, /* Use this to access opmode bits */
e_can_op_mode_normal = 0x00,
e_can_op_mode_sleep = 0x20,
e_can_op_mode_loop = 0x40,
e_can_op_mode_listen = 0x60,
e_can_op_mode_config = 0x80
} CanOpMode;

/* Configure the CAN Module */
void init_can(void)
{
/* CAN_TX = RB2, CAN_RX = RB3 */
TRISB2 = 0; /* CAN TX */
TRISB3 = 1; /* CAN RX */

/* Enter CAN module into config mode */
CANSTAT &= 0x1F; /* clear previous mode */
CANSTAT |= 0x80; /* set new mode */

/* Wait untill desired mode is set */
while (CANSTAT != 0x80);

/* Enter CAN module into Mode 0 */
ECANCON = 0x00;

/* Initialize CAN Timing 8MHz */
BRGCON1 = 0xE1; /* 1110 0001, SJW=4, TQ, BRP 4 */
BRGCON2 = 0x1B; /* 0001 1011, SEG2PHTS 1 sampled once PS1=4TQ PropagationT 4TQ */
BRGCON3 = 0x03; /* 0000 0011, PS2, 4TQ */

/*
* Enable Filters
* Filter 0
*/
RXFCON0 = 0x01;

/*
* Initialize Receive Filters
* Filter 0 = 0xFFC
*/
RXF0EIDH = 0x00;
RXF0EIDL = 0x00;
RXF0SIDH = 0x6B;
RXF0SIDL = 0xC0;

/* Enter CAN module into Loop back mode */
CAN_SET_OPERATION_MODE_NO_WAIT(e_can_op_mode_loop);

/* Set Receive Mode for buffers */
RXB0CON = 0x00;
}

/* Check the buffers, if it have message */
unsigned char can_receive(void)
{
if (RXB0FUL) /* CheckRXB0 */
{
can_payload[EIDH] = RXB0EIDH;
can_payload[EIDL] = RXB0EIDL;
can_payload[SIDH] = RXB0SIDH;
can_payload[SIDL] = RXB0SIDL;
can_payload[DLC] = RXB0DLC;
can_payload[D0] = RXB0D0;
can_payload[D1] = RXB0D1;
can_payload[D2] = RXB0D2;
can_payload[D3] = RXB0D3;
can_payload[D4] = RXB0D4;
can_payload[D5] = RXB0D5;
can_payload[D6] = RXB0D6;
can_payload[D7] = RXB0D7;

RXB0FUL = 0;
RXB0IF = 0;

return TRUE;
}
else
{
return FALSE;
}
}

/* Transmit Sample Mesaage */
void can_transmit(void)
{
TXB0EIDH = 0x00; /* Extended Identifier */
TXB0EIDL = 0x00; /* Extended Identifier */

/* 0x35E 0110 1011 110 */
TXB0SIDH = 0x6B; /* Standard Identifier */
TXB0SIDL = 0xC0; /* Standard Identifier */

TXB0DLC = 0x08; /* Data Length Count */
TXB0D0 = 'A'; /* DataByte 0 */
TXB0D1 = 'B'; /* DataByte 1 */
TXB0D2 = 'C'; /* DataByte 2 */
TXB0D3 = 'D'; /* DataByte 3 */
TXB0D4 = 'E'; /* DataByte 4 */
TXB0D5 = 'F'; /* DataByte 5 */
TXB0D6 = 'G'; /* DataByte 6 */
TXB0D7 = 'H'; /* DataByte 7 */

TXB0REQ = 1; /* Set the buffer to transmit */
}

can.h
#ifndef CAN_H													   
#define CAN_H

/* Defines ECAN */
#define   F_ECAN_MODE2_FP		CANCON & 0x0F
#define   F_ECANFIFO_0			RXB0CONbits.RXFUL
#define   F_ECANFIFO_1			RXB1CONbits.RXFUL
#define   F_ECANFIFO_2			B0CONbits.RXFUL
#define   F_ECANFIFO_3			B1CONbits.RXFUL
#define   F_ECANFIFO_4			B2CONbits.RXFUL
#define   F_ECANFIFO_5			B3CONbits.RXFUL
#define   F_ECANFIFO_6			B4CONbits.RXFUL
#define   F_ECANFIFO_7			B5CONbits.RXFUL

#define CAN_SET_OPERATION_MODE_NO_WAIT(mode)		\
{													\
	CANCON &= 0x1F;									\
	CANCON |= mode;									\
}

#define EIDH					0
#define EIDL					1
#define SIDH					2
#define SIDL					3
#define DLC						4
#define D0						5
#define D1						6
#define D2						7
#define D3						8
#define D4						9
#define D5						10
#define D6						11
#define D7						12

/* Global Variable */
extern unsigned char can_payload[13];

/* Function Prototypes  */
void init_can(void);
unsigned char can_receive(void);
void can_transmit(void);

#endif


clcd.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : clcd.c
 *   Title          : CLCD Driver
 *   Description    : Module to make CLCD work in 8 bit mode
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "clcd.h"

void clcd_write(unsigned char byte, unsigned char control_bit)
{
	CLCD_RS = control_bit;
	CLCD_PORT = byte;

	/* Should be atleast 200ns */
	CLCD_EN = HI;
	CLCD_EN = LO;

	PORT_DIR = INPUT;
	CLCD_RW = HI;
	CLCD_RS = INSTRUCTION_COMMAND;

	do
	{
		CLCD_EN = HI;
		CLCD_EN = LO;
	} while (CLCD_BUSY);

	CLCD_RW = LO;
	PORT_DIR = OUTPUT;
}

void init_clcd()
{
	/* Set PortD as output port for CLCD data */
	TRISD = 0x00;
	/* Set PortC as output port for CLCD control */
	TRISC = TRISC & 0xF8;

	CLCD_RW = LO;

	TWO_LINE_5x7_MATRIX_8_BIT;
	CURSOR_HOME;
	DISP_ON_AND_CURSOR_OFF;
	CLEAR_DISP_SCREEN;
}

void clcd_print(const unsigned char *data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	while (*data != '\0')
	{
		clcd_write(*data++, DATA_COMMAND);
	}
}

void clcd_putch(const unsigned char data, unsigned char addr)
{
	clcd_write(addr, INSTRUCTION_COMMAND);
	clcd_write(data, DATA_COMMAND);
}


clcd.h

#ifndef CLCD_H														   
#define CLCD_H

#define HI				1
#define LO				0

#define INPUT				0xFF
#define OUTPUT				0x00

#define DATA_COMMAND			1
#define INSTRUCTION_COMMAND		0

#define LINE1(x)			(0x80 + (x))
#define LINE2(x)			(0xC0 + (x))

#define TWO_LINE_5x7_MATRIX_8_BIT	clcd_write(0x38, INSTRUCTION_COMMAND)
#define CLEAR_DISP_SCREEN		clcd_write(0x01, INSTRUCTION_COMMAND)
#define CURSOR_HOME			clcd_write(0x02, INSTRUCTION_COMMAND)
#define DISP_ON_AND_CURSOR_OFF		clcd_write(0x0C, INSTRUCTION_COMMAND)

#define CLCD_PORT			PORTD
#define CLCD_EN				RC2
#define CLCD_RS				RC1
#define CLCD_RW				RC0
#define CLCD_BUSY			RD7
#define PORT_DIR			TRISD7

void init_clcd(void);
void clcd_print(const unsigned char *data, unsigned char addr);
void clcd_putch(const unsigned char data, unsigned char addr);
void clcd_write(unsigned char bit_values, unsigned char control_bit);

#endif


main.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : main.c
 *   Title          : Controller Area Network
 *   Description    : A simple appication demonstrating CAN communication using loop back
 *   		      method
 *-----------------------------------------------------------------------------------------------*/

#include "main.h"
#include "matrix_keypad.h"
#include "can.h"
#include "clcd.h"

/* delay 1ms function */
void delay(unsigned short factor)
{
	unsigned short i, j;

	for (i = 0; i < factor; i++) { for (j = 500; j--; ); } } void init_config(void) { /* Initialize Matrix Keypad */ init_matrix_keypad(); /* Initialize CLCD module */ init_clcd(); /* Initialize CAN module */ init_can(); /* Set buzzer as output */ TRISE0 = 0; BUZZER = 0; clcd_print("CAN Bus Demo", LINE1(2)); } void can_demo(void) { unsigned char key; unsigned char i = 0; key = read_switches(1); if (key == MK_SW1) { clcd_print("Tx DATA : -->   ", LINE2(0));
		can_transmit();
		delay(1000);
	}

	if (can_receive())
	{
		clcd_print("Rx DATA : <--", LINE2(0));

		i = 0;
		while (i != 8)
		{
			clcd_putch(can_payload[D0 + i], LINE2(14));
			i++;

			/* ON Sound */
			//BUZZER = 1;
			delay(500);
			BUZZER = 0;
		}
	}
}

void main(void)
{    
	init_config();

	while (1)
	{
		can_demo();	
	}
}


main.h

#ifndef MAIN_H														   
#define MAIN_H

#include 

#define _XTAL_FREQ 20000000

#pragma config OSC		= XT
#pragma config WDT		= OFF
#pragma config BOREN		= OFF
#pragma config PBADEN		= OFF
#pragma config LVP		= OFF

/* Defines the data */
#define TRUE			1
#define FALSE			0

#define BUZZER			RE0

#define LED_PORT		PORTB
#define LED7			RB6
#define LED8			RB7

#endif


matrix_keypad.c

/*------------------------------------------------------------------------------------------------- 			    
 *   Author         : Emertxe (https://emertxe.com) 
 *   Date           : Wed 24 Mar 2021 16:00:04 IST
 *   File           : matrix_keypad.c
 *   Title          : Matrix Keypad - Driver
 *   Description    : A module which detects both level and state change of user input using
 *   		      matrix keypad
 *-----------------------------------------------------------------------------------------------*/

#include "matrix_keypad.h"
#include "main.h"

void init_matrix_keypad(void)
{
	/* Config PORTB as digital */
	ADCON1 = 0x0F;

	/* Set Rows (RB7 - RB5) as Outputs and Columns (RB4 - RB1) as Inputs */
	TRISB = 0x1E;

	/* Set PORTB input as pull up for columns */
	RBPU = 0;

	MATRIX_KEYPAD_PORT = MATRIX_KEYPAD_PORT | 0xE0;
}

unsigned char scan_key(void)
{
	ROW1 = LO;
	ROW2 = HI;
	ROW3 = HI;

	if (COL1 == LO)
	{
		return 1;
	}
	else if (COL2 == LO)
	{
		return 4;
	}
	else if (COL3 == LO)
	{
		return 7;
	}
	else if (COL4 == LO)
	{
		return 10;
	}

	ROW1 = HI;
	ROW2 = LO;
	ROW3 = HI;

	if (COL1 == LO)
	{
		return 2;
	}
	else if (COL2 == LO)
	{
		return 5;
	}
	else if (COL3 == LO)
	{
		return 8;
	}
	else if (COL4 == LO)
	{
		return 11;
	}

	ROW1 = HI;
	ROW2 = HI;
	ROW3 = LO;
	/* TODO: Why more than 2 times? */
	ROW3 = LO;

	if (COL1 == LO)
	{
		return 3;
	}
	else if (COL2 == LO)
	{
		return 6;
	}
	else if (COL3 == LO)
	{
		return 9;
	}
	else if (COL4 == LO)
	{
		return 12;
	}

	return 0xFF;
}

unsigned char read_switches(unsigned char detection_type)
{
	static unsigned char once = 1;
	unsigned char key;

	key = scan_key();

	if (detection_type == STATE_CHANGE)
	{
		if ((key != ALL_RELEASED) && once)
		{
			once = 0;

			return key;
		}
		else if (key == ALL_RELEASED)
		{
			once = 1;
		}
	}
	else if (detection_type == LEVEL_CHANGE)
	{
		return key;
	}

	return 0xFF;
}


matrix_keypad.h

#ifndef MATRIX_KEYPAD_H												
#define MATRIX_KEYPAD_H

#define MAX_ROW			4
#define MAX_COL			3

#define STATE_CHANGE		1
#define LEVEL_CHANGE		0

#define MK_SW1			1
#define MK_SW2			2
#define MK_SW3			3
#define MK_SW4			4
#define MK_SW5			5
#define MK_SW6			6
#define MK_SW7			7
#define MK_SW8			8
#define MK_SW9			9
#define MK_SW10			10
#define MK_SW11			11
#define MK_SW12			12

#define ALL_RELEASED		0xFF

#define HI			1
#define LO			0

#define MATRIX_KEYPAD_PORT	PORTB
#define ROW3			RB7
#define ROW2			RB6
#define ROW1			RB5
#define COL4			RB4
#define COL3			RB3
#define COL2			RB2
#define COL1			RB1

void init_matrix_keypad(void);
unsigned char scan_key(void);
unsigned char read_switches(unsigned char detection_type);

#endif

<c/code>

Microcontrollers programming Example output: