Professional Documents
Culture Documents
Lab 8
3581450
Abstract
The purpose of this lab was to create a Digital Voltmeter (DMV) and transmit the
data through a serial port to a computer. The power supply was used to supply the
voltage to be measured. The voltage from the power supply was analog so an analog to
digital conversion was needed. The analog to digital conversion result was then used to
calculate the voltage and sent to a computer through a serial port to be displayed on the
computer monitor using 4 decimal places.
Introduction
This lab requires an application that will measure the voltage supplied by a power
supply and display it on a computer monitor via the use of a serial port. To solve this
problem a series of steps needed to be taken. The first thing was to set up several
registers. These registers included ADCON0, ADCON1, TXSTA, RCSTA, and SPBRG.
These registers were needed in order to convert the analog signal and output the correct
result at the correct rate to the computer monitor. Also data direction needed to be set up
so that the proper inputs and outputs could be used. The next thing was to determine how
to convert the analog to digital conversion result to a meaningful voltage. The analog to
digital converter produces a 12 bit result however the most significant two bits are always
zero. This makes the range of hex values are from 0x00 to 0x400, or in decimal from 0 to
1023. Using this and the fact that the voltage supplied can only range from 0 volts to 5
volts an equation was created that converted the binary number from the analog to digital
conversion to a voltage value. This process will be explained in the main body. The next
thing was to write the program. The first part of this stage was to read the AD result 128
times and keep a running total of all the conversions. The reason the AD needed to be
averaged is because a potentiometer was used to vary the voltage read by the
microcontroller. The average of the running total was taken by dividing by 128.
However before the result could be divided it needed to be multiplied by 1000 so that the
value would not be truncated. This value was then used to convert to a voltage. This will
also be explained in more detail in the main body. This converted value was then put into
a character array. Multiplying the result by 1000 as stated above gave a decimal number
with for decimal digits. Each one of these digits was stored in the proper index of the
character array. The most significant digit was stored in the zero element. The next digit
was stored in the 2nd element because the first element was a decimal point. This
continued until all decimal numbers were in the array. This array was 6 elements long, 4
for the decimal numbers, 1 for the decimal point, and the last for the carriage return.
Using an array like this allowed values such as 2.343 and 4.893 to be displayed. This
array was outputted to the computer through the use of a for loop. Each element was a
character so it needed to be sent individually to the computer via the serial port. Lastly
the AD conversion was started again and the process began all over again.
Main Body
Subroutines
In this program does not have multiple subroutines, in fact it only has the main
function. To better explain the code I will split it up into 4 parts: setting up of registers,
reading the AD conversion, converting the AD result and storing it into an array, and
sending the converted value to the computer.
Since this lab requires the use of the analog to digital converter and the USART
several registers needed to be set up. The registers to set up the AD conversion were
ADCON0 and ADCON1. These set up the AD with the correct processing speed, select
which pin was the analog input, choose the voltage references, set up the pin as an analog
input, and turn on the converter. Next the data direction registers needed to be set up.
Pin AN0 that has the analog input needed to be configured as input by writing a 1 to the
appropriate bit of the TRISA register. Also since the USART is needed PORTC pin 7 was
needed to be an input by writing a 1 to TRISC pin 7 and PORTC pin 6 needed to be an
output by writing a 0 to TRISC pin 6. Lastly since serial communication was used the
registers dealing with data transmission to the computer needed to be set up. The first is
the transmit status and control register (TXSTA). This was used to select asynchronous
mode, 8 bit transmission, and to determine when the data has been transmitted. The next
register was the receive status control register (RCSTA). This register was only needed
to enable the port that the serial communication is on. Lastly a value of 64 needed to be
written to SPBRG so that a baud rate of 9600 was used.
Next the running total of 128 AD conversions needed to be done. This was done
simply within an if statement that would execute 128 times. Each time it would start the
AD conversion, wait for it to be done then add the result to a variable called ADresult.
After the if statement has been executed 128 times ADresult contains the sum of all the
individual AD conversions.
Next this result was converted into a meaningful value as described in the section,
Converting from AD result to meaningful voltage. As stated above the AD result was
converted to a meaningful value that represents a voltage. This value is 4 digits long.
This number needed to be converted to a decimal number however integer arithmetic
does not have decimal places, it truncates the number. This is why the result was
multiplied by 1000 so that a not so obvious method could by used to convert the number.
The process would modulo the number with 10 and store that result in the 4th element of
the array as a character. That result was then divided by 10 so that it was only 3 digits
long. Again the operation modulo 10 was performed and stored that result in the 3rd
element of the character array. This process was repeated to more times where the next
number was stored in the 2nd element of the array and the following digit was stored in
the 0th element of the array. The reason it was not stored in the 1st element is because this
is where the decimal point occurs. The result is that it converted a 4 decimal long
number to a decimal number with decimal point 3 places from the left (i.e. 4356 to
4.356).
Lastly the converted value needed to be sent to the computer through the serial
port. To do this each character element of the array was written to TXREG 1 at a time.
Before a new character could be sent the previous transmission needed to be complete.
This was done by waiting for the transmit shift register to be empty. This was done in a
for loop that would execute 6 times sending the 0th element first and the 5th element last,
the 5th element being a carriage return.
Results
Using the potentiometer to change the voltage supplied to the microcontroller it
was found that the range displayed on the computer was from zero to five volts which is
correct because that is the range of the power supply. It was also found that the number
displayed would constantly update as the potentiometer was turned up or down (by up or
down I mean allowing a higher voltage or only allowing a lower voltage to be read by the
microcontroller). It was also found that the result displayed was 4 digits long with 3
decimal places to the right of the decimal point which was the desired accuracy.
1) Using the simulator it was found that it outputs a voltage value to the computer
every 6.4189 milliseconds. This is a sampling rate of 1/(6.4189*10^-3 s) which equals a
frequency of 156 Hz.
2) To find out what digital 10-bit value an analog input of 2.3 volts corresponds to
the equation N=Cx needs to be used. As stated earlier C is 1023/5 and x = 2.3 volts.
Plugging these values in N=(1023/5)(2.3) which equals 470 truncated. Converting this to
binary it equals 111010110.
void main(void)
{
char array[6]={'0','.','0','0','0',0x0D};
unsigned char temp=0;
unsigned long int ADresult=0;
unsigned long int average,send;
char i;
while(1)
{
}
}
}