Microcontrollers 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:
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:
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--; );
}
}
#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:
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:
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:
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:
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:
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:
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:
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:
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:
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: