0% found this document useful (0 votes)
17 views43 pages

MC Unit - 5 All Ans

The document provides detailed instructions on interfacing a 16x2 LCD display with a PIC18F4520 microcontroller, including pin descriptions, wiring diagrams, and a C program for displaying messages. It also explains the logic for detecting key presses from a 4x3 matrix keypad using both pull-up and pull-down resistors, along with corresponding C programs and flowcharts. Important notes on initialization and timing for the LCD are included, as well as suggestions for improving keypad functionality.

Uploaded by

413 YASH MANE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views43 pages

MC Unit - 5 All Ans

The document provides detailed instructions on interfacing a 16x2 LCD display with a PIC18F4520 microcontroller, including pin descriptions, wiring diagrams, and a C program for displaying messages. It also explains the logic for detecting key presses from a 4x3 matrix keypad using both pull-up and pull-down resistors, along with corresponding C programs and flowcharts. Important notes on initialization and timing for the LCD are included, as well as suggestions for improving keypad functionality.

Uploaded by

413 YASH MANE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

CREDIT - YASH

UNIT – 5 ANS
1) Explain interfacing of LCD display with PIC18F4520 microcontroller with the help of
connection diagram.

✅ Overview of LCD 16x2


The 16×2 LCD display has:

 2 lines, 16 characters per line.


 Each character is a 5×8 pixel matrix.
 Commonly uses HD44780 controller.

There are 16 pins in the LCD (you may use 14 if no backlight control is needed).

✅ LCD Pin Description


Pin No. Name Description
1 VSS GND
2 VDD +5V
3 VEE Contrast (connect to a 10k potentiometer)
4 RS Register Select (0 = Command, 1 = Data)
5 RW Read/Write (0 = Write, 1 = Read; usually grounded)
6 EN Enable (used to latch data)
7–14 D0–D7 Data lines (only D4–D7 used in 4-bit mode)
15 LED+ Backlight +
16 LED− Backlight GND

✅ Connection Diagram (8-bit mode)


We'll use PORTD for LCD data and RC1, RC2, RC3 for control.

🖧 Wiring:

LCD Pin Connects to


VSS GND
VDD +5V
VEE Middle terminal of 10k pot (for contrast)
RS RC1
RW GND (Write-only mode)
EN RC3
D0–D7 RD0 to RD7
LED+ +5V via 330Ω resistor (optional)
LED− GND
CREDIT - YASH

✅ In 4-bit mode, only D4–D7 would connect to RD4–RD7, reducing pin usage.

✅ Block Diagram Summary

+--------------------------+
| PIC18F4520 MCU |
| |
| RC1 → RS |
| RC3 → EN |
| RD0–RD7 → D0–D7 |
| |
+--------------------------+

+-----------------+
| LCD 16x2 |
| RS, EN, D0–D7 |
| VSS/VDD/VEE |
+-----------------+

10k Potentiometer

✅ Important Notes
 Use __delay_ms() between LCD commands to ensure correct timing.
 Always initialize LCD with the right command sequence (usually done via
lcdinit()).
 Always clear and set cursor to home position before printing.
 RW pin can be permanently grounded if only writing to LCD (as in most cases).

📋 Summary
Feature Choice
Mode 8-bit (RD0–RD7) or 4-bit (RD4–RD7)
RS RC1
EN RC3
RW GND (write only)
LCD VEE 10k pot to adjust contrast
Backlight Connect via 330Ω resistor to +5V
CREDIT - YASH

2) Write a C program to display ASCII string message on LCD. Also draw flowchart of
the program.
ANS 
#include <xc.h>
#include <stdio.h>
#include <string.h>
float data;
unsigned char array[16];
#define en PORTCbits.RC3
#define rs PORTCbits.RC1
#define _XTAL_FREQ 4000000
void lcd_string(unsigned char *S);
void lcdinit(void);
void lcdcmd(unsigned char data);
void lcddata(unsigned char data);
///////////////////////////////////////////////////////////////////////////////////
void lcd_string(unsigned char *S)
{
while(*S)
{
lcddata(*S);
S++;
}
}
//////////////////////////////////
////////////////////////////
void lcdcmd(unsigned char data)
{
PORTD=data;
rs=0;
CREDIT - YASH

__delay_ms(1);
en=1;
__delay_ms(1);
en=0;
}
////////////////////////////////////////////////////
void lcddata(unsigned char data)
{
PORTD=data;
rs=1;
__delay_ms(1);
en=1;
__delay_ms(1);
en=0;
}
////////////////////////////////////////////////////
void lcdinit(void)
{
lcdcmd(0x01);
__delay_ms(40);
lcdcmd(0x38);
lcdcmd(0x0C);
lcdcmd(0x06);
lcdcmd(0x80);
}
//////////////////////////////////////////////////////////////////
void main(void)
{
OSCCON=0xEF; //EF 4 MHz
CREDIT - YASH

TRISB=0X00;
TRISC=0x00;
TRISD=0x00;
en=0;
__delay_ms(10);
lcdinit();
lcdcmd(0x81);
lcd_string("RIT WELCOMES");
lcdcmd(0xC1);
lcd_string("YOU");
__delay_ms(500);
data=563.563;
sprintf(array,"%.2f",data);
strcat(array," V");
lcdcmd(0x01);
lcd_string(array);
while(1)
{
}
}
CREDIT - YASH

✅ 📊 Flowchart for Your Code (Step-by-Step)


Here’s the flowchart representation:

+--------------------------+
| Start |
+--------------------------+

+--------------------------+
| Set internal oscillator |
| OSCCON = 0xEF (4 MHz) |
+--------------------------+

+--------------------------+
| Configure TRISB, TRISC, |
| and TRISD as outputs |
+--------------------------+

+--------------------------+
| Initialize LCD (lcdinit) |
| Send LCD commands |
+--------------------------+

+--------------------------+
| Display "RIT WELCOMES" |
| on LCD Line 1 |
+--------------------------+

+--------------------------+
| Display "YOU" on Line 2 |
+--------------------------+

| Delay 500 ms |
+--------------------------+

+------------------------------+
| data = 563.563 |
+------------------------------+

+------------------------------+
| Format data to 2 decimal |
| places using sprintf() |
| → array = "563.56" |
+------------------------------+

+------------------------------+
| Concatenate " V" to array |
| → array = "563.56 V" |
+------------------------------+

+--------------------------+
| Clear LCD |
| Display array on LCD |
+--------------------------+

+--------------------------+
| Infinite loop |
+--------------------------+
CREDIT - YASH

3) Write a C program to interface matrix key pad of 4 rows and 3 columns using
pull up resistors. Explain logic of key press detection and also draw flowchart of
the program.

ANS 

CODE –

#include <xc.h>
#include <string.h>

#define C1 PORTBbits.RB0
#define C2 PORTBbits.RB1
#define C3 PORTBbits.RB2

#define en PORTCbits.RC3
#define rs PORTCbits.RC1
#define rw1 PORTCbits.RC2

#define R1 PORTBbits.RB4
#define R2 PORTBbits.RB5
#define R3 PORTBbits.RB6
#define R4 PORTBbits.RB7

void lcd_string(unsigned char *Spointer);


void lcdinit(void);
void lcdcmd(unsigned char data);
void lcddata(unsigned char data);

#define _XTAL_FREQ 4000000

//////////////////////////////////////////////////////////////////////

void lcd_string(unsigned char *Spointer)


{
while(*Spointer)
{
lcddata(*Spointer);
Spointer++;
}
}
////////////////////////////////////////////////////////////////
void lcdcmd(unsigned char command) //To write LCD Commands
{
PORTD=command;
rs=0;
en=1;
__delay_ms(1);
CREDIT - YASH

en=0;

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcddata(unsigned char data) // To write one byte ASCII data to LCD
{
PORTD=data;
rs=1;
en=1;
__delay_ms(1);
en=0;
}
////////////////////////////////////////////////////
void lcdinit(void) //LCD initialization Function
{
lcdcmd(0x01);
__delay_ms(80);
lcdcmd(0x38);
__delay_ms(10);
lcdcmd(0x0C);
__delay_ms(10);
lcdcmd(0x06);
__delay_ms(10);
lcdcmd(0x80);
}
////////////////////////////////////////////////////////
////////////////////////////////////////////////////
void main(void)
{

OSCCON=0xEF; //EF 4 MHz


ADCON1=0X0F;
TRISD=0X00;
TRISB=0X0F;
TRISC=0X00;
PORTD=0X00;
PORTC=0X00;
rw1=0;

lcdinit();
lcdcmd(0xC0);
lcd_string("RIT WELCOMES YOU");
while(1)
{
//scan row1
R1=0;
R2=1;
R3=1;
R4=1;
CREDIT - YASH

if(C1==0)
{
lcdcmd(0x80);
lcddata('1');

}
if(C2==0)
{
lcdcmd(0x80);
lcddata('2');

}
if(C3==0)
{
lcdcmd(0x80);
lcddata('3');

}
/////////////////////////////////////////////////
//scan row2
R1=1;
R2=0;
R3=1;
R4=1;

if(C1==0)
{
lcdcmd(0x80);
lcddata('4');

}
if(C2==0)
{
lcdcmd(0x80);
lcddata('5');

}
if(C3==0)
{
lcdcmd(0x80);
lcddata('6');

}
/////////////////////////////////////////////////
//scan row3
R1=1;
R2=1;
R3=0;
R4=1;
CREDIT - YASH

if(C1==0)
{
lcdcmd(0x80);
lcddata('7');

}
if(C2==0)
{
lcdcmd(0x80);
lcddata('8');

}
if(C3==0)
{
lcdcmd(0x80);
lcddata('9');

}
/////////////////////////////////////////////////
//scan row4
R1=1;
R2=1;
R3=1;
R4=0;

if(C1==0)
{
lcdcmd(0x80);
lcddata('*');

}
if(C2==0)
{
lcdcmd(0x80);
lcddata('0');
// break;
}
if(C3==0)
{
lcdcmd(0x80);
lcddata('#');

__delay_ms(300);
}

}
CREDIT - YASH

✅ 1. Keypad Connection Summary (4×3 Matrix)


Layout:
C1 C2 C3
+----+----+----+
R1| 1 | 2 | 3 |
R2| 4 | 5 | 6 |
R3| 7 | 8 | 9 |
R4| * | 0 | # |
+----+----+----+

✅ 2. Logic of Key Press Detection


You're using a row-column scanning method:

Step-by-step logic:

1. Set one row LOW (e.g., R1 = 0, rest HIGH).


2. Read columns (C1–C3):
o If any column is LOW → key at that (row, col) is pressed.
3. Take action based on key location (e.g., display '1', '2', '3').
4. Repeat the process for each row.

👉 This is repeated continuously in a loop to check for keypresses.

Example:

If key '2' is pressed:

 You set R1 = 0 (others HIGH).


 If C2 == 0 → Key '2' is detected.

This scanning ensures:

 Only one row is LOW at a time.


 The intersection of LOW row and LOW column reveals the key.

✅ 3. Keypad Pin Configuration in Code


Pin Port Pin Direction
R1–R4 RB4–RB7 Output (set HIGH/LOW to scan)
C1–C3 RB0–RB2 Input (read column status)

✔ TRISB = 0x0F → Lower nibble RB0–RB3 as input (columns), upper as output (rows).
CREDIT - YASH

✔ PORTBbits.RBx used to manually control row scanning and column detection.

✅ 4. Flowchart of the Progra


+------------------------+
| Start |
+------------------------+

+------------------------+
| Initialize LCD, I/O |
| Set Rows = outputs |
| Set Cols = inputs |
+------------------------+

+------------------------+
| Display "RIT WELCOMES"|
| "YOU" |
+------------------------+

| Loop |
+------------------------+
| Set R1 LOW, R2-R4 HIGH |
| → Check C1, C2, C3 |
| If LOW → print '1','2','3' |
+------------------------+

| Set R2 LOW, others HIGH|
| If LOW → print '4','5','6' |
+------------------------+

| Set R3 LOW, others HIGH|
| If LOW → print '7','8','9' |
+------------------------+

| Set R4 LOW, others HIGH|
| If LOW → print '*','0','#' |
+------------------------+

| Delay 300 ms |
+------------------------+

| Repeat scanning |
+------------------------+

✅ 5. Improvements (optional but recommended)


 Add debouncing logic.
 Avoid repeated printing for long key hold.
 Break loop after a valid key (to process only once).
 Buffer the keys entered if needed (e.g., for password input).
CREDIT - YASH

✅ Summary
 Logic: Set one row LOW, read columns to detect key.
 Rows (RB4–RB7): Outputs, actively scanned.
 Cols (RB0–RB2): Inputs, read to detect press.
 LCD: Used to display the pressed key.
 Simple and effective matrix keypad scanning logic.

4) Write a C program to interface matrix key pad of 4 rows and 3 columns using
pull down resistors. Explain logic of key press detection and also draw flowchart
of the program.

ANS 

CODE –

#include <xc.h>
#include <string.h>

#define C1 PORTBbits.RB0
#define C2 PORTBbits.RB1
#define C3 PORTBbits.RB2

#define en PORTCbits.RC3
#define rs PORTCbits.RC1
#define rw1 PORTCbits.RC2

#define R1 PORTBbits.RB4
#define R2 PORTBbits.RB5
#define R3 PORTBbits.RB6
#define R4 PORTBbits.RB7

void lcd_string(unsigned char *Spointer);


void lcdinit(void);
void lcdcmd(unsigned char data);
void lcddata(unsigned char data);

#define _XTAL_FREQ 4000000

//////////////////////////////////////////////////////////////////////

void lcd_string(unsigned char *Spointer)


{
CREDIT - YASH

while(*Spointer)
{
lcddata(*Spointer);
Spointer++;
}
}
////////////////////////////////////////////////////////////////
void lcdcmd(unsigned char command) //To write LCD Commands
{
PORTD=command;
rs=0;
en=1;
__delay_ms(1);
en=0;

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lcddata(unsigned char data) // To write one byte ASCII data to LCD
{
PORTD=data;
rs=1;
en=1;
__delay_ms(1);
en=0;
}
////////////////////////////////////////////////////
void lcdinit(void) //LCD initialization Function
{
lcdcmd(0x01);
__delay_ms(80);
lcdcmd(0x38);
__delay_ms(10);
lcdcmd(0x0C);
__delay_ms(10);
lcdcmd(0x06);
__delay_ms(10);
lcdcmd(0x80);
}
////////////////////////////////////////////////////////
////////////////////////////////////////////////////
void main(void)
{

OSCCON=0xEF; //EF 4 MHz


ADCON1=0X0F;
TRISD=0X00;
TRISB=0X0F;
TRISC=0X00;
PORTD=0X00;
PORTC=0X00;
CREDIT - YASH

rw1=0;

lcdinit();
lcdcmd(0xC0);
lcd_string("RIT WELCOMES YOU");
while(1)
{
//scan row1
R1=1;
R2=0;
R3=0;
R4=0;

if(C1==1)
{
lcdcmd(0x80);
lcddata('1');

}
if(C2==1)
{
lcdcmd(0x80);
lcddata('2');

}
if(C3==1)
{
lcdcmd(0x80);
lcddata('3');

}
/////////////////////////////////////////////////
//scan row2
R1=0;
R2=1;
R3=0;
R4=0;

if(C1==1)
{
lcdcmd(0x80);
lcddata('4');

}
if(C2==1)
{
lcdcmd(0x80);
lcddata('5');
CREDIT - YASH

}
if(C3==1)
{
lcdcmd(0x80);
lcddata('6');

}
/////////////////////////////////////////////////
//scan row3
R1=0;
R2=0;
R3=1;
R4=0;

if(C1==1)
{
lcdcmd(0x80);
lcddata('7');

}
if(C2==1)
{
lcdcmd(0x80);
lcddata('8');

}
if(C3==1)
{
lcdcmd(0x80);
lcddata('9');

}
/////////////////////////////////////////////////
//scan row4
R1=0;
R2=0;
R3=0;
R4=1;

if(C1==1)
{
lcdcmd(0x80);
lcddata('*');

}
if(C2==1)
{
lcdcmd(0x80);
lcddata('0');
// break;
CREDIT - YASH

}
if(C3==1)
{
lcdcmd(0x80);
lcddata('#');

__delay_ms(300);
}

✅ 1. Interfacing 4x3 Matrix Keypad with Pull-down Resistors

🔹 Keypad Layout:
C1 C2 C3
+----+----+----+
R1 | 1 | 2 | 3 |
R2 | 4 | 5 | 6 |
R3 | 7 | 8 | 9 |
R4 | * | 0 | # |
+----+----+----+

✅ 2. Connection Summary:
Line PIC18F4520 Pin Direction Purpose
R1–R4 RB4–RB7 Output Row scan lines
C1–C3 RB0–RB2 Input Column read lines
RW RC2 Output Write control for LCD
RS RC1 Output Register Select for LCD
EN RC3 Output Enable for LCD
LCD D0–D7 PORTD Output LCD Data lines
CREDIT - YASH

✅ 3. Logic of Key Press Detection (with pull-down resistors)


Step-by-step:

1. Rows (R1–R4) are driven HIGH/LOW one at a time.


2. Columns (C1–C3) are read as digital inputs (with pull-down resistors).
o These resistors keep column lines HIGH when no key is pressed.
3. If a key is pressed:
o A connection is formed between a LOW row and column → column pin reads
HIGH (1).
4. The software:
o Sets one row HIGH, others LOW.
o Reads column pins.
o If a column reads HIGH, the position (row, col) tells us which key was
pressed.
5. It then prints the associated key on the LCD.

✅ Why Pull-down Resistors?


They ensure inputs (columns) are HIGH by default, avoiding floating values when no key is
pressed.

✅ 4. Flowchart of the Program


Here's the logic flow:

+------------------------+
| Start |
+------------------------+

+------------------------+
| Initialize oscillator, |
| LCD, TRIS, PORTs |
+------------------------+

+------------------------+
| Display "RIT WELCOMES" |
| "YOU" |
+------------------------+

| Loop |
+------------------------+
| Set R1 HIGH, others LOW|
| If C1 HIGH → '1' |
| If C2 HIGH → '2' |
| If C3 HIGH → '3' |
+------------------------+

| Set R2 HIGH, others LOW|
| If C1 HIGH → '4' |
| If C2 HIGH → '5' |
| If C3 HIGH → '6' |
CREDIT - YASH

+------------------------+

| Set R3 HIGH, others LOW|
| If C1 HIGH → '7' |
| If C2 HIGH → '8' |
| If C3 HIGH → '9' |
+------------------------+

| Set R4 HIGH, others LOW|
| If C1 HIGH → '*' |
| If C2 HIGH → '0' |
| If C3 HIGH → '#' |
+------------------------+

| Delay 300 ms |
+------------------------+

| Repeat Loop |
+------------------------+

✅ 5. Behavior Summary
 The keypad is scanned row-by-row.
 Each key is mapped based on (row, column) combo.
 Pressed key is printed at LCD location 0x80 (first line, start).
 LCD functions (lcdcmd, lcddata, etc.) handle display.
 300 ms delay ensures debouncing & key stability.

✅ Example:
If key ‘5’ is pressed:

 R2 = 1, R1, R3, R4 = 0
 C2 becomes HIGH → software detects (R2,C2) → prints '5'
CREDIT - YASH

5) Write a C program to interface matrix key pad of 3 rows and 3 columns using
pull up resistors. Explain logic of key press detection and also draw flowchart of
the program.

ANS 

✅ 1. C Program to Interface 3×3 Matrix Keypad (Pull-up


Resistors)
📘 Assumptions:

 Rows (R1–R3) = Outputs (RB4–RB6)


 Cols (C1–C3) = Inputs (RB0–RB2) with pull-up resistors
 LCD on PORTD
 RC1 = RS, RC2 = RW (always 0), RC3 = EN

#include <xc.h>
#include <string.h>

#define _XTAL_FREQ 4000000

#define C1 PORTBbits.RB0
#define C2 PORTBbits.RB1
#define C3 PORTBbits.RB2

#define R1 LATBbits.LATB4
#define R2 LATBbits.LATB5
#define R3 LATBbits.LATB6

#define rs PORTCbits.RC1
#define rw PORTCbits.RC2
#define en PORTCbits.RC3

void lcd_string(const char *Spointer);


void lcdinit(void);
void lcdcmd(unsigned char data);
void lcddata(unsigned char data);

// LCD string function


void lcd_string(const char *Spointer) {
while(*Spointer)
lcddata(*Spointer++);
}

// LCD command
void lcdcmd(unsigned char cmd) {
PORTD = cmd;
rs = 0;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}

// LCD data
CREDIT - YASH

void lcddata(unsigned char data) {


PORTD = data;
rs = 1;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}

// LCD initialize
void lcdinit(void) {
lcdcmd(0x01);
__delay_ms(10);
lcdcmd(0x38);
lcdcmd(0x0C);
lcdcmd(0x06);
lcdcmd(0x80);
}

void main(void) {
OSCCON = 0xEF; // 4 MHz internal oscillator
ADCON1 = 0x0F; // Digital I/O

TRISD = 0x00; // LCD data


TRISC = 0x00; // LCD control
TRISB = 0b00000111; // RB0–RB2 input (columns), RB4–RB6 output (rows)
PORTD = 0x00;
PORTC = 0x00;
LATB = 0x70; // Initial all rows HIGH

rw = 0; // Always write

lcdinit();
lcdcmd(0x80);
lcd_string("Keypad Ready");

while(1) {
// R1 LOW
R1 = 0; R2 = 1; R3 = 1;
if(C1 == 0) lcddata('1');
else if(C2 == 0) lcddata('2');
else if(C3 == 0) lcddata('3');

// R2 LOW
R1 = 1; R2 = 0; R3 = 1;
if(C1 == 0) lcddata('4');
else if(C2 == 0) lcddata('5');
else if(C3 == 0) lcddata('6');

// R3 LOW
R1 = 1; R2 = 1; R3 = 0;
if(C1 == 0) lcddata('7');
else if(C2 == 0) lcddata('8');
else if(C3 == 0) lcddata('9');

__delay_ms(300); // Debounce
}
}
CREDIT - YASH

✅ 2. Logic of Key Press Detection (Using Pull-Up Resistors)

🔹 Connection:

 Columns (RB0–RB2) are connected with pull-up resistors (internal or external).


 When no key is pressed, columns read HIGH (1).
 When a key is pressed, and its corresponding row is set LOW → the column
becomes LOW (0).

🔹 Scanning Process:

1. Set one row LOW, others HIGH.


2. Read all columns.
3. If any column reads 0 → key at that row and column is pressed.
4. Print corresponding character on LCD.

Example:

 Set R2 = 0, others HIGH.


 Pressing '5' connects C2 to LOW row R2.
 So C2 == 0 → '5' is detected.
CREDIT - YASH

✅ 3. Flowchart of the Program


+-----------------------------+
| Start |
+-----------------------------+

+-----------------------------+
| Set internal oscillator |
| Initialize I/O, LCD |
+-----------------------------+

+-----------------------------+
| Display "Keypad Ready" |
+-----------------------------+

| Loop |
+-----------------------------+
| R1=0, R2=R3=1 |
| If C1==0 → '1' |
| If C2==0 → '2' |
| If C3==0 → '3' |
+-----------------------------+
| R2=0, R1=R3=1 |
| If C1==0 → '4' |
| If C2==0 → '5' |
| If C3==0 → '6' |
+-----------------------------+
| R3=0, R1=R2=1 |
| If C1==0 → '7' |
| If C2==0 → '8' |
| If C3==0 → '9' |
+-----------------------------+

| Debounce delay (300 ms) |
+-----------------------------+

| Repeat Loop |
+-----------------------------+

✅ Summary
Component Description
Keypad 3×3 matrix
Rows (outputs) RB4–RB6
Columns (inputs with pull-ups) RB0–RB2
Logic Drive rows LOW one-by-one, check column LOWs
LCD PORTD for data, RC1/RC2/RC3 for control
CREDIT - YASH

6) Write a C program to interface matrix key pad of 3rows and 2 columns using
pull up resistors. Explain logic of key press detection and also draw flowchart of
the program.

ANS 

✅ 1. Matrix Keypad Layout (3 Rows × 2 Columns)


Layout:
C1 C2
+----+----+
R1 | 1 | 2 |
R2 | 3 | 4 |
R3 | 5 | 6 |
+----+----+

✅ 2. Hardware Interface (Using Pull-up Resistors)


 Rows (R1–R3) → Outputs → RB4, RB5, RB6
 Columns (C1–C2) → Inputs with pull-up → RB0, RB1
(use either external pull-up resistors or internal if available)

Logic HIGH by default due to pull-up.


When a key is pressed and the row is LOW → the corresponding column becomes LOW.

✅ 3. C Program for PIC18F4520 (MPLAB + XC8)


#include <xc.h>
#include <string.h>

#define _XTAL_FREQ 4000000

// Define row and column pins


#define R1 LATBbits.LATB4
#define R2 LATBbits.LATB5
#define R3 LATBbits.LATB6

#define C1 PORTBbits.RB0
#define C2 PORTBbits.RB1

// LCD control
#define rs PORTCbits.RC1
#define rw PORTCbits.RC2
#define en PORTCbits.RC3

// Function prototypes
void lcdinit(void);
void lcdcmd(unsigned char cmd);
CREDIT - YASH

void lcddata(unsigned char data);


void lcd_string(const char *str);

// LCD functions
void lcdcmd(unsigned char cmd) {
PORTD = cmd;
rs = 0;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}

void lcddata(unsigned char data) {


PORTD = data;
rs = 1;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}

void lcd_string(const char *str) {


while(*str) {
lcddata(*str++);
}
}

void lcdinit(void) {
lcdcmd(0x01);
__delay_ms(10);
lcdcmd(0x38);
lcdcmd(0x0C);
lcdcmd(0x06);
lcdcmd(0x80);
}

void main(void) {
OSCCON = 0xEF; // 4MHz internal oscillator
ADCON1 = 0x0F; // All pins digital

TRISD = 0x00; // LCD data lines


TRISC = 0x00; // LCD control lines
TRISB = 0b00000011; // RB0, RB1 = input (columns); RB4–RB6 = output
(rows)
LATB = 0x70; // Make all rows HIGH initially
PORTD = 0;
PORTC = 0;

lcdinit();
lcdcmd(0x80);
lcd_string("Keypad Ready");

while(1) {
// Scan Row 1
R1 = 0; R2 = 1; R3 = 1;
if(C1 == 0) lcddata('1');
else if(C2 == 0) lcddata('2');

// Scan Row 2
R1 = 1; R2 = 0; R3 = 1;
CREDIT - YASH

if(C1 == 0) lcddata('3');
else if(C2 == 0) lcddata('4');

// Scan Row 3
R1 = 1; R2 = 1; R3 = 0;
if(C1 == 0) lcddata('5');
else if(C2 == 0) lcddata('6');

__delay_ms(300); // debounce delay


}
}

✅ 4. Key Press Detection Logic (with Pull-Up Resistors)


 Pull-up ensures input pins (columns) are HIGH when no key is pressed.
 Each time, one row is set LOW.
 Then check column pins:
o If a key is pressed at that row, the corresponding column will read LOW.
 The unique (row, column) pair maps to a specific key value.

Example:

 Set R2 = 0, R1, R3 = 1
 Pressing key '4' → connects R2 to C2
 So C2 == 0 → Print '4'
CREDIT - YASH

✅ 5. Flowchart of the Program


+---------------------------+
| Start |
+---------------------------+

+---------------------------+
| Initialize LCD, ports |
| TRISD, TRISB, TRISC setup |
+---------------------------+

+---------------------------+
| Display "Keypad Ready" |
+---------------------------+

| Loop |
+---------------------------+
| R1 = 0, R2 = R3 = 1 |
| C1 == 0 → Print '1' |
| C2 == 0 → Print '2' |
+---------------------------+
| R2 = 0, R1 = R3 = 1 |
| C1 == 0 → Print '3' |
| C2 == 0 → Print '4' |
+---------------------------+
| R3 = 0, R1 = R2 = 1 |
| C1 == 0 → Print '5' |
| C2 == 0 → Print '6' |
+---------------------------+

| Debounce delay (300 ms) |
+---------------------------+

| Repeat scanning loop |
+---------------------------+

✅ Summary
Feature Value
Keypad 3×2 matrix
Rows RB4–RB6 (outputs)
Columns RB0–RB1 (inputs with pull-up)
LCD PORTD (data), RC1/RC2/RC3 (control)
Debounce 300 ms
Scan logic One row LOW, check inputs
CREDIT - YASH

7) Draw circuit diagram to interface unipolar stepper motor with PIC


microcontroller. Write C program to rotate stepper motor in clock wise direction
by --X--- degree and in anticlockwise direction by ---Y--- degree. Assume full
step sequencing.

ANS 

To modify your code to rotate a stepper motor:

 ✅ In clockwise (CW) direction by X degrees


 ✅ In anticlockwise (CCW) direction by Y degrees
 ✅ Assuming full-step sequence

✅ Assumptions:
 Full-step angle = 1.8° (typical for many stepper motors)
 So, Steps per revolution = 360 / 1.8 = 200 steps

👉 Steps needed:

 CW: steps_cw = X / 1.8


 CCW: steps_ccw = Y / 1.8

✅ Code
#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define IN1 PORTBbits.RB0


#define IN2 PORTBbits.RB1
#define IN3 PORTBbits.RB2
#define IN4 PORTBbits.RB3

#define _XTAL_FREQ 4000000

// Function prototypes
void rotate_CW(unsigned int steps);
void rotate_CCW(unsigned int steps);

void main(void)
{
OSCCON = 0xEF; // Internal 4 MHz
ADCON1 = 0x0F; // All digital
TRISB = 0x00;
PORTB = 0x00;
CREDIT - YASH

unsigned int steps_cw = 100; // X degrees = 100 * 1.8 = 180°


unsigned int steps_ccw = 50; // Y degrees = 50 * 1.8 = 90°

rotate_CW(steps_cw); // Rotate CW by X degrees


__delay_ms(1000); // Wait
rotate_CCW(steps_ccw); // Rotate CCW by Y degrees

while(1); // Infinite loop


}

// Full-step clockwise sequence


void rotate_CW(unsigned int steps) {
for(unsigned int i = 0; i < steps; i++) {
IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 1; __delay_ms(10);
IN1 = 1; IN2 = 1; IN3 = 0; IN4 = 0; __delay_ms(10);
IN1 = 0; IN2 = 1; IN3 = 1; IN4 = 0; __delay_ms(10);
IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 1; __delay_ms(10);
}
}

// Full-step counterclockwise sequence


void rotate_CCW(unsigned int steps) {
for(unsigned int i = 0; i < steps; i++) {
IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 1; __delay_ms(10);
IN1 = 0; IN2 = 1; IN3 = 1; IN4 = 0; __delay_ms(10);
IN1 = 1; IN2 = 1; IN3 = 0; IN4 = 0; __delay_ms(10);
IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 1; __delay_ms(10);
}
}

✅ Explanation:
 rotate_CW() and rotate_CCW() use 4-step full-step sequences.
 Each step moves motor by 1.8°.
 Delay (__delay_ms(10)) controls speed (~50 RPM, adjust as needed).
 You can change steps_cw and steps_ccw based on your required angle:

Steps = Angle / 1.8 deg

📈 Example:
If you want:

 CW rotation = 180° → steps = 180 / 1.8 = 100


 CCW rotation = 90° → steps = 90 / 1.8 = 50
CREDIT - YASH

DIAGRAM 
CREDIT - YASH

8) Write C program to rotate stepper motor in clock wise direction by --X--- degree
and in anticlockwise direction by ---Y--- degree. Assume half step sequencing.
ANS 

✅ Updated Code: Clockwise + Anticlockwise Rotation (Half-


Step)
#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define IN1 PORTBbits.RB0


#define IN2 PORTBbits.RB1
#define IN3 PORTBbits.RB2
#define IN4 PORTBbits.RB3

#define _XTAL_FREQ 4000000

void main(void)
{
OSCCON = 0xEF; // 4 MHz internal oscillator
ADCON1 = 0x0F; // All pins digital
TRISB = 0x00; // PORTB as output
PORTB = 0x00; // Clear PORTB

unsigned char j;

while(1)
{
// 🚩 Clockwise Rotation
for(j = 0; j < 330; j++)
{
IN1=1; IN2=0; IN3=0; IN4=0;
__delay_ms(500);

IN1=1; IN2=1; IN3=0; IN4=0;


__delay_ms(500);

IN1=0; IN2=1; IN3=0; IN4=0;


__delay_ms(500);

IN1=0; IN2=1; IN3=1; IN4=0;


__delay_ms(500);

IN1=0; IN2=0; IN3=1; IN4=0;


__delay_ms(500);

IN1=0; IN2=0; IN3=1; IN4=1;


__delay_ms(500);

IN1=0; IN2=0; IN3=0; IN4=1;


__delay_ms(500);

IN1=1; IN2=0; IN3=0; IN4=1;


__delay_ms(500);
}
CREDIT - YASH

__delay_ms(1000); // Wait between rotations

// 🔁 Anticlockwise Rotation
for(j = 0; j < 330; j++)
{
IN1=1; IN2=0; IN3=0; IN4=1;
__delay_ms(500);

IN1=0; IN2=0; IN3=0; IN4=1;


__delay_ms(500);

IN1=0; IN2=0; IN3=1; IN4=1;


__delay_ms(500);

IN1=0; IN2=0; IN3=1; IN4=0;


__delay_ms(500);

IN1=0; IN2=1; IN3=1; IN4=0;


__delay_ms(500);

IN1=0; IN2=1; IN3=0; IN4=0;


__delay_ms(500);

IN1=1; IN2=1; IN3=0; IN4=0;


__delay_ms(500);

IN1=1; IN2=0; IN3=0; IN4=0;


__delay_ms(500);
}

__delay_ms(1000); // Wait between cycles


}
}

✅ Summary:
 First loop: Clockwise (CW) using half-step
 Second loop: Anticlockwise (CCW) using half-step
 Delay: You can reduce __delay_ms(500) to increase speed (e.g., __delay_ms(5) for
real rotation speed)
CREDIT - YASH

9) Draw circuit diagram to interface bulb using relay and relay driver circuit.
Write C program to control relay by switch. Use RB0 pin for interfacing switch
and use RC0 pin for relay interfacing.
ANS 

✅ Requirements:
 Switch input on RB0
 Relay control output on RC0
 Relay turns ON when switch is pressed, OFF when released

✅ C Program (XC8, MPLAB X)


#include <xc.h>

#define _XTAL_FREQ 4000000

// CONFIGURATION BITS (set these in your project if needed)


#pragma config OSC = INTIO67
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config BOREN = OFF
#pragma config MCLRE = ON
#pragma config DEBUG = OFF

#define SWITCH PORTBbits.RB0


#define RELAY LATCbits.LATC0

void main(void)
{
// Oscillator setup
OSCCON = 0x6F; // Internal oscillator 4 MHz

// I/O direction setup


TRISBbits.TRISB0 = 1; // RB0 as input (switch)
TRISCbits.TRISC0 = 0; // RC0 as output (relay)

// Initial values
LATCbits.LATC0 = 0; // Relay OFF
ADCON1 = 0x0F; // Set PORTB as digital

while(1)
{
if(SWITCH == 1) // Switch is pressed (assuming active-high)
{
RELAY = 1; // Turn ON relay
}
else
{
RELAY = 0; // Turn OFF relay
}
}
CREDIT - YASH

✅ Hardware Setup:
Pin Function
RB0 Connected to switch (with pull-down resistor if active-high)
RC0 Connected to relay driver input (e.g., base of BC547 or ULN2003 IN)
Relay Connected to +12V and load, through driver transistor/ULN2003

✅ Notes:
 If your switch is active-low (connects to GND when pressed), change:

if(SWITCH == 0)

 Always use transistor driver or ULN2003 to safely drive relay coil.


 Use diode (1N4007) across relay coil for flyback protection.

DIAGRAM 
CREDIT - YASH

10) With the help of block diagram explain working of I2C module in PIC
microcontroller.
ANS 

The I²C (Inter-Integrated Circuit) module in the PIC18F4520 microcontroller is implemented


via the MSSP (Master Synchronous Serial Port) module and supports both Host (Master) and
Client (Slave) modes. Below is a breakdown of the working and structure based on the
datasheet.

🔷 Block Diagram: I²C Mode (from datasheet)

The I²C MSSP block diagram includes the following core components:

 SSPBUF (Serial Buffer Register): Stores transmitted or received data.


 SSPSR (Shift Register): Used for serial-to-parallel and parallel-to-serial conversion.
 SSPADD (Address Register): Used for:
o Holding address in Client mode.
o Baud rate generation in Host mode.
 SSPSTAT (Status Register): Reflects the I²C bus status (Start, Stop, Data/Address).
 SSPCON1 & SSPCON2 (Control Registers): Control start/stop condition, enabling
MSSP, and ACK/NACK handling.
 SDA and SCL Pins: Serial data and clock lines (RC4 and RC3 respectively) with
 open-drain configuration.

🧩 Block Diagram (Simplified):

SDA ↔ SSPSR ↔ SSPBUF


↓ ↑
Start/Stop, ACK Detect
↓ ↑
SSPSTAT SSPCON1/2

SSPADD (Address / Baud Rate)

Baud Rate Generator

SCL

(Refer to Figure 17-7 in datasheet)


CREDIT - YASH

🔷 Working of I²C in PIC18F4520

✅ 1. Initialization

 Configure RC3 (SCL) and RC4 (SDA) as inputs (TRISC<3:4>=1).


 Set SSPEN=1 to enable MSSP in I²C mode.
 Set appropriate mode in SSPCON1<3:0> (e.g., I²C Host mode).

✅ 2. Start Condition

 Triggered by setting SEN=1 (SSPCON2<0>).


 Sets the Start bit (S) in SSPSTAT.

✅ 3. Address Transmission

 Load address into SSPBUF.


 Automatically shifted out via SSPSR.
 Client responds with ACK/NACK (monitored via ACKSTAT).

✅ 4. Data Transmission/Reception

 Data is written to SSPBUF and shifted via SSPSR.


 On reception, hardware stores data in SSPBUF and sets interrupt flag SSPIF.

✅ 5. Stop Condition

 Triggered by setting PEN=1 (SSPCON2<2>).


 Sets Stop bit (P) in SSPSTAT.

🔷 Key Registers

 SSPCON1: Enables MSSP, sets I²C mode.


 SSPCON2: Controls Start/Stop, ACK/NACK, Receive mode.
 SSPSTAT: Indicates status (Start/Stop bit detect, Data/Address).
 SSPBUF: Data buffer for Tx/Rx.
 SSPSR: Internal shift register (not directly accessible).
 SSPADD: Holds baud rate or address based on mode.

🔷 Timing Requirements

Refer to Table 26-20 and 26-21 in the datasheet for I²C timing specs (Start/Stop hold/setup
time, clock high/low durations).
CREDIT - YASH

11) With the help of timing diagram explain SPI protocol.

ANS 

SPI Protocol with Timing Diagram – Explanation Using Datasheets

Overview of SPI

Serial Peripheral Interface (SPI) is a synchronous, full-duplex communication protocol


typically used for short-distance communication between a microcontroller (like
PIC18F4520) and peripheral devices (like EEPROM, sensors, displays, etc.). It uses four
main lines:

1. MOSI (Master Out Slave In) – Data sent from master to slave.
2. MISO (Master In Slave Out) – Data sent from slave to master.
3. SCK (Serial Clock) – Clock signal generated by the master.
4. SS/CS (Slave Select/Chip Select) – Used by master to select the slave.

Working and Signals (Based on 25LC256 Datasheet)

A typical SPI transfer includes:

 Clock Setup: The master sets the clock frequency and polarity (CPOL) and phase
(CPHA).
 Transmission Start: CS (Chip Select) is pulled low to activate the slave.
 Data Transfer: Data is shifted out on MOSI and sampled on MISO, synchronized
with the clock.
 End of Transfer: CS is pulled high to complete the transmission.

Timing Diagrams (from 25LC256 EEPROM Datasheet)

1. Serial Input Timing (Figure 1-2)

CS ─────┐ ┌──────
└──────────────────────────────────────┘

SCK ___ ___ ___ ___ ___ ___


| | | | | | | | | | |
_______| |___| |___| |___| |___| |___|

SI -->[Instr]--->[Addr MSB]--->...-->[Data Byte]

SO High Impedance during Input

 SI (Serial Input) is sampled on the rising edge of SCK.


 Instruction is loaded first (e.g., 00000011 for read), followed by address and data.
CREDIT - YASH

2. Serial Output Timing (Figure 1-3)

CS ─────┐ ┌──────
└──────────────────────────────────────┘

SCK ___ ___ ___ ___ ___ ___


| | | | | | | | | | |
_______| |___| |___| |___| |___| |___|

SO [MSB out]-->...-->[LSB out]

 SO (Serial Output) changes on the falling edge of SCK and is valid on the next
rising edge.
 CS must stay low throughout the transfer.

SPI in PIC18F4520

In the PIC18F4520, SPI is implemented via the MSSP (Master Synchronous Serial Port)
module:

 Registers involved: SSPSTAT, SSPCON1, SSPBUF, etc.


 Operates in SPI Master/Slave modes.
 Can support SPI modes 0–3 (based on clock polarity and phase).

Summary

Signal Direction Description


CS Input Activates/deactivates slave
SCK Input Synchronizes data transfer
MOSI Input Master sends data to slave
MISO Output Slave sends data to master

Use Case Example

Using the PIC18F4520, the microcontroller would:

1. Pull CS low.
2. Send a read instruction and address via MOSI.
3. Read data from MISO.
4. Pull CS high after transfer.
CREDIT - YASH

12) With the help of block diagram and associated SFRs explain working of PWM
module in PIC microcontroller. How is speed of DC motor controlled using
PWM signal?

ANS 

PWM Module in PIC18F4520 – Working and Motor Speed Control

(With reference to the PIC18F4520 datasheet)

🔧 1. Block Diagram of PWM Module

The PWM (Pulse Width Modulation) signal in the PIC18F4520 is generated by the CCP
(Capture/Compare/PWM) module, enhanced in 40/44-pin versions as ECCP. Here's a
simplified block diagram explanation from the datasheet:

+-------------------+
| CCPR1L: |
| CCP1CON<5:4> | <-- 10-bit Duty Cycle Register
+-------------------+
|
Comparator
|
+--+--+
TMR2 -----> | CMP | -----> CCP1 Output
+--+--+
|
PWM Control Logic

 Timer2 provides the time base.


 CCPR1L:CCP1CON<5:4> holds the 10-bit duty cycle value.
 When TMR2 matches the duty cycle value, the output pin is cleared.

The PWM signal has two primary parameters:

 Period: Set by PR2 register.


 Duty Cycle: Set by CCPRxL and CCPxCON<5:4>.

📘 Special Function Registers (SFRs) in PWM

Register Description
CCP1CON Mode selection and lower 2 bits of duty cycle
CCPR1L Upper 8 bits of 10-bit duty cycle
PR2 Sets PWM period
T2CON Timer2 control (Prescaler, On/Off)
TRISCbits.TRISC2 Must be cleared to use RC2 as PWM output
CREDIT - YASH

🔄 How PWM Controls DC Motor Speed

A PWM signal switches the motor's power on and off rapidly:

 Higher Duty Cycle (e.g., 80%) → motor receives power for longer → higher speed.
 Lower Duty Cycle (e.g., 30%) → less power → lower speed.

Connection Example

 PWM output pin (e.g., RC2/CCP1) connected to ULN2003 driver input.


 ULN2003 output connected to DC motor.
 The microcontroller changes duty cycle to vary speed.

🧠 Summary of Steps for PWM Motor Speed Control

1. Configure CCP module in PWM mode via CCP1CON.


2. Set the PWM period using PR2.
3. Load the 10-bit duty cycle into CCPR1L and CCP1CON<5:4>.
4. Set Timer2 prescaler and start Timer2.
5. Clear TRISC2 to make RC2 output the PWM signal.
CREDIT - YASH

13) Write a C program to generate PWM signal of 1500 Hz of 60% duty cycle on
RC2 pin of PIC microcontroller using PWM module 1. Calculate numbers to be
written to PR2 and CCPR1L and CCP1CON register. (Note: Frequency and
duty cycle will be changed randomly).

ANS 

✅ Objective
Write a C program using PWM module 1 (CCP1) of PIC18F4520 to:

 Generate 1500 Hz PWM signal


 With 60% duty cycle
 On RC2 (CCP1) pin
 Use PWM mode of CCP1, Timer2 as time base

✅ Step 1: PWM Register Calculations

📌 Given:

 Fosc = 4 MHz
 PWM frequency = 1500 Hz
 Duty cycle = 60%
 PWM resolution = 10-bit
 Timer2 prescaler = 1:16 (can be changed if needed)

✅ PWM Period Formula:

✅ So :
PR2 = 166
CREDIT - YASH

➡️ Now split 401 (10-bit) into:

 CCPR1L = upper 8 bits = 401 >> 2 = 100


 CCP1CON<5:4> = lower 2 bits = 401 & 0x03 = 1

✅ Step 2: Final Values


Register Value
PR2 166
CCPR1L 100
CCP1CON<5:4> 01

✅ Step 3: Final C Program (MPLAB X + XC8)


#include <xc.h>

#define _XTAL_FREQ 4000000

// CONFIG
#pragma config OSC = INTIO67, WDT = OFF, LVP = OFF, PBADEN = OFF, MCLRE =
ON

void main(void)
{
// Set RC2 (CCP1) as output
TRISCbits.TRISC2 = 0;

// Set CCP1 to PWM mode (CCP1CON<3:0> = 1100)


CCP1CON = 0b00001100;

// Set Duty Cycle = 60% (value = 401)


CCPR1L = 100; // Upper 8 bits (401 >> 2)
CCP1CONbits.DC1B1 = 0; // Bit 1 of lower 2 bits (401 =
0b011001001)
CCP1CONbits.DC1B0 = 1; // Bit 0 of lower 2 bits

// Set PWM Period for 1500 Hz → PR2 = 166


PR2 = 166;

// Timer2 setup: Prescaler = 1:16 (T2CON<1:0> = 0b11)


T2CON = 0b00000111; // TMR2 ON + Prescaler 1:16
CREDIT - YASH

while(1); // Do nothing, PWM runs in hardware


}

✅ Notes:
 PWM runs fully in hardware once configured.
 You can change PR2 and duty cycle calculation dynamically to change frequency/duty
cycle on the fly.
 RC2 is the PWM output pin → connect it to a ULN2003 driver or transistor + motor.

You might also like