- •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
Finally we get the Tens by right shifing the byte 4-bits, which we use as the ASCII character offset.
Tens = (Tens >> 4) + '0';
We’ll use these ideas in the showClock function in the software.
The Real Timer Clock Software
In the software you will encounter: uint8_t, which is WinAVR specific and denotes what would normally we called ‘unsigned char’ and is the same as a byte.
Create a new directory, Real Time Clock, and copy the .c and .h files and the makefile from the Messenger directory.
Open Messenger.h in Programmers Notepad and write:
// identify yourself specifically
const char TALKING_TO[] PROGMEM = "\rYou are talking to the "; const char WHO_DEMO[] PROGMEM = "'Real Time Clock' demo.\r";
// bad command
const char BAD_COMMAND1[] PROGMEM = "\rYou sent: '";
const char BAD_COMMAND2[] PROGMEM = "' - I don't understand.\r";
const char ENTER[] PROGMEM = "Enter ";
const char TEXT_GET[] PROGMEM = "'get' to get the time and date.\r";
const char TEXT_SEC[] PROGMEM = "'secXX' to set the second"; const char TEXT_MIN[] PROGMEM = "'minXX' to set the minute"; const char TEXT_HOUR[] PROGMEM = "'hourXX' to set the hour"; const char TEXT_TOXX[] PROGMEM = " to XX.\r";
const char ERROR_NUMBER[] PROGMEM = "\rERROR - number must be less than ";
const char ERROR_60[] PROGMEM = " 60.\r"; const char ERROR_12[] PROGMEM = " 12.\r";
const char THE_TIME_IS[] PROGMEM = "The time is: ";
Open Demonstrator.h and write:
182
Chapter 8: C Pointers and Arrays
// Demonstrator.h Real Timer Clock version
void initializer(void); void parseInput(char *);
void setSecond(char *); void setMinute(char *); void setHour(char *);
char CHAR2BCD2(char input); void RTC_init(void);
void showClock(void); void setClock(void);
Open Demonstrator.c and write:
// Demonstrator.c Real Time Clock version
#include "PC_Comm.h" #include "Messages.h"
unsigned char gSECOND; unsigned char gMINUTE; unsigned char gHOUR;
void initializer()
{
//Calibrate the oscillator: OSCCAL_calibration();
//Initialize the USART USARTinit();
//Initialize the RTC
RTC_init();
// Display instructions on PC sendFString(TALKING_TO); sendFString(WHO_DEMO); sendFString(ENTER); sendFString(TEXT_GET); sendFString(ENTER); sendFString(TEXT_SEC); sendFString(TEXT_TOXX); sendFString(ENTER); sendFString(TEXT_MIN); sendFString(TEXT_TOXX); sendFString(ENTER);
183
Chapter 8: C Pointers and Arrays
sendFString(TEXT_HOUR); sendFString(TEXT_TOXX);
}
void parseInput(char s[])
{
// parse first character switch (s[0])
{
case 'g':
if( (s[1] == 'e') && (s[2] == 't') ) showClock();
break; case 's':
if( (s[1] == 'e') && (s[2] == 'c') ) setSecond(s);
break; case 'm':
if( (s[1] == 'i') && (s[2] == 'n') ) setMinute(s);
break; case 'h':
if( (s[1] == 'o') && (s[2] == 'u') && (s[3] == 'r')) setHour(s);
break; case 'd':
if((s[1]=='e')&&(s[2]=='m')&&(s[3]=='o')&&(s[4]=='?')) sendFString(TALKING_TO); sendFString(WHO_DEMO);
break;
default: sendFString(BAD_COMMAND1); sendChar(s[0]); sendFString(BAD_COMMAND2);
break;
}
s[0] = '\0';
}
void setSecond(char s[])
{
char str[] = {0,0,'\0'}; int sec;
184
Chapter 8: C Pointers and Arrays
str[0] = s[3]; str[1] = s[4];
sec = atoi(str); if( sec <= 60)
{
gSECOND = (uint8_t)sec;
}
else
{
sendFString(ERROR_NUMBER); sendFString(ERROR_60);
}
}
void setMinute(char s[])
{
char str[] = {0,0,'\0'}; int min;
str[0] = s[3]; str[1] = s[4];
min = atoi(str); if( min <= 60)
{
gMINUTE = (uint8_t)min;
}
else
{
sendFString(ERROR_NUMBER); sendFString(ERROR_60);
}
}
void setHour(char s[])
{
char str[] = {0,0,'\0'}; int hour;
str[0] = s[4]; str[1] = s[5];
hour = atoi(str); if( hour <= 12)
{
gHOUR = (uint8_t)hour;
}
else
{
sendFString(ERROR_NUMBER);
185
Chapter 8: C Pointers and Arrays
sendFString(ERROR_12);
}
}
void showClock(void)
{
uint8_t HH, HL, MH, ML, SH, SL;
HH = CHAR2BCD2(gHOUR);
HL = (HH & 0x0F) + '0';
HH = (HH >> 4) + '0';
MH = CHAR2BCD2(gMINUTE);
ML = (MH & 0x0F) + '0';
MH = (MH >> 4) + '0';
SH = CHAR2BCD2(gSECOND);
SL = (SH & 0x0F) + '0';
SH = (SH >> 4) + '0';
sendFString(THE_TIME_IS); sendChar(HH); sendChar(HL); sendChar(':'); sendChar(MH); sendChar(ML); sendChar(':'); sendChar(SH); sendChar(SL); sendChar('\r');
}
//convert a character into a binary coded decimal chracter in the range
//0 to 99 resulting byte has tens in high nibble and ones in low nibble char CHAR2BCD2(char input)
{
char high = 0;
while (input >= 10) |
// Count tens |
{ |
|
high++; |
|
input -= 10; |
|
} |
|
return (high << 4) | input; |
// Add ones and return answer |
}
186
Chapter 8: C Pointers and Arrays
//initialize Timer/counter2 as asynchronous using the 32.768kHz watch
//crystal.
void RTC_init(void)
{
// wait for external crystal to stabilise for(int i = 0; i < 10; i++)
_delay_loop_2(30000);
cli(); |
// disable global |
interrupt |
cbi(TIMSK2, TOIE2); |
// disable OCIE2A |
and TOIE2 |
ASSR = (1<<AS2); |
// select asynchronous operation of Timer2 |
|
TCNT2 = 0; |
// clear TCNT2A |
//select precaler: 32.768 kHz / 128 = 1 sec between each overflow TCCR2A |= (1<<CS22) | (1<<CS20);
//wait for TCN2UB and TCR2UB to be cleared
while((ASSR & 0x01) | (ASSR & 0x04));
TIFR2 = 0xFF; |
// clear interrupt-flags |
|
sbi(TIMSK2, TOIE2); |
// enable Timer2 overflow interrupt |
|
sei(); |
|
// enable global interrupt |
// initial time and date setting |
||
gSECOND |
= 0; |
|
gMINUTE |
= 0; |
|
gHOUR |
= 0; |
|
} |
|
|
// one second interrupt from 32kHz watch crystal |
||
SIGNAL(SIG_OVERFLOW2) |
|
|
{ |
|
// increment second |
gSECOND++; |
||
if (gSECOND == 60) |
|
|
{ |
|
|
gSECOND = 0; |
// increment minute |
|
gMINUTE++; |
||
if (gMINUTE > 59) |
|
|
{ |
gMINUTE = 0; |
|
|
// increment hour |
|
|
gHOUR++; |
if (gHOUR > 12)
187
Chapter 8: C Pointers and Arrays
{
gHOUR = 0;
}
}
}
}
Using Real Time Clock:
After compiling and loading the code, in HyperTerminal you should see:
You are talking to the 'Real Time Clock' demo.
Enter 'get' to get the time and date.
Enter 'secXX' to set the second to XX.
Enter 'minXX' to set the minute to XX.
Enter 'hourXX' to set the hour to XX.
Get the current time:
get
The time is: 12:00:03
Which initially should be a few seconds past 12. Set the current time as follows:
sec45
min4
hour11
Then you can get the correct time:
get
The time is: 11:05:01 get
The time is: 11:05:12 get
The time is: 11:05:17
188