DesignSpark Electrical Logolinkedin
Menu Search
Ask a Question


This project presents the detailed design and programming of a shooting range game using the old fashioned multipurpose PIC16F877A microcontroller from Microchip®.

Apart from passing the microcontroller’s course, the main objective of this project was to make use of the microcontroller Microchip® PIC16F877A, and all of the different modules that we can connect, to create an example of a target range.

The explanation of the project has been divided into two main parts:

  • HARDWARE: First of all, we built a tower with two servo motors in order to give our “gun” two degrees of freedom (axis X and Y). The “gun” selected was a laser placed at the top of the tower. Everything was moved thanks to a joystick connected to the same board. Finally, we placed four LDR resistances on a board, in order to work as the targets of our shooting range. A LCD screen was used as well to indicate the number of the target to be lased.
    • All the electronic control of the project is carried out by the microcontroller Microchip® PIC16F877A. This presents the core of the whole system in which we can connect all the different modules explained above.
    • Regarding the programming of the microcontroller, MPLAB IDE (Integrated Development Environment) has been used. Everything was written in C due to the simplicity of it, compared with the assembler language.
    • Finally, all the program was simulated and emulated by the debugger MPLAB - ICD2 and recorded into the microcontroller.

All the hardware elements as well as the technical programming parts of the project will be explained below. We had to make use of a D/A converter as well as and A/D converter. Besides a comparator was needed in order to decide the moment when the laser aimed the target.



We made use of two servo motors in order to create the movable tower. 

The way the servo motors work is based on a PWM signal. As shown in the next figure, a 20 ms period was chosen for both signals. Depending on the duty cycle, the motor will move to any position between 0 and 180 degrees. The limits of this range vary a lot depending on the specific servo motor. After some trials, we chose our limited duty cycle to be 0.25 and 0.31.


A laser was used as the “gun” of our shooting range.


The joystick enables us to subdivide all the movements into two different axes. As the PIC16F877A only has one analog to digital converter, we will have to multiplex both movements. Furthermore, by pressing the button of the joystick the laser was turned on and off.


They are characterized by being able to change its resistance when the light strikes the surface of it. If they are in a voltage divider, we can study how the voltage changes with the intensity of the light. In this way, we obtained the effects of striking the laser into the resistances.


We will split the way this program works in three stages. In order to show the functionality much better, we will use some block diagrams. They present all the interruptions as well as the inputs and outputs pins.

First of all, let’s show the inputs/outputs in the following table:





Port A


Analog input

Analog comparator module - target 1


Analog comparator module - target 2


Analog comparator module - target 3


Analog comparator module - target 4


Read X axis of the potentiometer and digital conversion with the A/D converter.

Port E


Analog input

Read Y axis of the potentiometer and digital conversion with the A/D converter.

Port B


Digital input

Turn the laser on and off with the button of the joystick


PWM output

Servo’s control – X axis


Servo’s control – Y axis


Digital output

Digital output that powers on the laser

An electronic connection scheme will be shown below:



Both elements were used to read the data provided by the joystick.


Due to the use of two servos (in order to provide two degrees of freedom), we were forced to read two different analog signals, one for each axis. As explained above, the period of the PWM signals selected has been 20 ms (TIMER1). Due to this reason, as the TIMER0 determines the beginning and the end of each conversion, it was stabilised with a temporization of 10 ms. This helped us make two A/D conversions before updating the duty cycle of the PWM signal.

Temporization = 10 ms = (28 - NTMR0) · P · 1 µs

The pre divisor used was P=64 which implies a value of TMR0 = 99.75 ≈ 100. 


While the TIMER0 was used just to limit the time of the conversions, the A/D converter transforms our analog input signals of the potentiometers of the joystick, into some digital values.

This module requires 4 processes to operate, sampling, retention, quantification and coding. However, the acquisition and conversion times must be considered, since a bad selection of them can lead to a malfunction of the module.

The acquisition time requires a 40 µs wait after an A/D conversion or after the next channel is selected. This is due to the capacitor charge used in the retention process.

On the other hand, the conversion time specifies the necessary frequency of the converter, depending on the oscillator. Since the PIC16F877A microprocessor has a 4MHz oscillator, we were looking for the largest fraction of the frequency by comparing it with the condition of the sampling frequency. 

Ts ≥ TDIG = TACQ + TCONV   →   TAD > 1.6 µs

FOSC = 4 MHz   →   4 MHz/8 = 500 kHz

1/1.6µs = 625 kHz   →   500 kHz < 625 kHz

As we can see above, when we select and weight part of the frequency of oscillation, the conditions is fulfilled.


We will use the TIMER1 in conjunction with the CCP (capture-compare-PWM) module to control the servomotors by generating a PWM signal. The PIC16F877A has two modules CCP1 and CCP2 which will share the same time base (TIMER1).

The way in which the PWM signal starts is by setting the bits RB1 and RB2 to 1 when the interruption, due to the overflow of TIMER1, occurs. When the result of the comparison of the CCP1 module is positive, the output RB1 is set to 0. In the same way, when the comparison of the CCP2 is positive, it is RB2 which is set to 0.

Thus, we can control the frequency of the PWM signal with the initial value of TIMER1 and its pre-divisor. Besides, the duty cycle, which determines the position of the servo, is controlled with the value entered in the CCPR register of the corresponding CCP module. This value is updated based on the desired position.



The D/A converter was used in order to create a voltage reference of 2.65 V. Thanks to the analog comparator we can compare this value with the one of the LDR resistance. (they act as the targets of the field).

We use a potentiometer and an LDR resistance for each target in order to make a voltage divisor between VCC (5V) and GND (0V). When the laser points at one of the targets the resistance decreases as well as the voltage on it. This is compared with 2.65 V and, whenever it is lower, the word “Acierto” will appear on the LCD screen.

It’s important to mention (as it can be seen in the image of the block diagram) that the analog comparator only works with two inputs at the same time (it compares both of them). These inputs are RA0 and RA1 when CIS=0 (of the register CMCON) or RA2 and RA3 when this bit is equal to 1. The next table shows the relationship between the target-pin-CIS that we have followed:





Target 1




Target 2




Target 3




Target 4





Where RB0 corresponds with the button of the joystick.


Finally, we tested our device as it can be seen in the video and to our joy and pride it really worked very well. We had been able to use in a single project the A/D and D/A converters, analog comparators, timers, interrupts, and capture/compare/PWM peripheral modules that include the old fashioned multipurpose PIC16F877A microcontroller.

Aldaz has not written a bio yet…