ECE 4760: Laboratory 1
Digital Capacitance Meter.
Introduction.
You will produce a digital capacitance meter (DCM) which displays the capacitance in the LCD. The DCM will
measure capacitances from 1 to 100 nF.
Procedure:
- Save TimersGCC644.c, uart.c and uart.h into your directory and build the project. This program measures the period of a square wave in two diffent ways and demonstrates that polling for a bit is inferior to using the Timer1 capture ISR for measuring time intervals. It is organized as main, one task subroutine and two ISRs. I suggest modifying this code in the assignment below so that the task updates the LCD and another task slowly blinks an LED so that you know your code is running. The example uses timer0 interrupt to maintain the time base for printing data. It uses timer1 capture ISR to measure intervals. You will need to change the ACSR definitions so that AIN1 (B.3) is compared to AIN0 (B.2), rather than the the bandgap reference.
- Connect the LCD (see below) and run the LCD test program (LCDtestGCC644.c, lcd_lib.c, lcd_lib.h). You should see a counter on line 0 and a moving dot on line 1. Note that this program uses a software delay to time the display, something you can never do if your program has to respond to external events.
The LCD library lcd_lib.c and lcd_lib.h are from Scienceprog.com.
As in lab 0, be sure to set the crystal frequency in the project options.
- Remember that a switch which is pushed reads back a logic zero..
The Liquid Crystal Display (LCD):
A 16 character, two line (16x2), LCD display be used as a numerical display. The display we are using has an industry-standard interface. A more detailed data sheet for a similar display shows the command set, but start by reading the demo code, not by reading the data sheet. There are several aspects of the display you should note:
Capacitance measurement
The approach we will use is to measure the time it takes for a RC circuit to
charge a capacitor to a given level. If R3=R4
in the schematic below then the level will be v(t1/2)=Vcc/2
. Specifically,
we will use the internal analog comparator as shown in the following
diagram to trigger a timer1 event. Since R2 will be known, we can get C because the voltage on the capacitor v(t)=Vcc(1-exp(-t/τ))
with τ=(R2)*C
.
The capacitor shown is the device you are trying to measure.
The resistor going to PortB2 should be around 100 ohms to limit current. You must choose R2
so that the capacitor charging time is not too short or too long. If it is too short you will lose measurement accuracy. It if is too long, the timer will overflow.
If you decide to print floating point numbers to the LCD you need to follow the directions in Using sprintf function for float numbers in AVR-GCC the AVRstudio directions are at the bottom of the page. The summary is: Open the Project>Project Configuration
dialog box, then go to the custom options
, then select linker options
, and then add the -Wl,-u,vfprintf -lprintf_flt
switches.
Your program will have to (in time order):
- Set PortB3 to an input.
- Drive PortB2 to zero by making it an output and wait long enough
to discharge the capacitor through 100 ohms. Clearly, to dischage to zero volts with 1% accuracy,
R2>100*(100ohms).
- Convert PortB2 to an input and start a timer. The capacitor will start
to charge toward Vcc.
- Detect when the voltage at PortB2 is greater than than the
voltage at PortB3. That is, you will have to record when the comparator
changes state. You could do this by polling the ACO bit of the ACSR and stopping the clock when ACO changes state, but a
much better way to do it is to use the timer1 input capture function set up to be triggered
by the comparator. Using input capture gives better timing accuracy and more dynamic range.
- Repeat
I suggest that you organize the program as follows:
- Timer0 compare-match ISR updates a millisceond counter to time task1.
- Timer1 capture ISR simply copies ICR1 into a variable.
- Main schedules task1 to execute about every 200 mSec..
- Task1
- Does steps 1 and 2 above
- Computes the capacitance and updates the LCD. This takes long enough that the capacitor is discharged.
- Zeros timer1 and does step 3 above.
- Exits.
- By the time that task1 executes again, the capture ISR will have executed and a new ICR1 value will be available.
Assignment
All timing must be done with interrupt-driven hardware timers and not with software wait-loops. All programs must be in C.
Write a program which will:
- The LCD should be updated every 100 mSec or so.
- An LED should blink about 1/second.
- The capacitance should be measured as quickly as possible as described above.
- The program should detect whether a capacitance is present or not and display an appropriate message if no capacitor is present.
- Formats the capacitance as an ASCII number
and prints the message
C = xxx nf
to the LCD
When you demonstrate the program to
a staff member, you should demonstrate that the capacitance is correct within the tolerance of the resistors you use.
Your written lab report should include the sections mentioned in the policy page, and :
- How you converted time to capacitance
- A heavily commented listing of your code.
Copyright Cornell University Jan 2009