You are on page 1of 29

EXERCISES TO GET PREPARED FOR THE FINAL EXAM

1) Which Special Function Registers (SFR's) of Pic16F887 are configured to accomplish the
following functions? Write down typical instructions to accomplish each function:

• To define whether the pins of the I/O ports will be used as an input or output
TRISB = 0x05; //0b00000101 B0 and B2 are inputs, other pins are outputs
• To define whether the pins of the I/O ports will be used as Analog or Digital inputs
ANSEL = 0b10100011; //AN0, AN1, AN5 & AN7 are analog, others are digital
ANSELH is the high byte and it can be configured similarly
• To assign values to the pins of the I/O ports.
PORTC = 0x32; // 0b00110010

2) Which Port of PIC16F887 has built in pull-up resistors and which SFR’s are used to
configure whether the pull up resistors of each pin will be enabled or disabled. Write down
instructions to enable pull up resistors on RB0, RB2 and RB4, while disabling the pull up
resistors on the other pins of.

PORTB has built in pull-up resistors. OPTION_REG and WPUB SFR’s are used to
enable and disable the pull-up resistors.

TRISB2_bit = 1; //Set B2 as input


OPTION_REG.F7 = 0; //Enable Pull-up Resistor property of PORTB
WPUB = 0b00000111; //(0x07 in hex) Pull-up resistor is connected to RB0, RB1 & RB2
pins

3) Which I/O pin is the only ‘true’ external interrupt source and which SFR's are configured to
set up this interrupt. Write down intructions to set up the external interrupt.

B0 is the only true external interrupt source:

TRISB0_bit = 1; //Set B0 as input


INTCON = 0xD0; //Enable INTE/RB0 interrupt (bits GIE, PEIE and INTE)
Alternatively INTE_bit = 1; GIE_bit = 1; PEIE_bit = 1; //set each IE bit
separately
INTIF_bit = 0; //reset INTIF interrupt flag

4) Which SFR's are used to control the operations of Timer0, Timer1 and Timer2? How can
you configure the Timers to operate either as a Timer or a counter? How can you select the
clock source? How can you set the prescaler values? Write down instructions to accomplish
these functions.
OPTION_REG is used to control Timer0
T1CON is used to control Timer1
T2CON is used to control Timer2

Timer0 Configuration:

T0CS_bit=0; //Timer0 uses internal cycle clock (Fosc/4) and operates as Timer
T0CS_bit=1; //Timer uses external clock input on RA4 and operates as counter
PSA_bit = 0; // Prescaler is assigned to the TMR0 timer/counter
PS0_bit = PS2_bit=1; //Timer0 is set as a timer with a prescale factor of 1:64
PS1_bit=0;
PS2, PS1, PS0 bits are used to select the Prescale value

Timer1 Configuration:

TMR1CS_bit = 0; //Timer uses internal cycle clock (Fosc/4) and operates as a Timer
TMR1CS_bit = 1; //Timer uses external cycle clock input and operates as a counter
T1CON = 0b00110001; // Timer1 is set as a Timer with a prescale factor of 1:8
T1OSCEN_bit = 1; // LP Oscillator (32 kHz) is used as the TMR1 Clock
TMR1GE & T1GSS bit enables Timer1 gate control, T1GINV is used to start T1 at high
or low
T1CKPS1 & T1CKPS0 bits are used to select the Prescale value
TMR1ON_bit = 1; //Timer1 starts counting the time in us

Timer2 can be configured using T2CON, similar to Timer1 configuration.

5) Why do we need interrupt property of timers and how do we set up timer interrupts? Write
down instructions to accomplish these functions.
We need interrupts to detect the instants of overflow and compare match of timers.
GIE_bit=PEIE_bit=1; // Enable interrupt (bits GIE and PEIE are set)
TMR1IF_bit = 0; // Reset the TMR1IF bit
TMR1IE_bit=1; //Enable an interrupt on TMR1 verflow
TMR1ON_bit = 1; // Turn on timer TMR1

6) Which SFR's are used to control the Capture, Compare and PWM operations? Write down
instructions to set up capture, PWM and compare operations. How can you set the frequency
and the duty period of the PWM signal?

CCP1CON, CCP2CON, CCPR1, CCPR2 & TMR1 SFR’s are used to control the Capture
and Compare operations.

CCP1CON, CCP2CON, CCPR1, PR2, CCPR2, TMR2, PWM1CON & PSTRCON SFR’s
are used to control the PWM operations.
Capture Configuration:

TRISC2_bit=1; // RC2 is assigned as input for CCP1


CCP1CON=0x05; // CCP1 module is configured to capture every rising edge on RC2
CCP1IF_bit=0; //capture interrupt flag is reset
GIE_bit=PEIE_bit=1; //GIE & PEIE are enabled to generate interrupt at
//rising edges
CCP1IE_bit=1; //CCP1 interrupt is enabled
TMR1ON_bit=1; //Timer1 is started

Compare configuration:
CCP1CON=0x0A; // CCP module is configured for compare operation
// Interrupt request arrives and bit CCP1IF is set on match
CCPR1= 500000; //Timer1 will be compared with 500000 us and an interrupt will be
//generated on match
TMR1ON_bit=1;

//Timer1 is started
GIE_bit=PEIE_bit=1 //GIE & PEIE are enabled
PWM configuration
TRISC2_bit = 0; // Assign PORTC2 pin as output
CCP1CON = 0x4C; // PWM1 on all P1 pins are set to active HIGH
//DC motor Full bridge forward rotation mode is selected
PR2 = 255; //Set the period (frequency) of the PWM1 to 255 us for 4Mhz osc
CCPR1L = 20; // set the duty ratio as 20 us
PSTRCON = 0x0F; //enables PWM for P1A, P1B, P1C & P1D pins
PWM1CON = 0x05; //Deadband is defined as 5 us, in the inverter mode

7) Write comments for each of the following instructions to explain their functions clearly:
Assume that the clock frequency is 4 MHz and prescale ratio is 1:1
duty = (long)adc_rd*255/1024; //convert (map) the value of adc_rd from 0 to 1023 to 0 – 255 and
save it into duty val
WPUB =0x43; //Connect pull-up resistors to B0, B1 and B6.
CCP1CON = 0x8C; //Half Bridge output, P1A and P1B Modulated with deadband control
PR2 = 200; //Set the PWM period to 200 us
CCPR1L= 50; //Set the Duty period to 50 us
OPTION_REG.F7 =0; //Enable Pull up property for PortB
adc_rd = ADC_Read(0); //Read analog Voltage on AN0 and store it to adc_rd
INTCON = 0xD8; //11011000 GIE, PEIE, INTE and RBIE interrupts are enabled
CCP1IE_bit = 1; //Capture interrupt on RC2(CCP1) is enabled
Lcd_Out(2,1,"Counter is");//Print Counter is on the second row of LCD starting from first
column
8)How can you drive an Hbridge circuit with PWM signals and which pins produce PWM
HBRIDGE DC Motor Control Mode

P1B

P1C

P1D

P1D (RD7) & P1B (RD5), pins produce PWM signals. P1A (RC2) & P1C (RD6) pins produce
Active (High or Low) signals
CCP1CON = 0xCC; //PWM1 on all P1 pins are set to active HIGH
//DC motor Full bridge reverse rotation mode is selected

HBRIDGE Inverter Control Mode

P1A and P1B produce PWM signals with 180 deg phase shift
CCP1CON = 0x8C; //PWM1 on all P1 pins are set to active HIGH
//Inverter mode is selected
PWM1CON= 0x05; //sets the deadband to 5 us
9) Write a C program to control the light intensity of an LED connected to RC2 pin, using two
buttons connected to RB0 (increase) and RB1 (decrease) and applying the PWM function of
the PIC16F887. Construct the hardware of this simple circuit under Proteus simulator and apply
your program to your simulator to see the result.
L1(1)

L1
12V

U1
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
16
R1 Q1
2 17 BC337
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
REF TEMP + 4
RA1/AN1/C12IN1- RC3/SCK/SCL
23
1k
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
REF TEMP - RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
PIC16F887

LED Light Intensity Control using buttons:

void main(){
ANSEL=ANSELH=0; //set all pins to digital I/O
TRISB=0x03; //Set B0 and B1 as inputs for buttons
TRISC2_bit = 0; // assign RC2 pin as output for PWM
CCP1CON=0x0C; //configures the CCP1 for PWM operation
CCPR1L=20; // Sets the duty period to 20 us for 4 MHz oscc
PR2=250; //Assuming 4 MHz OSC, set the period to obtain a 4 kHz PWM
OPTION_REG.F7 = 0; //Enable pull up resistors for PortB pins
WPUB=0x03; // Enable pull up rsistor for RB0 & RB1
GIE_bit =1; //Global interrupt enable
RBIE_bit = 1; //Logical change on Port B pins is enabled
IOCB= 0x03; //Logical change on RB1 is enabled
RBIF_bit = 0; // PORTB interrupt flag is reset
T2CON=0x04;
while(1){
//Wait for the buttons to be pressed
}
}
void interrupt(){
if (RB0_bit == 0){ //If button on B0 is pressed
CCPR1L = CCPR1L + 10; // Increase current duty
RBIF_bit = 0;
}
if (RB1_bit == 0) { //If button on B1 is pressed
CCPR1L = CCPR1L -10; // Decrease current duty
RBIF_bit = 0;
}
}

10) Write a C program to control the light intensity of an LED connected to RC2_bit using a
potentiometer connected to AN0 and the PWM function of the PIC16F887. Construct the
hardware of this simple circuit under Proteus simulator and apply your program to your
simulator to see the result.
L1(1)

L1
12V

RV1 U1
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
16
R1 Q1
2 17
57%

RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1 BC337


3 18 1k
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
1k 6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
PIC16F887

void main(){
ANSEL=0x01; //A0 is assigned as analog input for POT
TRISC2_bit = 0; //Assign RC2 pin as output for PWM
CCP1CON=0x0C; //configure CCP1 for PWM operation
PR2=250; //Assuming 4 MHz OSC, set the period to obtain a 4 kHz (250us) PWM
CCPR1L =20; //Initial value of 20 us (for a clock freq of4MHz) for Duty ratio
Delay_ms(10); //Wait until PWM settles
while(1){
CCPR1L = (long)ADC_Read(0)*250/1023; //Convert POT value into Duty 0-250
Delay_ms(10); //Wait until PWM settles
}
}
11) Write a C program to measure the period of a square waveform applied to RC2 pin using
the capture feature pf PIC16F887 and display it on an LCD. Simulate this application under
Proteus environment.

char txt[7];
unsigned int period;
void main() {
ANSEL = ANSELH = 0x00; //All pins are set to digital I/O
TRISC2_bit = 1; //Set RC2 as input for pulse signal
CCP1CON=0x05; //Capture every rising edge
GIE_bit=PEIE_bit=1; //Enable Global and peripheral interrupt
CCP1IE_bit=1; //Enable capture interrupt
CCP1IF_bit=0; //Reset interrupt flag
TMR1L=0x00; //Reset Timer register
TMR1H=0x00;
Lcd_Init(); //Initialize the LCD
T1CON=0x01; //Start Timer1
TMR1L=TMR1H=0; Reset Timer1 counter
while(1){
IntToStr(period, txt); //Convert period into string to be displayed on the LCD
Lcd_Out(2,1,txt); //Display the period on the second row third column of LCD
Delay_ms(100);
}
}
void interrupt(){ //When the rising edge occurs on RC2 (CCP1) input
CCP1IF_bit=0; // Reset the inerrupt flag
period = CCPR1; //Save the current value of Timer1 when the rising edge occurs
TMR1L=0x00; //Reset the Timer1 fort he next period measurement
TMR1H=0x00;
}

12) In which application can you use the Timer1 gate control and which SFR’s are used to
configure Pic16F887 for the Timer1 gate control? Write a program to measure the period of a
pulse waveform using the Timer1 gate control and simulate this application using Proteus.

LCD1
LM016L
R2
VDD
VSS

VEE

RW
RS

D0
D1
D2
D3
D4
D5
D6
D7

10k
E

RV1 SONAR1 U1
1
2
3

4
5
6

7
8
9
10
11
12
13
14

ULTRASONIC SENSOR 1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
www.TheEngineeringProjects.com RC1/T1OSI/CCP2
0%

TestPin 2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
1k RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
Trigger

RA6/OSC2/CLKOUT
Echo

13 19
Gnd
+5V

RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29 R1
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39 330
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
B

A
D

PIC16F887
D1
LED-BLUE
char txt[8];
unsigned int period, distance;
//Alarm function to turn ON & OFF a buzzer if Distance < 15 cm
void alarm() {
RD7_bit=1;
delay_ms(100);
RD7_bit=0;
delay_ms(100);
}
void main() {
ANSEL = 0x00; //All pins are digital
ANSELH = 0x00;
T1GSS_bit = 1; //T1G(RB5) input is used for gate control
TRISB=0x21; //B5 is input for the T1G input and B0 is input to detect the rising
//edge of the ECHO Pulse
GIE_bit=1; //Global interrupt is enabled
INTE_bit=1; //RB0/INT is enabled to detect the rising edge of the ECHO Pulse at T1G
INTF_bit=0; //INTF flag is reset
TRISD=0x00; // All PortD pins are assigned as outputs to drive the LCD and buzzer
PORTD =0x00;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,"Distance ");
T1CON = 0xC1; //Start Timer1 and set TMR1GE and T1GINV bits to enable T1G
TMR1L=0x00; //Timer is reset to start measuring the period
TMR1H=0x00;
while(1){
RD6_bit=1; //Send a trigger pulse to the TRIG input of the sensor
Delay_us(10); // pulse period is 2 us
RD6_bit= 0;
period = TMR1L | (TMR1H<<8); // TMR1 value is obtained by combining L & H bytes
distance = period/58 ; // Distance to the target is obtained using the pulse period
intToStr(distance, txt);
Lcd_Out(1,11,txt);
if(distance < 15)alarm(); //Alarm is triggered if distance < 15 cm
Delay_ms(1000);
}
}
void interrupt() {
INTF_bit=0;
TMR1L=TMR1H=0; //TMR1 is reset at each rising edge of the ECHO pulse
}
13) Draw the circuit diagrams and write down instructions for the following cases:
a) Write down instructions to enable the internal pull up resistors to pins RB0 and RB1 of
Pic16F6887. Draw a circuit diagram where active low buttons are connected to these pins. Use
the internal pull-up resistors of the Pic. Turn ON an LED connected to RD0 when the button
on RB0 is pressed and turn it OFF when the button on RB1 is pressed.

void main(){
ANSEL = ANSELH=0;
TRISB=0x03; //set B0 and B1 as inputs
TRISD0_bit = 0; //set D0 as an output
PORTC=0x00;
OPTION_REG.F7=0; //enable pull-up resistors
WPUB = 0x03; //enable pull-up resistor on B0 & B1
GIE_bit =1; //Global interrupt enable
RBIE_bit = 1; //Logical change on Port B pins is enabled
IOCB= 0x03; //Logical change on RB1 is enabled
RBIF_bit = 0; // PORTB interrupt flag is reset

while(1){
}
}
void interrupt(){
if (RB0_bit == 0){
RC0_bit =1; //LED is ON when B0 is pressed
RBIF_bit = 0;
}
if (RB1_bit == 0) {
// LED is OFF when B1 is pressed
RBIF_bit = 0;
}
}
b) Write down instructions to operate the CCP1 module of Pic16F6887 in compare mode and
flash a LED diode connected to RC0 pin every 400 ms. Use a clock frequency of 4 MHz.
U1 R1
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2 330
2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3
RA1/AN1/C12IN1- RC3/SCK/SCL
18 D1
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24 LED-BLUE
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
PIC16F887

void main(){
TRISC0_bit= 0; //RC0 is assigned as output to drive the LED
RC0_bit=1; //LED is initially turned ON
GIE_bit = PEIE_bit=1; //GIE & PEIE are enabled to generate interrupt at rising edges
CCP1IE_bit = 1; //CCP1 interrupt is enabled
CCP1IF_bit=0; //CCP1 interrupt flag is reset
TMR1L=0x00; //TMR1 is reset
TMR1H=0x00;
CCPR1= 50000; //50 ms is assigned to the Compare value
T1CON=0x31; //Timer1 is started and a prescale factor of 1:8 is selected to time 400 ms
CCP1CON=0x0A; //CCP1 module is in compare mode, interrupt arrives and CCP1IF=1 on
match
while (1){
}
}
void interrupt() {
RC0_bit = ~RC0_bit; //toggle RC0 to flash the led every 400 ms
CCP1IF_bit=0;
CCPR1= 50000; //50000*8 = 400000 us = 400 ms is set to generate interrupt every400 ms
TMR1L=0x00; //TMR1 is reset
TMR1H=0x00;
}
c) Write a mikroC program which measures the room temperature using LM35 (10mV/degC)
connected to pin AN0 of the Pic16F6887. An LED connected to pin RC2 is turned ON when
the temp < 22 degC and it is turned OFF when the temp > 25 degC. Draw the circuit diagram
unsigned short duty = 125;
int adc_rd, temp;
void main() {
ANSEL = 0x01; //A0 is set as analog
TRISA0_bit=1; // A0 is set as input
TRISC2_bit=0; // RC0 is set as output
while(1){
adc_rd = ADC_Read(0); // A/D conversion. Pin RA0 is an input
temp = (long)adc_rd*500/1024; //convert LM35 output voltage into degC using 10mV/degC
if(temp>25)RC2_bit=0;
if(temp<20)RC2_bit=1;
}
}
}

14) Draw the HBridge power control circuit diagram of a DC motor speed control system using
the PWM feature of PIC16F6887 and write a MicroC program to accomplish the following
requirements:

a) Generate a PWM signal with variable duty ratio and drive the motor via the terminals P1A,
P1B, P1C and P1D
b) Use a potentiometer connected to AN0 pin to control the speed of the motor by changing the
duty ratio of the PWM signal.
c) Use an active low button connected to PORTB0 which rotates the motor in clockwise
direction and an active low button connected to PORTB1 which rotates the motor in counter
clockwise direction.

unsigned short duty = 125;


unsigned int adc_rd;
void main() {
ANSEL = 0x01; //A0 is analog others are digital
ANSELH=0;
TRISD=0;
TRISC =0;
TRISB=0x03;
PORTC=0; //RC2 is used as P1A output
PORTD=0; //RD5, RD6 and RD7 are used as P1B, P1C and P1D outputs
OPTION_REG.F7 =0; // Pull up resistors are enabled for PORTB
WPUB =0x03; // Pull up resistors are enabled for RB0 and RB1
GIE_bit = 1; //Global interrupt enable
RBIE_bit = 1; //Logical change on Port B pins is enabled
IOCB = 0x03; //Logical change on RB1 is enabled
CCP1CON = 0x4C; // Full bridge forward rotation is selected at start
PR2 = 250; // Set PWM period as 250 us, assuming that fosc=4MHz;
CCPR1L= 50; //Duty ratio is set as 50
T2CON =0x04;
Delay_ms(100);
while(1){
adc_rd = ADC_Read(0); // Pot value is read at the RA0 analog input
duty = (long)adc_rd*250/1024; // analog value is converted into duty ratio with max 250
CCPR1L = duty; //Duty period is updated according to the analog input from the pot value
Delay_ms(100);
}
}
void interrupt(){
if (RB0_bit == 0){ //If button on B0 is pressed
CCP1CON=0x4C;// Motor is rotated in CCW direction if B0 is pressed
RBIF_bit = 0;
}
if (RB1_bit == 0) { //If button on B1 is pressed
CCP1CON=0xCC;//Motor is rotated in CCW direction if B1 is pressed
RBIF_bit = 0;
}}
Q3(D)

D1(A)
Q3
D1
Q1
DIODE IRF150
C

D
A

C3 3 U1 C2
10uF .1uF
IRF150
10 6
HIN VC VB
R2
11 7
SD HO
5 150
VS
12 1
LIN COM LO

2 IR2112

RV1 U3
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
16 R3
2 17
31%

RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18 150
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5
RA3/AN3/VREF+/C1IN+ RC5/SDO
24
A
Q4
10k 6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
14
RA5/AN4/SS/C2OUT RC7/RX/DT B Q2
RA6/OSC2/CLKOUT IRF150
13 19
RA7/OSC1/CLKIN RD0 C
20
RD1
33 21
RB0/AN12/INT RD2 D
34 22 IRF150
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D D2(A)
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9 D2
RE1/AN6
10
RE2/AN7
DIODE
PIC16F887 C1
10uF
U2 C4
3 .1uF
10 6
HIN VC VB
11 7
R4
SD HO
5 R5
150
VS
12 1
LIN COM LO
150
2 IR2112
15) Write the instructions to capture a rising edge at the RC2/CCP1 input of the Pic16F887,
generate an interrupt when a rising edge arrives and save the curent value of Timer1 into a
variable called Period at this instant when the rising edge arrives. Reset Timer1 at each
rising edge.
Write your comments for each instruction, to explain its function and parameters
clearly.
16) Write a mikroC program to control the speed of a DC motor connected to the RC2 pin of a
Pic16F887, via a BC237 transistor using a potentiometer and the PWM function of the
PIC16F887. Draw the circuit diagram showing each component and connections clearly.
Write your comments for each instruction, to explain its function and parameters
clearly.
b) How can you change the direction of rotation of the motor? Explain the method of rotating
the DC motor in both directions by drawing the circuit diagram. Which SFR is used to change
the direction of the motor. Which values do you assign to this SFR in order to rotate the DC
motor in the forward and reverse directions?

17) Draw the diagram of a closed loop oven temperature control system including: a Pic16F887,
an oven with a thermocouple, a transistor and a relay to energize the oven from an AC supply,
a potentiometer to set the reference temperature and two LED indicators to indicate the status
of the oven.

Write a MikroC code for Pic 16F887 which will control the temperature of an oven by
performing the following functions:

- Read the variable analog voltage obtained from the Reference Temperature
Potentiometer and convert this voltage into a reference temperature value, assuming that
the maximum reference temperature will be 300 degC.
- Read the analog voltage obtained from the thermocouple and convert this voltage into
actual oven temperature using the Temperature coefficient (20mV/degC) of the
thermocouple.
- Turn ON the heater, using a transitor and a relay, if the actual temperature is less than
reference temperature – 2 degC. Also turn ON the LED to indicate that the Heater is
ON.
- Turn OFF the heater, if the actual temperature is more than referance temperature +2
degC, also turn OFF the LED.

18) Design a red light viloation detection system having the following components:

A vehicle detector connected to the RB0 pin is placed on the road just before the traffic lights,
a Pic 16F887 based control card, an LCD to display the number of vehicles which cross the
junction while the red light is ON and also the total number of vehicles crossing the junction
on this road. Use the RB0/INT interrupt feature of the Pic16F887 to detect the vehicles. You
can represent the vehicle sensor with a push button on your circuit diagram.

Draw the circuit diagram of the system and write a MikroC code which will:

- Control the phases of one set of traffic lights using the RC0, RC1 & RC2 pins (Red 15
sec), (orange 2 sec), (Green 20 sec)
- Detect the vehicles using a vehicle detector placed on the road which acts as a push
button when the vehicle passes over the sensor. The sensor output is connected to the
RB0/INT pin
- Count the number of total vehicles passing on this road and the number of vehicles
which violate the red light rule.
- Use the PORTD pins to drive the LCD. You can ignore the sbit LCD commands in the
program
- Display the total number of vehicles which crosses the junction on the first row of the
LCD.
- Display the number of Vehicles which violate the red light rule on the second row of
the LCD.
Write your comments for each instruction, to explain its function and parameters
clearly.

19) a) What is the function of Max232 IC? Draw a diagram showing the connections between
the PIC, MAX232 and the PC serial port.
20) Draw a digram showing the sequence of idle state, start bit, 8 bit data and stop bit during
data transmission via the serial port
21) Which registers are used in data transmission via the serial port. Explain how a data is
transmitted from one device to another (EUSART Data Transmitter) on a diagram.
22) Which registers are used in data receive via the serial port. Explain how a data is received
(EUSART Data Receiver) on a diagram.
23) What are the differences between Synchronous and asynchronous modes of serial
communication? What are the advantages and disadvantages of these modes of
communication?
24) Why do we use RX9 bit in Asynchronous communication. Explain how the adress of the
slave is detected using RX9 on a diagram. Pages 150, 151
25) Explain how address detection in the asynchronous serial communication is made when more than
one slave is used, by making use of the related diagrams, by making use of necessary figures.
Explain Framing Error and the Overrun Error in Serial Communcation. How can you detect these errors?
26) Explain how the address and data are transmitted in I2C communication.
27) Write instructions to write into and read from the internal EEPROM of the Pic6F887
28) Write instructions to write into and read from the external EEPROM 24C02.
29) Explain the importance of resolution in ADC. What are the two methods to increase resolution in
an ADC operation?
30) Explain the principles of Analog Comparator module of the Pic16F887. In which applications can
you use Analog Comparators. Give a practical example using figures.

31) A PIC 16F887 microcontroller which measures the temperature and heart rate of a patient
is connected to a PC via the serial port and they communicate via the UART in asynchronous
mode. Body temperature of the patient is measured using an LM35 (10 mV/degC) connected to the
RA0 pin. Heart rate sensor produces a square wave pulse, for each heart beat, which is applied
to the RC0 (T1CKI) counter input of the PIC. Write a MicroC code which will perform the
following actions:
i) The user sends a value of 1 from the PC to the PIC16F887 via the UART to start the
temperature and heart rate measurement.
ii) When the PIC receives the value of 1 at its RX terminal, it starts measuring the temperature
using the temperature sensor LM35 (10 mV/degC) connected to the RA0 pin and the heart rate
using the TMR1 counter feature of the PIC which counts the pulses at the RC0 (T1CKI) input
pin.
iii) Heart rate is measured by starting TMR1 and after a delay of 10 sec, recording the value of
TMR1 register. Heart rate/min can be calculated by multiplying the TMR1 value with 6.
iv) PIC sends the values of the temperature and the heart rate to the PC via the serial port.
v) If the heart rate > 140 or the temperature > 40 degC an alarm is generated via the RB0 pin.

int bodyTemp, uart_rd, heartRate;


char txt[8];
void main(){
ANSEL= 0;
ANSELH = 0x01; //Only RA0 is analog
T1CON = 0x03; //TMR1 is set as counter to count pulses from RC0 (T1CKI) counter input connected to the heart rate sensor
TRISA0_bit = 1; //RA0 is set as an input for LM35
TRISB0_bit = 0; // RB0 is set as an output for alarm
TRISC0_bit = 1; //RC0 is set as counter input
RB0_bit = 0; // Reset RB0 as output to turn OFF the alarm
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
while(1){
if (UART1_Data_Ready()) { // If data is received from PC terminal at the RX terminal of the PIC,
uart_rd = UART1_Read(); // PIC reads the received data at the RX pin
uart_rd = uart_rd - 48; //Convert ASCII data to decimal. ASCII for 0 is 48
if(uart_rd==1) { //If a data of "1" is received from the the PC, measurement is started
bodyTemp = ADC_Read(0); //Read analog value from the body temperature sensor
bodyTemp = (long)bodyTemp*500/1023; //Convert the analog value from 0-5 V to 0-500 C (for 10mV/ degC and Vref=5V)
TMR1H = TMR1L = 0; //Reset TMR1 counter
Delay_ms(10000); //Let TMR1 count the heart beats for 10 seconds
heartRate= (TMR1L | (TMR1H<<8))*6; // heartRate is obtained by combining L & H bytes and multiplied by 6. (pulses/min)
inttostr(bodyTemp,txt); //body temperature is converted to string to send to the PC serial port
UART1_Write_Text(" Temperature:");
UART1_Write_Text(txt); // Body temperature is sent to the PC serial port
inttostr(heartRate,txt); // heartRate is converted to string to send to the PC serial port
UART1_Write_Text(" Heart Rate:");
UART1_Write_Text(txt); // PIC sends heartRate data from its TX pin, to the PC terminal via UART
UART1_Write_Text(" \r"); // Feed one line for the next reading
if (bodyTemp > 40 | heartRate > 140) RB0_bit = 1; // If the bodyTemp is > 40 or heartRate is >140, alarm is turned ON
else RB0_bit = 0; //otherwise alarm is turned OFF
}
}
}
}

32) Please answer the following questions clearly, by using the related diagrams:
a) Explain how address detection in the asynchronous serial communication is made when more than
one slave is used, by making use of the related diagrams.

b) Explain the importance of resolution in ADC operation. What determines the resolution and how can
you increase the resolution in an ADC operation? Assuming that a temperature sensor (thermocouple)
which produces 5 mV/°C output, is used to measure an oven temperature with a maximum value of 500
°C, calculate the optimum reference voltage applied to the Vref+ input of the Pic16F887 to measure the
oven temperature with the best resolution. Write down the instructions required to enable external Vref+,
read the sensor voltage and convert into temperature in °C.
) Resolution determines the minimum detectable change in the ADC operation. Resolution can be
increased by:
- increasing the number of bits in the ADC result register
- Applying a suitable Vref at the Vref+ pin (pin5) whose voltage is equal to the maximum value of the
sensor output voltage:
Vref = 5 mV/°C *500 °C = 2500 mV
To enable the use of external Vref+ voltge of 2500 mV at pin5 (Vref+ pin) of the pic, following
instructions should be used :

ADCON1= 0x90; // ADFM is set to 1 for right justified and VCFG0 is set to 1 to use external Vref+

33) A Pic16F887 based vehicle speed and count measurement system is defined as follows:

• 2 Vehicle detectors are mounted perpendicularly on a road with a distance of 1m between each
other. The detectors produce a short pulse when the wheels of the vehicles press on them.
• Each of CCP1 and CCP2 Capture inputs of the Pic16F887 microcontroller are connected to one
of the vehicle detectors to capture the rising edges of the pulses produced as the vehicle wheels
press on the detectors.
• Assume that there will be no Timer overflow during speed measurements.
Write a MicroC program using CCP1 & CCP2 capture interrupt property of Pic16F887 to perform the
following functions:
a) Measure the speed of the vehicles passing over the detectors
b) Count the number of vehicles passing over the detectors
c) Start a UART serial communication with a PC and send the measured speed and the number of
vehicles to the PC monitor via the serial port.

char txt[8];
unsigned int period, velocity, cnt=0;
void main() {
ANSEL = 0x00;
ANSELH=0;
TRISC= 0x06; // RC1 & RC2 is assigned as input for CCP2 and CCP1 respectively
TRISD=0x00; // PortD is assigned a output to drive the LCD
PORTD=0x00;
CCP1CON=0x04; // CCP1 modules is configured to capture every falling edge of the pulse signal
applied to RC2 input
CCP2CON=0x04; // CCP2 modules is configured to capture every falling edge of the pulse signal
applied to RC1 input
GIE_bit=PEIE_bit=1; //GIE & PEIE are enabled to generate interrupt at falling edges
CCP1IE_bit=CCP2IE_bit=1; //CCP1 & CCP2 interrupts are enabled
CCP1IF_bit=0; //capture interrupt flag is reset
CCP2IF_bit=0; //capture interrupt flag is reset
TMR1L=0x00; //TMR1 is reset
TMR1H=0x00;
T1CON=0x01; //Timer1 is started
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(200);
while(1){
velocity=(long)3600000/period; //Calculate velocity in km/hr
inttostr(velocity,txt); // velocity is converted to string to send to the PC serial port
UART1_Write_Text("Velocity:");
UART1_Write_Text(txt); // PIC sends velocity data via USART
inttostr(cnt,txt); // Count is converted to string to send to the PC serial port
UART1_Write_Text("Count:");
UART1_Write_Text(txt); // PIC sends count datavia USART
}
}
void interrupt(){
if(CCP1IF_bit){
CCP1IF_bit=0;
TMR1L=0x00; //TMR1 is reset to start speed measurement when the vehicle is detected by the first
sensor
TMR1H=0x00;
cnt++;
}
if(CCP2IF_bit){
CCP2IF_bit=0;
period = CCPR2; //Period is recorded using the Timer1 value captured in CCPR2, when the vehicle
is detected by the second sensor
}
}

34) Design a Home Automation and Security Control System using:


a PIC16F887, an IR motion sensor with a digital output, an optical (TCRT5000) door detector, a smoke
sensor and an alarm horn. Write a MikroC program to perform the following actions:
- Set the alarm if the front door is opened or if any motion is detected at the entrance hall.
- Set the alarm if the smoke sensor is activated by a fire.
Note: Use PortB IOC interrupts to activate the alarms mentioned above.
- If the alarm is activated, it can be reset by pressing a button connected to the RB0/INT input,
using the interrupt feature.
- Room temperature is controlled by measuring the temperature with an LM35 sensor and using
a heater which is connected to the PIC16F887 via a transistor and a relay. Reference
temperature is set by using a potentiometer.
- The lights of the living room are turned ON and OFF according to the darkness of the room
using an LDR connected to the PIC16F887 via the Schmitt Trigger IC 74HC14. Use the capture
input (RC2) and the interrupt feature for this operation.
2
LDR1
1 U2 RV1 TORCH_LDR

1
24.0

74%
U1
2 1 15 :A
VOUT RE3/MCLR/VPP RC0/T1OSO/T1CKI
1k RC1/T1OSI/CCP2
16 R2
2 17 2 1 10k
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
3 LM35 4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA 74HC14
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
ALARM RESET 7
RA5/AN4/SS/C2OUT RC7/RX/DT
26

Vcc TX GND
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20

Reader
Card
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
Vcc Out GND

RB2/AN8 RD4
36
RB3/AN9/PGM/C12IN2- RD5/P1B
28 R1
37 29 R3
IR Motion

RB4/AN11 RD6/P1C 220


Sensor

38 30 220
RB5/AN13/T1G RD7/P1D BUZ1
Digital

39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9 R4
RE1/AN6 1k
10
RE2/AN7
BUZZER
PIC16F887 Q2
3 4
D2 BC237
HEATER
LED-BLUE
:B 20
74HC14
220V RL1 5V
Vcc Out GND MAINS SUPPLY
Digital

Sensor Q1
Smoke

BC237

int temp, ref;


void main(){
ANSEL=0x03; //AN0 & AN1 are analog, other pins are digital
ANSELH=0;
TRISA =0x03;
TRISC2_bit=1; //sets RC2 pins as input for the LDR
TRISB =0x0F; //RB0, RB1, RB2 & RB3 are set as inputs for the interrupts & alarm reset button
TRISD=0; //PORTD pins are set as output for ligths, alarm and heater control
PORTD=0; //ligths, alarm and heater are initially OFF
INTCON =0xC8; // Global, Peripheral and IOC at PortB are enabled
OPTION_REG.F7=0;
WPUB= 0x0F; //Pull up resistors are connected to B0, B1, B2 & B3
IOCB = 0x0F; // PORTB 0, 1, 2 & 3 pins of PORTB are enabled for IOC
RBIE_bit = 1; //PORTB Interrupt On Change is enabled
RBIF_bit=0;
INTEDG_bit=0; //RB0/INT will occur on the falling edge
CCP1CON=0x05; //set CCP1 to capture rising edge (darkness)
CCP1IE_bit=1; //Capture interrupt is set to detect dark/light change
CCP1IF_bit=0;
Delay_ms(10);
while(1){
temp = (long)ADC_Read(1)*500/1024; //convert LM35 output voltage into deg C
ref = (long)ADC_Read(0)*30/1024; //convert ref pot voltage into deg C
if (temp > ref+1) { // if actual temp is greater than reference temp
RD2_bit = 0; //turn OFF heater
}
if (temp < ref-1){ // if actual temp is less than reference temp
RD2_bit = 1; //turn ON heater
}
Delay_ms(1000);
}
}
void interrupt(){
if(CCP1IF_bit){
RD1_bit=!RD1_bit; //turn ON/OFF lights
CCP1CON.F0= !CCP1CON.F0; //set CCP1 to capture rising edge (light)
CCP1IF_bit=0;
}
if (RBIF_bit){
if (RB0_bit=0){
RD0_bit=0; //reset alarm
RBIF_bit=0;
}

if(RB1_bit){
RD0_bit=1; //activate alarm when door opens
RBIF_bit=0;
}
if(RB2_bit){
RD0_bit=1; //activate alarm when motion is detected
RBIF_bit=0;
}
if(RB3_bit){
RD0_bit=1; //activate alarm when fire is detected
RBIF_bit=0;
}
}
}

35) Design a Gate Control System having the following components:


A simple card reader module which can be directly interfaced with microcontrollers using the UART
communication terminals. When the card reader reads a card, it will send the card number as a one byte
data, via its TX terminal which is connected to the RX terminal of the PIC16F887.
Write a MikroC program to perform the following functions:
- Read the card number and check whether it has an access through the gate by comparing with
the 50 numbers which are stored in the internal EEPROM of the PIC16F887, starting from the
address location 0x08 of the internal EEPROM.
- Open the gate using a transistor and a relay connected to RD2, when a valid card is read and use
a buzzer connected to RD1 to give a beep sound to indicate that the card is valid.
- Print the number of the card on the UART serial monitor of the PC.
U1

Vcc TX GND
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16

Reader
Card
RC1/T1OSI/CCP2
2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35
RB2/AN8 RD4
27 R2 Gate turnstile
36 28 1k
RB3/AN9/PGM/C12IN2- RD5/P1B
37
RB4/AN11 RD6/P1C
29 R3 BUZ1
38 30 1k
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6 BUZZER
10
RE2/AN7 RL1
Q1 5V
PIC16F887 BC237 D1
DIODE

Q2
BC237

#include <built_in.h>
char txt[8];
unsigned int data1, uart_rd, i=0;
void main(){
ANSEL = ANSELH = 0; // Configure AN pins as digital I/O
PORTD = 0;
TRISD = 0;
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
while (1){
RD1_bit= RD2_bit=0; //Turn off the gate and the buzzer initially
if (UART1_Data_Ready()) { // If data is received from PC terminal at the RX terminal of the PIC,
uart_rd = UART1_Read(); // PIC reads the received data at the RX pin
for (i= 8 ; i < 58; i++){
data1 = EEPROM_Read(i); // Read data from address 8 to 58
if (uart_rd==data1){
RD1_bit= RD2_bit=1; // Open the gate and turn ON the buzzer
break; //Skip the rest of the for loop when match occurs
}}
inttostr(uart_rd,txt); // card number (uart_rd) is converted to string to send to the PC serial port
UART1_Write_Text(" Card No");
UART1_Write_Text(txt);
Delay_ms(1000);
RD1_bit= RD2_bit=0; //close the gate and turn off the buzzer
}}}
36) The tank shown in the figure is used to heat and mix a fluid in a
chemical process which is controlled by a PIC 16F887 microcontroller.

The mixer is driven by a DC motor whose speed is controlled by the


PWM1 (CCP1) module at the RC2 pin of the PIC via a transistor at a
frequency of 10kHz. Assume Fosc = 8 MHz.

The temperature of the heater is controlled by using a relay and a


transistor whose base terminal is connected to RD0, via a series resistor.
ON/OFF control is applied to keep the temperature of the fluid between
110 – 115 deg C

- A closed loop temperature control is used where the temperature of the fluid is measured with
a thermocouple whose sensitivity is 20 mV/degC and fed back to AN1 input of the PIC. The
temperature of the fluid should be kept between 110 - 115 deg C using the PWM2 control.
- The DC motor of the mixer is started when the temperature is above 50 degC and the speed of
the DC motor is controlled by changing the duty ratio of the PWM1 manually by a potentiometer
connected to AN2 pin of the PIC.
- The whole process will be finished in 30 minutes and this period will be determined by the
Timer1 whose prescale factor is set to 1:8. Use Timer1 overflow interrupt feature to count this
time period. When the process is finished, the mixer and the heater should be turned OFF.

a) Draw a proteus circuit diagram of this system and label each component clearly on the diagram.
b) Write a MicroC code to perform the required actions explained in the above procedure, including
detailed explanations of each instruction clearly.
(+)

U1
RV1 1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
16
R1 Q1
2 17 BC337
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
66%

RA1/AN1/C12IN1- RC3/SCK/SCL 1k
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO RL1
6 25
RA4/T0CKI/C1OUT RC6/TX/CK 5V
1k 7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3 Q2
35
RB2/AN8 RD4
27 R2
36 28 BC337
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29 1k
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
PIC16F887

+88.8
Volts Heater
OV1
OVEN

int temp, duty, cnt=0;


void main(){
ANSEL=0x06; //A1 & A2 is assigned as analog input for POT
ANSELH=0; //Other pins are assigned as digital I/O
TRISD0_bit =0; //RD0 is an output to drive the motor
RD0_bit=0 ; //The motor is initially turned OFF
TRISC2_bit = 0; //Assign RC2 pin as output for PWM
CCP1CON=0x0C; //configure CCP1 for PWM operation
PR2=200; //For an 8 MHz OSC, set the period to obtain a 10 kHz PWM
CCPR1L =0; //Initial zero voltage is applied to the motor
GIE_bit=PEIE_bit= 1; //Global and peripheral interrupts are enabled
TMR1IE_bit=1; //TMR1 overflow interrupt is enabled
TMR1IF_bit=0; //TMR1 overflow interrupt flag is reset
T2CON=0x04;
Delay_ms(10); //Wait until PWM settles
T1CON = 0x31;//Prescale factor is 1:8, TMR1 is turned ON T1 overflows in approx. 0.5 sec
while(1){
temp = (long)ADC_Read(2)*250/1024; //convert thermocouple voltage into deg C for 20mV/degC
if (temp > 115) RD0_bit = 0; // if actual temp is greater than reference temp, turn OFF heater
if (temp < 110) RD0_bit = 1; // turn ON heater if actual temp is less than reference temp
if(temp>50){ //the motor is started when the temperature > 50 degC
duty = (long)ADC_Read(1)*255/1024; //Convert POT value into Duty 0-255
CCPR1L = duty; // duty period is updated according to the set value from the pot
Delay_ms(10); //Wait until PWM settles
}
else CCPR1L =0; //Turn OFF the motor
if (cnt>7200) { // for 8 MHz clock, Timer overflows in 0.26 sec. For 30 mins, 7200 interrupts needed
CCPR1L=0; // Stop the motor when 30 min is elapsed
RD0_bit=0; //Turn OFF the heater
while(1);
}
}
}
void interrupt(){
TMR1IF_bit = 0;
cnt++; //Count the number of Timer overflows
}
37) Design an autopark enterance control system where the cars enter through the gate using a card
reader:
A simple card reader module is used (see the Appendix) which can be directly interfaced with
microcontroller via the UART communication terminals. When the card reader reads a card, it will send
the card number as a one byte data, via its TX terminal which is connected to the RX terminal of the
PIC16F887.
Write a MikroC program to perform the following functions:
- Initially, write card numbers on the internal EEPROM, starting from location 5 to location 105,
such that each card number is equal to 2 times its address in the EEPROM, i.e.
cardNo= 2*address
- Read the card number and check whether it has an access through the gate by comparing with
the 100 numbers which are stored in the internal EEPROM of the PIC16F887, starting from the
address location 5 of the internal EEPROM.
- When a valid card is read, the gate is opened by using a DC motor which is rotated in CW
direction. A buzzer connected to RD3 pin is used to give a beep sound to indicate that the card
is valid. The DC motor is driven by an L293 motor driver IC (see appendix) whose control
inputs IN1 and IN2 are connected to the RD0 & RD1 pins of the Pic16F887 respectively. Stop
the motor after 3 seconds. Enable pin of L293 is connected to RD2 to enable & disable L293.
- Print the number of the card on the UART serial monitor of the PC.
- A TCRT5000 optical sensor, whose output terminal is connected to the RB0 pin, is used to
detect the existence of the vehicle when the vehicle is crossing the gate barrier. The gate barrier
will not be closed while the vehicle is crossing the barrier. The gate will only be closed when
there is no vehicle above the sensor placed at the gate barrier. The DC motor is rotated in CCW
direction to close the gate. Stop the motor after 3 seconds.
C1
1uF

1 3 U?
RXD
VT52, VT100, ANSI
C1+ C1-
TXD
11 14
T1IN T1OUT
12 13 RTS
R1OUT R1IN
10 7
T2IN T2OUT Xmodem, Ymodem, Zmodem
9 8 CTS
R2OUT R2IN
2
VS+
6
VS-

C2+ C2- C4
U1 C3 1uF
1 15 4 5 MAX232 1uF
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
2 17 C2
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
U3:A RA3/AN3/VREF+/C1IN+ RC5/SDO 1uF
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
1 2 RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
74HC14 20
RD1 U2(VS)
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28 16 8 U2
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C R2
38 30 2 3
RB5/AN13/T1G RD7/P1D IN1 VSS VS OUT1
39 1k 7 6
RB6/ICSPCLK BUZ1 IN2 OUT2
40 8 1
RB7/ICSPDAT RE0/AN5 EN1
9
RE1/AN6
10
RE2/AN7
9
EN2
PIC16F887 BUZZER 10 11
IN3 OUT3
15 14
Q1 IN4 GND GND OUT4
BC237
L293D
char txt[8];
unsigned int data1, uart_rd, i=0;
void main(){
ANSEL = ANSELH = 0; // Configure AN pins as digital I/O
TRISD = 0;
PORTD = 0;
TRISB0_bit=1; //Vehicle sensor is connected to RB0 input
GIE_bit=INTE_bit=1; //Enable RB0/INT interrupt for the vehicle sensor
INTF_bit=0; //Reset INT flag
INTEDG_bit=0; //Interrupt on the falling edge at RB0
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
for (i= 5 ; i < 105; i++){
EEPROM_Write(i,2*i); // Write some data at address 2
}
while (1){
if (UART1_Data_Ready()){//If data is received from PC terminal at RX terminal of PIC,
uart_rd = UART1_Read(); // PIC reads the received data at the RX pin
for (i= 5 ; i < 105; i++){
data1 = EEPROM_Read(i); // Read data from address i
if (uart_rd==data1){
RD2_bit = 1; //L293 is enabled
RD0_bit=1; //L293 is set to rotate the DC motor in CW direction
RD1_bit=0;
RD3_bit = 1 ; //buzzer beeps
Delay_ms(3000);
RD2_bit = 0; // Buzzer is turned OFF
RD3_bit = 0; //L293 is disabled and the motor stops after 3 sec
inttostr(uart_rd,txt); // card number is converted to string to send to the PC serial port
UART1_Write_Text(" Card No");
UART1_Write_Text(txt);
}}
}}
void interrupt(){
INTF_bit= 0;
RD2_bit = 1; //L293 is enabled
RD0_bit=0; //Rotate the motor in CCW to close the gate
RD1_bit=1;
Delay_ms(3000);
RD2_bit = 0; //Disable L293 to stop the motor after 3 sec
}
AUXILIARY INFORMATION
T1CKPS<1:0>: Timer1 Input Clock
Prescale Select bits
11 = 1:8 Prescale Value
10 = 1:4 Prescale Value
01 = 1:2 Prescale Value
00 = 1:1 Prescale Value

T2CKPS<1:0>: Timer2 Clock Prescale


Select bits
00 = Prescaler is 1
01 = Prescaler is 4
1x = Prescaler is 16
CCP1CON Register
mikroC instructions

ADC_Read(), TRISB, PORTB, RB1_bit,


int temp, TMR1L, TMR1H, CCPR1, UART_Init()
UART_Write_Text() UART_Data_Ready()
UART_Read() UART_Write() EEPROM_Read();
SCHMITT TRIGGER:A
IR Motion
1 2
Sensor

Digital
74HC14 Vcc Out GND

Card
Reader

Vcc TX GND

TCRT5000

SCHMITT TRIGGER:A

1 2

74HC14

Smoke
Sensor

Digital
Vcc Out GND
16 8 U4 DC Motor is connected to the OUT1 & OUT2 terminals
2
IN1 VSS VS OUT1
3 IN1 & IN2 are the control pins which will be connected to
7 6
1
IN2 OUT2 the Pic output pins such as RD0 & RD1
EN1

9 When IN1 = 1 & IN2 = 0 , motor rotates clockwise


EN2
10 11 When IN1 = 0 & IN2 = 1 , motor rotates counterclockwise
IN3 OUT3
15 14
IN4 GND GND OUT4

L293D

You might also like