- •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 10: C Structures
Unions
A union provides a way to have a type that may be of different sizes depending on the circumstances of its use.
We use a union in prgmspacehlp.h to store a float or an int in the same program memory:
union
{
int i[2]; // uint16_t float f;
} u;
Bit-fields
ANSI C defines bit-fields as a member of a structure or union that is defined to be a cluster of bits. This cluster can be a single bit, as would be used for a flag, or a 4-bit nibble, or any number of bits you might want to define. These fields can be very useful, but unfortunately, in many microcontrollers, these bit-fields slow things down (the compiler promotes bit to larger data types) so for efficiency sake, bits are best dealt with using bit masking, which compiles to faster and smaller assembly code. Bit masking simply uses a constant to define the position of a bit in a byte and allows you to read or write only that bit using the bitwise operators. We will look at the C-way, since we are learning C, then the mask-way since we want to be as efficient as possible.
Bit-Fields the C-way
In our examples above we have often declared an object as an unsigned char when that object could only have two values: TRUE or FALSE. Using bit-fields we can declare eight similar variables in a single unsigned char (note – not true for WinAVR, which promotes them to eight bytes).
We could define:
unsigned char calibrate = FALSE;
247
Chapter 10: C Structures
to control a loop:
while(!calibrate) { // do something while calibrate == FALSE};
which runs as long as calibrate equals FALSE. We could have used:
struct {
unsigned int calibrate : 1; unsigned int this : 1; unsigned int that : 1; unsigned int the : 1; unsigned int other : 1; unsigned int tobe: 1; unsigned int or!tobe : 1; unsigned int hello : 1;
} flags;
Setting aside 8 flags in the space formerly used by calibrate. Now we control the loop:
while(!flags.calibrate)
That is, we could have done this in an ideal world. In the real world, our compiler would allow us to use the above syntax, but would assign 8 bytes to do the job. K&R notes: “Almost everything about fields is implementation dependent.”
Bit-fields the masking-way
This is mostly a review of stuff presented with the bitwise operator section, but reviews are good. Let’s look at a bit-masking example from OSCCAL.C:
We define an alias name for the Timer/Counter 2 Interrupt Flag Register:
#define TIFR2 _SFR_IO8(0x17)
Noting that the _SFR_IO8(0x17) is itself an alias defined elsewhere, but eventually is aliased to a specific register address on our ATMEGA169.
We next define two ‘bit-fields’ in the TIFR2 register;
248
Chapter 10: C Structures
#define |
OCF2A |
1 |
#define |
TOV2 |
0 |
Next we write a function that causes our code to wait for the timer2 compare flag, OCF2A, which is bit one of the Timer/Counter2 Interrupt Flag Register:
while ( !(TIFR2 && (1<<OCF2A)) );// wait for timer2 compareflag
So this usage will do the same as a bit-field, but with greater efficiency.
Let’s look at another example where we assign Port B to a ‘bit-field structure’ without using bit-fields or structures. First we get the address of the Port B registers from io169.h which also has defines for each bit.
/* Port B */ |
_SFR_IO8(0x03) |
#define PINB |
|
#define DDRB |
_SFR_IO8(0x04) |
#define PORTB |
_SFR_IO8(0x05) |
#define PB7 7 |
|
#define PB6 6 |
|
#define PB5 5 |
|
#define PB4 4 |
|
#define PB3 3 |
|
#define PB2 2 |
|
#define PB1 1 |
|
#define PB0 0 |
|
In the Butterfly software main.c file, the initialization function has:
PORTB = (15<<PB0); |
// Enable pullup on |
And we ask, what’s with the 15? Well, 15 in hex is 0xE which in binary is 1110, so since PB0 == 0, what we are doing is setting PORTB equal to 00001110 << 0, remembering that ‘<<’ is the left-shift operator we know that we actually aren’t doing anything, or rather we are left shifting 15 zero times, which is doing nothing if I’ve ever seen nothing, which I haven’t but… back to our story, we are setting PORTB pins 1, 2, and 3 to 1 thus enabling the pull-ups on port B pins 2, 3, and 4. And that ends this discussion.
249
Chapter 10: C Structures
This alternative bit-field technique is a compromise between the K&R way of doing things in C and the machine efficient way of doing things in C for microcontrollers.
250