ECE 4760: Laboratory 1
Digital Capacitance Meter.
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.
But first you need to set up a board, arrange jumpers, learn how to connect peripheral devices and use the compiler. You will first do a quick exercise to compile an existing program and watch the blinking lights. The LEDs on the board are the embedded programmers low-level, fast, debug tool.
The hardware you will be using to
support the MEGA-series microcontroller is a small board providing:
- A target microcontroller (mcu) with onboard flash program memory, timers, ADC, and other peripherials.
- A 5 volt, 100 mA (max) power supply.
- A 16 MHz crystal for MCU clock.
- A USB serial connection for applications.
- A separate programmer (AVRISP MkII) for the target flash memory will be used (see image below).
For the initial testing phase of this lab, connect the LEDs and pushbuttons with jumpers as shown at the right above. Note that the buttons are active low. You will need a USB cable with a type-B connector for serial communication. Another USB cable attaches the programmer to the PC. The left image shows programming, LED and serial jumpers. The programming jumper is partly hidden to the left of the programmer cable plug. The two serial jumpers are to the left of the SOIC device. The LED jumper is below and to the right of the green LED.
Images of the target board from different angles without jumpers mounted are shown below.
The six-pin programming header is visible, as well as the 36 pin white-board header.
Software you will use is freely downloadable and consists of:
General hardware Procedures
- The USB connection is for serial communication between the running program and the PC, which will be running PuTTY. Set up PuTTY for 9600 baud, no parity, 1 stop-bit, no flow-control.
In the PuTTY config window, choose serial connection, then click serial in the left hand panel and set the parameters. Connect PuTTY to whatever serial port the USB dongle configures. Use
Control Panel...System...Hardware Tab...Device Manager Button...+Ports to find out which serial port is connected to the USB dongle.
- Put all files on your
Z drive! Be sure to put all your files there and to back up daily!.
You can also use a flash drive.
Do not creat a project on the local PC disk drives!
These drives are wiped when you logout or if the system crashes.
- There should be a shortcut to AVRstudio on the desktop or start menu, or search for
- After you define a new project, you can add a C source file and edit it.
This first example code is just for testing the hardware setup (shown above) and to learn how to use AVR studio.
Later you will use a different program to measure timer intervals, which is the basis for lab 1.
- Save this example code onto your
z drive. This program uses the circuitry shown above (two buttons, two LEDs).
You will also need uart.c and uart.h in the same folder.
This program blinks LEDs, records time in eeprom, and
responds to buttons. It is organized as three task subroutines. You will
use this code to test your hardware setup.
- In the AVRstudio
Project menu choose
Project Wizard. When the dialog box
- In the new dialog box choose a GCC project, give the project a name, and indicate a source file to use. Choose a location on your Z drive to store the project.
- In the next dialog box choose to debug with
AVR simulator and choose
ATmega1284p, then press
- In the menu item
Project-> Configuration Options -> General -> Frequency enter 16000000 because the crystal frequency is 16 MHz.
A better way of setting the frequency is to always insert
#define F_CPU 16000000UL as the first line of your program.
- In the menu item
Project-> Configuration Options -> Libraries click on
libm.a, then click on
Add Library, and press
Doing this fixes a floating point error which will you will not notice until Lab 2.
- Identify the code you downloaded as a source file by right-clicking the
source files item in the left panel. Also add uart.c.
- Choose the menu item
Build from the
Build menu. A message window will open to tell you if
there are errors in the code.
- If the compile is successful, you should be
able to download the program to the board and see some blinking
To download, select the
Tools>Program AVR>Autoconnect menu item. One of two dialog boxes will open. You may be asked to choose a programming device. If so, choose
AVRISPmkII. Otherwise the main programmer dialog box will open. In the main programmer dialog box:
- In the
Main tab, set the ISP frequency (
Settings... dropdown) to 125 Khz, then press
You can try using a higher speed, but always be prepared to drop back to the low speed to check the fuze settings in step 3 below.
- Make sure the device is
- Always check Mega1284 fuze settings: (Fuze tutorial)
- Go to the
Fuses tab in the programmer window and set the
SUT_CLKSEL fuse to:
Ext crystal osc 8- MHz; startup time: 16k clk+65 mSec.
- Uncheck the
- Uncheck the
JTAGEN box and answer YES in the confirming dialog. (If you leave the box checked, PORTC does not work correctly).
- In the
Program Tab, Flash box, select the
hex file generated by the compiler.
The file will be in the
project folder>default folder. Press the
If the program does not download to the chip, call a TA.
Note that the hex file name is NOT updated for you and will default to the last project compiled on the computer, which probably will not exist..
When the program is running and blinking lights, you should be able to press button 7 to change the blinking rate. You should have serial communication to the PC and the program should be printing sequential numbers at about 1 Hz. At this point you can move on to the actual lab exercise below.
- Save TimersGCC644.c, uart.c and uart.h into your directory, add uart.c to the source file list, and build the project. Connect B.3 to D.7 to hook the squarewave output to the comparator input. 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 (LCDtestGCC644v2.c, lcd_lib.c, lcd_lib.h). You should see a counter on line 0 and a moving dot on line 1.
The LCD library lcd_lib.c and lcd_lib.h are from Scienceprog.com.
Be sure to set the crystal frequency in the project options.
[Note that the linked version of lcd_lib.c above is modified from the scienceprog version. Every instance of
_delay_ms(1) was replaced with
you may need to disconnect the programmer if the LCD scrolls uncontrollably.]
- Remember that a switch which is pushed reads back a logic zero.
- Timing of all functions in this lab, and every exercise in this course will be handled by interrupt-driven counters, not by software wait-loops. This will be enforced because wait-loops are hard to debug and tend to limit multitasking. Specifically, you may not use the delay library routine
delay_us will be acceptable when you need to produce delays on the order of a few microseconds.
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:
- Connecting the power backwards may destroy it.
Always check the polarity before connecting the display.
- The 14 pin header is on a corner of the display. LCD pin 1 is usually closest to the edge of the pc-board, but is always marked.
The connection pattern is shown below.
Note that pins 7 to 10 on the LCD are not connected and that MCU port pin C3 is not used.
|3 contrast **
||look to the right >>>
** contrast is connected to the wiper (connection 2, see below) of a 10K trimpot.
Vcc goes to connection 1of the trimpot, and gnd goes to 3 of the trimpot.
Adjust the LCD contrast using a small screwdriver to turn the trimpot.
Trimpot bottom view:
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
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
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, but NOTE that one library is left out. The correct summary is:
Project>Project Configuration dialog box, then go to the
custom options , then select
and then add the
-Wl,-u,vfprintf -lprintf_flt -lm and
-Wl,-u,vfscanf -lscanf_flt -lm 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,
- 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.
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..
- 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.
- By the time that task1 executes again, the capture ISR will have executed and a new ICR1 value will be available.
You can connect the oscilloscope to the computer with a USB cable (type-B connector) attached to the back of the oscilloscope (not the type-A connector on the front).
To use the Tektronix software on the PC:
- Search for
OpenChoice Desktop in the start menu, and start the program.
- When the main panel appears, choose
- In the select dialog box, choose the
USB device, and click
- Back in the main panel, click
- Copy or save the image or data to your lab report.
Timing of all functions in this lab, and every exercise in this course will be handled by interrupt-driven counters, not by software wait-loops. This will be enforced because wait-loops are hard to debug and tend to limit multitasking.
Write a C program which will:
- The LCD should be updated every 200 mSec or so.
- An LED should blink about 1/second.
- The capacitance should be measured as quickly as possible as described above.
- The range of capacitances to be measured is 1 nf to 100 nf.
- The program should detect whether a capacitance is present or not and display an appropriate message if no capacitor is present.
- If present, format 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 program should not need to be
reset during the demo.
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.
- A screen capture of the oscilloscope showing the charge/discharge waveform.
- Explain how you could make the meter autoranging.
Copyright Cornell University
September 21, 2012