- •Chapter 1: Introduction
- •Goals
- •Chapter 2: Quick Start Guide
- •Software
- •WinAVR – Oh, Whenever…
- •Programmers Notepad
- •AVRStudio – FREE and darn well worth it.
- •Br@y++ Terminal:
- •Hardware
- •Constructing Your Development Platform
- •Blinking LEDs – Your First C Program
- •Write it in Programmers Notepad
- •Download to the Butterfly with AVRStudio
- •Blinky Goes Live
- •Simulation with AVRStudio
- •GOOD GRIEF!
- •Comments
- •Include Files
- •Expressions, Statements, and Blocks
- •Operators
- •Flow Control
- •Functions
- •The Main() Thing
- •Chapter 4: C Types, Operators, and Expressions
- •Data Types and Sizes
- •Seen on a shirt at a Robothon event:
- •Bits
- •Bytes
- •The long and short of it
- •Variable Names
- •Constants
- •Declarations
- •Arithmetic Operators
- •Relational and Logical Operators
- •Bitwise Operators
- •Testing Bits
- •Assignment Operators and Expressions
- •Conditional Expressions
- •Precedence and Order of Evaluation
- •Projects
- •Port Input and Output
- •Cylon Eye Speed and Polarity Control
- •Chapter 5: C Control Flow
- •Statements and Blocks
- •If-Else and Else-If
- •Switch
- •Loops – While, For and Do-while
- •Break and Continue
- •Goto and Labels
- •A few practical examples: strlen, atoi, itoa, reverse
- •Chapter 6: C Functions and Program Structures
- •Function Basics
- •Returns
- •Variables External, Static, and Register
- •Scope
- •Headers
- •Blocks
- •Initialization
- •Recursion
- •Preprocessor
- •Macro Substitution
- •Conditional Inclusion
- •Projects
- •Is anybody out there? Communicating with a PC
- •Demonstrator
- •PC_Comm
- •Using CommDemo:
- •Chapter 7: Microcontroller Interrupts and Timers
- •Interrupts
- •Projects
- •Grab your joystick – and test your interrupts
- •Using joystick
- •Timers/Counters
- •Calibrating the Butterfly oscillator:
- •OSCCAL_calibration() function – detailed explanation
- •ALL THIS AND WE HAVEN’T EVEN STARTED CALIBRATING YET!
- •Projects
- •Precision Blinking
- •Using Precision Blinking:
- •Pulse Width Modulation – LED Brightness Control
- •Pulse Width Modulation - Motor Speed Control
- •Speedometer
- •Chapter 8: C Pointers and Arrays
- •Addresses of variables
- •Function Arguments
- •Arrays
- •FIFOs and LIFOs: Stacks and Queues (Circular Buffers)
- •Stacks
- •Queues (Circular Buffers)
- •Function Pointers
- •Complex Pointer and Array Algorithms
- •Projects
- •Messenger
- •Arrays in RAM and ROM
- •Does anybody know what time it is? A Real Time Clock.
- •A one second interrupt
- •Converting Computer Time to Human Readable Time
- •The Real Timer Clock Software
- •Music to my ears. “Play it again Sam.”
- •More on pointers to arrays
- •Setting the frequency
- •Setting the duration
- •An example song array – Fur Elise
- •Using the Piezo-element to make sound
- •Initializing the Timer1 for PWM to the piezo-element.
- •Generating the tone using PWM from Timer1
- •Using the Timer0 interrupt to play a tune
- •Chapter 9 – Digital Meets Analog – ADC and DAC
- •But First - A Debugging Tale
- •Analog to Digital Conversion
- •What is Analog to Digital Conversion?
- •Analog to Digital Conversion by Successive Approximation
- •Analog to Digital Conversion with the ATMEGA169
- •Starting a Conversion
- •Conversion Timing
- •Changing Channels
- •Digital Noise Reduction
- •Conditioning the Analog Input Signal
- •Accuracy
- •Projects
- •Initializing the ADC
- •Reading the ADC
- •Light Meter
- •Temperature Meter
- •The @#%#&*#!!!! Volt Meter
- •Using ADC
- •DAC and ADC - Function Generator / Digital Oscilloscope
- •Chapter 10: C Structures
- •Structure Basics
- •Structures and Functions
- •Structure Arrays
- •Typedef
- •Unions
- •Bit-fields
- •Bit-Fields the C-way
- •Bit-fields the masking-way
- •Projects
- •Finite State Machine
- •Chapter 11 The Butterfly LCD
- •PC to LCD test program
- •Conclusion
- •Appendix 1: Project Kits
- •Data I/O
- •PWM Motor Control
- •Appendix 2: Soldering Tutorial
- •Appendix 3: Debugging Tale
- •Appendix 4: ASCII Table
- •Appendix 5: Decimal, Hexadecimal, and Binary
- •Appendix 6: Motor Speed Control Wheel
- •Appendix 7: HyperTerminal
- •Index
Chapter 7: Microcontroller Interrupts and Timers
Calibrating the Butterfly oscillator:
We first used the OSCCAL_calibration() function in the PC_Comm project, claiming that we would explain it later. Well, it’s later and, wow, it’s time to understand how it works.
If you try to tell time with the uncalibrated oscillator built into the ATmega169, you can expect to gain or lose a couple of hours a day. These oscillators produce very precise pulse trains, but due to manufacturing variables, the pulse timing varies from chip to chip and do not correlate to ‘real’ time. Real time is determined by the National Bureau of Standards and references an atomic clock. To calibrate the built-in oscillator to real time requires an external crystal that has been precisely trimmed to pulse in time with the NBS clock. The Butterfly uses an external 32.768 kHz watch crystal to calibrate the oscillator to run at 8 MHz. Watch crystals are accurate, cheap, and make keeping human time easy (‘easy’ being another relative term).
We can get an accurate count of a time period by counting pulses from the watch crystal. For instance if we count 32768 pulses we know that one second has passed. We use a shorter known good period to calibrate the internal oscillator by setting the oscillator to generate x pulses in the known good time period. Remember that the oscillator is running at about 8 MHz, so we are going to get a lot more counts from it than we will get from the watch crystal. If we count 32768 pulses from the watch crystal and 8 million pulses from the oscillator in the same period, we know the 8 MHz is accurate. That is, we get 8 million counts from the oscillator in the same period we get 32768 counts (one second) from the crystal meaning the oscillator is running at exactly 8 million pulses per second. But we will actually use a much shorter period and have smaller counts. If the oscillator count is too small for the period we change the value in a register to speed it up, and if it is too large we change the register to slow it down. We do this in a loop to keep bracketing the speed until it gets as accurate as we can make it. Sounds easy, but as you’ll quickly see, it is a real pain just to get the registers all set up properly.
In this section we will learn how the Butterfly oscillator is calibrated. This is presented in two sections, the first shows the OSCCAL_calibration function, and the second gives a detailed explanation.
121
Chapter 7: Microcontroller Interrupts and Timers
OSCCAL_calibration() function – the code:
/*******************************************************************
*
* Function name : OSCCAL_calibration
* |
None |
* Returns : |
|
* |
|
*Parameters : None
*Purpose : Calibrate the internal OSCCAL byte, using the external
* |
32,768 kHz crystal as reference |
|
* |
|
|
*******************************************************************/ |
||
void OSCCAL_calibration(void) |
||
{ |
|
|
unsigned char calibrate = FALSE; |
||
int temp; |
|
|
unsigned char tempL; |
|
|
CLKPR = (1<<CLKPCE); |
// set Clock Prescaler Change Enable |
|
// set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz |
||
CLKPR = (1<<CLKPS1) |
| (1<<CLKPS0); |
|
TIMSK2 = 0; |
//disable OCIE2A and TOIE2 |
|
ASSR = |
(1<<AS2); |
//select asynchronous operation of timer2 |
|
|
(32,768kHz) |
OCR2A = 200; |
// set timer2 compare value |
|
TIMSK0 = 0; |
// delete any interrupt sources |
|
TCCR1B = (1<<CS10); |
// start timer1 with no prescaling |
|
TCCR2A = (1<<CS20); |
// start timer2 with no prescaling |
//wait for TCN2UB and TCR2UB to clear
while((ASSR & 0x01) | (ASSR |
& 0x04)); |
|
Delay(1000); |
// wait for |
external crystal to stabilise |
while(!calibrate)
{
cli(); // mt __disable_interrupt(); // disable global interrupt
TIFR1 |
= |
0xFF; |
// |
delete |
TIFR1 |
flags |
TIFR2 |
= |
0xFF; |
// |
delete |
TIFR2 |
flags |
122