In this article, we have come up with a new PIC micro controller project. Our author Mithun has created a Digital Voltmeter Circuit using PIC16F73A and multiplexed 7 segment displays. The circuit is well explained with diagrams and the source code (written in Embedded C language) is available for download. If you have any doubts while implementing this project, please feel free to ask in comments.

Note:- You may also like to read our Digital Voltmeter using 8051 created a while before. In this circuit, we have created a voltmeter using AT89S51. In addition you will learn about interfacing 7 segment displays and ADC to 8051 micro controller.

How a Multiplexed Seven Segment Display Works?

First of all, we need to understand how a multiplexed 7-segment display works. When 4 segment displays are connected as a single segment, the data bus of all the segments comes in parallel and the enable pin is different for all segments. In this way, we control the individual segments. Let’s see the image below:
Here data is send thorough ‘a, b, c, d, e, f, g’ lines and ‘s1, s2, s3, s4’ are the enable lines. When data is send via the data bus and s1 is made high,the data will be shown in the first segment. Similarly when s2 is made high, data will be shown in the second segment. This is how multiplexed seven segment display works. But now the question is how can we show different data in these 4 segments at a time? Remember, human eyes can’t find the difference within 10ms. I hope you already know about the persistence of vision. If we can change the data with corresponding enable pins of all these 4 segments within 10ms, our eyes will see a set of 4 digits in this segment. In other words, we will do the following within 10ms to display 1234. Feed data bus with 1 and set S1 high. Feed data bus with 2, turn S1 low and set S2 high. Feed data bus with 3, turn S2 low and set S3 high. Feed data bus with 4, turn S3 low and set S4 high. All this has to happen with in 10ms. Finally the process repeats to keep the display stable.

Let’s do the program:

First of all we need to write codes for the correct timing, so that we can send different data at different time by keeping high corresponding enable pin of the segment. So we need to make use of the timer interrupt.

The timer interrupt setting is given below.
Lets come to the rest of the program. Next step of program is port initialization. You can initialize ports with the following code segment.
Next step is setting the other initial values. The following code segment initializes all necessary variables.
Final set of initialization is for the ADC channel inside PIC, which is as given below.

Now we have completed all the initialization steps and they should be called inside main function void main(). In coming steps, we will be creating other important sections of the program like the loop to read input. Read the code segments given inside the while(1) loop.

Do you get an idea of what is happening here? In the first line, we are initializing the ADC channel0 to take the input analog signal. Second line is to take the signal, convert and store it in adc register. The third line of code, tlong = (float)adc_rd0*1.9607843 is in fact the conversion of the adc output to millivolts. The multiplication factor 1.9607843 is obtained from equation (5/255)X100; where 5= VDD, 255 for 8bit and 100 to reduce fractional error.

In the code segment you see, the converted value in millivolts is saved to a variable ‘number’. Now, what is ‘number’ here? To know what is ‘number’ , we need to see what the display() sub routine does.
By analyzing the code segment, you might have understood that ‘number’ is used to extract the data. So ‘number’ is a temporary variable used to store the data through out the display sub routine. Each extracted digit is passed through a subroutine named ‘mask’. This ‘mask’ subroutine is actually a LUT (look up table) which picks the exact seven segment display pattern for the corresponding digit. The ‘mask’ subroutine is given below.

Summary of the Project

I prefer you look the circuit diagram in detail now. Microcontroller fetches the analog signal through the AN0 pin of PIC16F73. The built in ADC of PIC16F73 converts the analog input to its digital value. A fractional conversion is applied to this digital data using an equation and the data is converted to millivolts. Each digit is extracted one by one using the sub routine void display(). The extracted digit is matched and the corresponding seven segment pattern is fetched from the LUT written inside the mask subroutine. The data from LUT is then passed to data bus of the multiplexed 7 segment display using pins 21 to 28 of PIC16F73. The enable pins are connected the micro controller at pins 11, 12, 13 & 14. Finally different data are sent to different segment displays by alternately switching the enable pins within 10 ms. This way our eyes see just a 4 digits number. So here is our full project.

Source Code

We have given the complete source code of this project, digital voltmeter using PIC micro controller for free download. You can download the code using the link given below.

We recommend:

Comments

Niki

June 22, 2016

Hello,
when i compile the code it gives me errors in the interrupt and display functions. It says conflicting declarations for variables PORTB, PORTC, TMR0 and others. Could you help me please?
Im am using Hi-Tech C compiler.
Thank you.