MC Unit - 5 All Ans
MC Unit - 5 All Ans
UNIT – 5 ANS
1) Explain interfacing of LCD display with PIC18F4520 microcontroller with the help of
connection diagram.
There are 16 pins in the LCD (you may use 14 if no backlight control is needed).
🖧 Wiring:
✅ In 4-bit mode, only D4–D7 would connect to RD4–RD7, reducing pin usage.
+--------------------------+
| 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
+--------------------------+
| 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
//////////////////////////////////////////////////////////////////////
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)
{
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
Step-by-step logic:
Example:
✔ TRISB = 0x0F → Lower nibble RB0–RB3 as input (columns), upper as output (rows).
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
//////////////////////////////////////////////////////////////////////
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)
{
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);
}
🔹 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
+------------------------+
| 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
#include <xc.h>
#include <string.h>
#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
// LCD command
void lcdcmd(unsigned char cmd) {
PORTD = cmd;
rs = 0;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}
// LCD data
CREDIT - YASH
// 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
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
🔹 Connection:
🔹 Scanning Process:
Example:
✅ 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
#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
// LCD functions
void lcdcmd(unsigned char cmd) {
PORTD = cmd;
rs = 0;
rw = 0;
en = 1;
__delay_ms(1);
en = 0;
}
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
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');
Example:
Set R2 = 0, R1, R3 = 1
Pressing key '4' → connects R2 to C2
So C2 == 0 → Print '4'
CREDIT - YASH
✅ 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
ANS
✅ Assumptions:
Full-step angle = 1.8° (typical for many stepper motors)
So, Steps per revolution = 360 / 1.8 = 200 steps
👉 Steps needed:
✅ Code
#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 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
✅ 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:
📈 Example:
If you want:
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
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);
// 🔁 Anticlockwise Rotation
for(j = 0; j < 330; j++)
{
IN1=1; IN2=0; IN3=0; IN4=1;
__delay_ms(500);
✅ 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
void main(void)
{
// Oscillator setup
OSCCON = 0x6F; // Internal oscillator 4 MHz
// 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)
DIAGRAM
CREDIT - YASH
10) With the help of block diagram explain working of I2C module in PIC
microcontroller.
ANS
The I²C MSSP block diagram includes the following core components:
✅ 1. Initialization
✅ 2. Start Condition
✅ 3. Address Transmission
✅ 4. Data Transmission/Reception
✅ 5. Stop Condition
🔷 Key Registers
🔷 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
ANS
Overview of SPI
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.
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.
CS ─────┐ ┌──────
└──────────────────────────────────────┘
CS ─────┐ ┌──────
└──────────────────────────────────────┘
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:
Summary
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
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
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
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
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:
📌 Given:
Fosc = 4 MHz
PWM frequency = 1500 Hz
Duty cycle = 60%
PWM resolution = 10-bit
Timer2 prescaler = 1:16 (can be changed if needed)
✅ So :
PR2 = 166
CREDIT - YASH
// CONFIG
#pragma config OSC = INTIO67, WDT = OFF, LVP = OFF, PBADEN = OFF, MCLRE =
ON
void main(void)
{
// Set RC2 (CCP1) as output
TRISCbits.TRISC2 = 0;
✅ 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.