
- •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 8: C Pointers and Arrays
This is a perfectly good function, but it requires that the user never ask for more bytes than the size of the pBuffer array. What if we set indexps = 50? The LoadEEPROM will fill the Name[STRLENGHT] array and the 25 bytes of RAM that follow the array. Since the second 25 bytes wasn’t allocated to this function we have no way of knowing what’s supposed to be stored there, but we overwrite it anyway and almost certainly cause havoc.
It would be good programming practice to add a line that checked the array size and the number of bytes before calling the LoadEEPROM function, and if there’s a problem generate an error.
if(NAMESIZE >= indexps){
// Load name from EEPROM
LoadEEPROM(Name, indexps, EEPROM_START + 1);
}
else
ErrorMessage(“LoadEEPROM error: number of bytes requested > array size”);
But we are smart and we’d never make such a dumb error, so why bother adding the extra code that only slows things down and increases the code size and is a pain to type? The obvious answer is that the mistakes we make will often be painfully dumb.
FIFOs and LIFOs: Stacks and Queues (Circular Buffers)
Stacks
Assembly language programmers frequently use the stack when calling subroutines and running algorithms.
Stacks are like those piles of trays in cafeterias, we take trays off the top and the dishwasher piles them back on the top. The top trays are usually wet and the bottom trays never get used. It is important to us that the we never try to use the tray below the bottom tray because it doesn’t exist, the analogy breaks down and we have a blown stack, as shown earlier when we discussed how C uses a stack when calling functions. Sometimes you’ll see ‘fifo’ to refer to these kinds of
167
Chapter 8: C Pointers and Arrays
stacks, fifo stands for ‘first in first out’. In control applications it is sometimes convenient to have fifos, private stacks, to manipulate data.
#define STACKSIZE 100
unsigned char myStack[STACKSIZE]; // create a data stack char stackCount = 0;
unsigned char myValue = 0; // create a byte variable
//Do some controlling
//push a byte on the stack
if (stackCount++ < STACKSIZE) // don’t blow your stack *myStack++ = myValue;
else
error(“You almost blew your stack! - overflow”);
//Do some more controlling
//pull a byte off the stack
if(stackCount-- > 0) //don’t blow itvin the other directon myValue = *--myStack;
else
error(“You almost blew your stack! - underflow”);
Queues (Circular Buffers)
If stacks are like lunchroom trays, then queues are like the line of students waiting to get a tray. The last one in line is the last one to get a tray. A circular buffer is more like a game of hot potato where the students form a circle and pass a hot pototo from one to the next and it keeps circulating indefinitely around. The hot potato in our analogy is actually the pointer to the next address in the queue. For real students it would probably be a joint or a bottle of cheap alcohol.
#define QUEUESIZE 100 |
|
unsigned char myQueue[QUEUESIZE]; // |
create a queue |
unsigned char *nextInQueue; //define |
a pointer to an unsigned char |
char queueCount = 0; |
a byte variable |
unsigned char myValue = 0; // create |
|
NextInQue = myQueue; // set pointer |
|
// Do some controlling |
|
168