├── AVR-Programming-Library ├── .gitignore ├── macros.h ├── binaryMacro.h ├── README.md └── USART.h ├── Chapter19_EEPROM ├── eememDemo │ ├── .gitignore │ └── eememDemo.c ├── quickDemo │ ├── .gitignore │ └── quickDemo.c ├── vigenereCipher │ ├── .gitignore │ ├── vigenereCipher.c_outline │ └── vigenereCipher.h └── favoriteColor │ ├── .gitignore │ └── favoriteColor.c ├── Chapter07_Analog-to-Digital-Conversion-I ├── lightSensor │ ├── .gitignore │ └── lightSensor.c ├── nightLight │ └── nightLight.c └── slowScope │ ├── serialScope.py │ └── slowScope.c ├── Chapter18_Using-Flash-Program-Memory ├── talkingVoltmeter │ ├── rich_speaking │ │ ├── .gitignore │ │ ├── go.wav │ │ ├── one.wav │ │ ├── six.wav │ │ ├── ten.wav │ │ ├── two.wav │ │ ├── begin.wav │ │ ├── eight.wav │ │ ├── five.wav │ │ ├── four.wav │ │ ├── nine.wav │ │ ├── point.wav │ │ ├── seven.wav │ │ ├── three.wav │ │ ├── volts.wav │ │ ├── zero.wav │ │ ├── hello_world.wav │ │ └── speaking_digits.wav │ ├── cornell │ │ ├── dpcm_2bit │ │ │ ├── .gitignore │ │ │ ├── AllDigits.wav │ │ │ ├── Welcome4760small.wav │ │ │ ├── downsample.m │ │ │ ├── FindOpt.m │ │ │ ├── Find2Code476.m │ │ │ └── sineWave.py │ │ └── dpcm_1bit │ │ │ └── Welcome4760small.wav │ └── elliot_speaking │ │ ├── .gitignore │ │ ├── five.wav │ │ ├── four.wav │ │ ├── nine.wav │ │ ├── one.wav │ │ ├── six.wav │ │ ├── two.wav │ │ ├── zero.wav │ │ ├── eight.wav │ │ ├── point.wav │ │ ├── seven.wav │ │ ├── three.wav │ │ ├── volts.wav │ │ ├── thankyou.wav │ │ └── talkingvoltmeter.wav ├── progmemDemo1 │ └── progmemDemo1.c ├── progmemDemo3 │ └── progmemDemo3.c ├── progmemDemo2 │ └── progmemDemo2.c ├── progmemDemo4 │ └── progmemDemo4.c └── progmemDemo5 │ └── progmemDemo5.c ├── avrdude_utilities ├── rm.exe ├── make.exe ├── avrdude.exe └── msys-1.0.dll ├── Chapter11_Driving-Servo-Motors └── servoSundial │ ├── justSetTime.py │ ├── _servoSerialHelpers.h │ ├── stepHours.py │ ├── _servoClockFunctions.h │ ├── _servoSerialHelpers.c │ ├── _servoClockFunctions.c │ └── servoSundial.h ├── Chapter05_Serial-IO ├── serialOrgan │ ├── organ.h │ ├── organ.c │ ├── scaleGenerator.py │ └── autoPlay.py └── serialLoopback │ └── serialLoopback.c ├── Chapter06_Digital-Input ├── avrMusicBox │ ├── organ.h │ ├── organ.c │ ├── scaleGenerator.py │ └── avrMusicBox.c ├── bossButton │ ├── bossButton.py │ └── bossButton.c ├── simpleButton │ └── simpleButton.c ├── toggleButton │ └── toggleButton.c ├── debouncer │ └── debouncer.c └── toggleButton_debounced │ └── toggleButton_debounced.c ├── Chapter04_Bit-Twiddling ├── cylonEyes_counting │ └── counting.c ├── cylonEyes_quasiRandomToggle │ └── quasiRandomToggle.c ├── cylonEyes_naive │ └── cylonEyes_naive.c ├── cylonEyes │ └── cylonEyes.c ├── cylonEyes_halfStepping │ └── cylonEyes_halfStepping.c ├── cylonEyes_8LFSR │ └── 8LFSR.c └── cylonEyes_16LFSR │ └── 16LFSR.c ├── setupProject ├── main.h ├── main.c ├── macros.h ├── setupProject.py ├── USART.h └── createPinDefines.py ├── Chapter15_Advanced-Motors ├── stepperWorkout │ └── half_stepping.h └── hBridgeWorkout │ └── hBridgeWorkout.c ├── Chapter17_I2C ├── i2cThermometer │ ├── i2c.h │ ├── i2c.c │ └── i2cThermometer.c └── loggingThermometer │ ├── i2c.h │ ├── i2c.c │ └── 25LC256.h ├── Chapter02_Programming-AVRs ├── blinkLED_AVR_style │ └── blinkLED_AVRStyle.c └── blinkLED │ └── blinkLED.c ├── Chapter09_Introduction-to-Timer-Counter-Hardware ├── reactionTimer │ ├── support.h │ └── reactionTimer.c ├── timerAudio │ ├── scale8.h │ └── timerAudio.c └── amRadio │ └── scale16.h ├── Chapter03_Digital-Output ├── povToy │ └── povToy.c ├── povToy_cylonEyes │ └── cylonEyes_POV.c ├── povToy_1up │ └── 1up.c └── povToy_invaders │ └── invaders.c ├── LICENSE.txt ├── Chapter08_Hardware-Interrupts ├── capSense │ ├── serialScope.py │ └── capSense.c ├── helloPinChangeInterrupt │ └── helloPinChangeInterrupt.c └── helloInterrupt │ └── helloInterrupt.c ├── Chapter10_Pulse-Width-Modulation ├── bruteForcePWM │ └── pwm.c ├── pwm │ └── pwm.c ├── pwm_cross-fading_cylons │ └── cross-fading_cylons.c ├── pwmOnAnyPin │ └── pwmOnAnyPin.c └── pwmTimers │ └── pwmTimers.c ├── Chapter13_Advanced-PWM-Tricks ├── adsr │ ├── fullSaw15.h │ ├── fullTri15.h │ ├── generateScale.py │ ├── fullSaw7.h │ ├── fullTri7.h │ ├── fullTriangle.h │ ├── fullSaw3.h │ ├── fullTri3.h │ ├── scale.h │ └── adsr.h ├── dds │ ├── fullSaw15.h │ ├── fullTri15.h │ ├── fullSquare15.h │ ├── fullSaw7.h │ ├── fullTri7.h │ ├── fullSquare7.h │ ├── fullTriangle.h │ ├── fullSaw3.h │ ├── fullTri3.h │ ├── fullSquare3.h │ ├── fullSine.h │ └── dds.c ├── fatSaw │ ├── fullSaw15.h │ ├── fullSaw7.h │ ├── fatSaw.h │ ├── fullSaw3.h │ └── fatSaw.c ├── dds_saw15 │ ├── fullSaw15.h │ ├── fullTri15.h │ ├── fullSquare15.h │ ├── fullSaw7.h │ ├── fullTri7.h │ ├── fullSquare7.h │ ├── fullTriangle.h │ ├── fullSaw3.h │ ├── fullTri3.h │ ├── fullSquare3.h │ ├── fullSine.h │ └── dds_saw15.c ├── dds_interrupts │ ├── fullSaw15.h │ ├── fullTri15.h │ ├── fullSquare15.h │ ├── fullSaw7.h │ ├── fullTri7.h │ ├── fullSquare7.h │ ├── fullTriangle.h │ ├── fullSaw3.h │ ├── fullTri3.h │ ├── fullSquare3.h │ └── fullSine.h └── dialTone │ └── fullSine.h ├── Chapter16_SPI └── spiEEPROMDemo │ ├── spiEEPROMDemo.c │ └── 25LC256.h ├── Chapter14_Switches └── dcMotorWorkout │ └── dcMotorWorkout.c └── allProjectsList /AVR-Programming-Library/.gitignore: -------------------------------------------------------------------------------- 1 | binaryMacroDemo.c 2 | 3 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/eememDemo/.gitignore: -------------------------------------------------------------------------------- 1 | *.eeprom 2 | *.raw 3 | 4 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/quickDemo/.gitignore: -------------------------------------------------------------------------------- 1 | *.eeprom 2 | *.raw 3 | 4 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/vigenereCipher/.gitignore: -------------------------------------------------------------------------------- 1 | vigenereCipher.eeprom 2 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/favoriteColor/.gitignore: -------------------------------------------------------------------------------- 1 | *.eeprom 2 | *.raw 3 | 4 | -------------------------------------------------------------------------------- /Chapter07_Analog-to-Digital-Conversion-I/lightSensor/.gitignore: -------------------------------------------------------------------------------- 1 | lightSensor_50Hz.c 2 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/.gitignore: -------------------------------------------------------------------------------- 1 | *8000.wav 2 | DPCM*.h 3 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/.gitignore: -------------------------------------------------------------------------------- 1 | *.wav 2 | DPCM*.h 3 | 4 | -------------------------------------------------------------------------------- /avrdude_utilities/rm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/avrdude_utilities/rm.exe -------------------------------------------------------------------------------- /avrdude_utilities/make.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/avrdude_utilities/make.exe -------------------------------------------------------------------------------- /avrdude_utilities/avrdude.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/avrdude_utilities/avrdude.exe -------------------------------------------------------------------------------- /avrdude_utilities/msys-1.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/avrdude_utilities/msys-1.0.dll -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/.gitignore: -------------------------------------------------------------------------------- 1 | *8000.wav 2 | DPCM*.h 3 | muah.wav 4 | outtakes.wav 5 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/justSetTime.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import calibrateTime 3 | 4 | s = serial.Serial("/dev/ttyUSB0", 9600, timeout=5) 5 | calibrateTime.setTimeNow(s) 6 | s.close() 7 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/go.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/go.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/one.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/one.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/six.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/six.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/ten.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/ten.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/two.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/two.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/five.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/five.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/four.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/four.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/nine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/nine.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/one.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/one.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/six.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/six.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/two.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/two.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/zero.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/zero.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/begin.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/begin.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/eight.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/eight.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/five.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/five.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/four.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/four.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/nine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/nine.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/point.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/point.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/seven.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/seven.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/three.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/three.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/volts.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/volts.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/zero.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/zero.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/eight.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/eight.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/point.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/point.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/seven.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/seven.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/three.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/three.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/volts.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/volts.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/thankyou.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/thankyou.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/hello_world.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/hello_world.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/AllDigits.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/AllDigits.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/speaking_digits.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/rich_speaking/speaking_digits.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/talkingvoltmeter.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/elliot_speaking/talkingvoltmeter.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_1bit/Welcome4760small.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_1bit/Welcome4760small.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/Welcome4760small.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexagon5un/AVR-Programming/HEAD/Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/Welcome4760small.wav -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/downsample.m: -------------------------------------------------------------------------------- 1 | clear all 2 | %reads a file at 16kHz and outputs it a 8kHz, 8 bits 3 | [d,r] = wavread('test6.WAV'); 4 | y = resample(d,1,2); 5 | wavwrite(y,8000,8,'test6small.wav') -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/_servoSerialHelpers.h: -------------------------------------------------------------------------------- 1 | /* Functions for serial port output formatting and input */ 2 | 3 | #include "servoSundial.h" 4 | // Prints out the time, nicely formatted 5 | void printTime(uint8_t hours, uint8_t minutes, uint8_t seconds); 6 | // Polls for serial input 7 | // sets the time if receives an "S" 8 | void pollSerial(void); 9 | -------------------------------------------------------------------------------- /Chapter05_Serial-IO/serialOrgan/organ.h: -------------------------------------------------------------------------------- 1 | 2 | // ------------- Function prototypes -------------- // 3 | 4 | // Plays a note for the given duration. None of these times are 5 | // calibrated to actual notes or tempi. It's all relative to TIMEBASE. 6 | void playNote(uint16_t period, uint16_t duration); 7 | 8 | // Does nothing for a time equal to the passed duration. 9 | void rest(uint16_t duration); 10 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/avrMusicBox/organ.h: -------------------------------------------------------------------------------- 1 | 2 | // ------------- Function prototypes -------------- // 3 | 4 | // Plays a note for the given duration. None of these times are 5 | // calibrated to actual notes or tempi. It's all relative to TIMEBASE. 6 | void playNote(uint16_t period, uint16_t duration); 7 | 8 | // Does nothing for a time equal to the passed duration. 9 | void rest(uint16_t duration); 10 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_counting/counting.c: -------------------------------------------------------------------------------- 1 | #include /* Defines pins, ports, etc */ 2 | #define F_CPU 1000000UL /* Sets up the chip speed for delay.h */ 3 | #include /* Functions to waste time */ 4 | 5 | #define DELAYTIME 100 6 | 7 | int main(void) { 8 | DDRB = 0b11111111; 9 | PORTB = 0; 10 | 11 | while (1) { 12 | PORTB = PORTB + 1; 13 | _delay_ms(DELAYTIME); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /setupProject/main.h: -------------------------------------------------------------------------------- 1 | 2 | // Standard AVR includes 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // Standard includes 13 | #include 14 | 15 | // These are optional, but nice to have around. 16 | // Feel free to comment them out if you don't use them. 17 | #include "USART.h" 18 | #include "macros.h" 19 | 20 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/FindOpt.m: -------------------------------------------------------------------------------- 1 | function fit = FindOpt(p,d,dd) 2 | p 3 | %init the code vector 4 | ddcode = zeros(1,length(dd)); 5 | %quantize the first derivative 6 | ddcode(find(dd=p(1) & dd=p(2) & dd=p(3)))=3; 10 | 11 | dl = zeros(1,length(ddcode)); 12 | for i=2:length(ddcode) 13 | dl(i) = dl(i-1)+ p(ddcode(i)+4) - .125*dl(i-1); % .* w'; 14 | end 15 | 16 | fit = mean((d(2:end)-dl').^2); -------------------------------------------------------------------------------- /Chapter15_Advanced-Motors/stepperWorkout/half_stepping.h: -------------------------------------------------------------------------------- 1 | 2 | // Include file for half-stepping order 3 | // You may need to change the software pinouts around to match your motor 4 | // or change your motor connections around to match the software. 5 | 6 | const uint8_t stepOrder[] = { 7 | (1 << PB0) | (1 << PB2), 8 | (1 << PB0), 9 | (1 << PB0) | (1 << PB3), 10 | (1 << PB3), 11 | (1 << PB1) | (1 << PB3), 12 | (1 << PB1), 13 | (1 << PB1) | (1 << PB2), 14 | (1 << PB2) 15 | }; 16 | 17 | #define LAST_PHASE_IN_CYCLE 7 18 | -------------------------------------------------------------------------------- /setupProject/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include "main.h" 3 | 4 | // -------- Global Variables --------- // 5 | 6 | // -------- Functions --------- // 7 | 8 | int main(void) { 9 | // -------- Inits --------- // 10 | 11 | // clock_prescale_set(clock_div_1); /* CPU Clock: 8 MHz */ 12 | initUSART(); 13 | printString("OK"); 14 | 15 | // ------ Event loop ------ // 16 | while (1) { 17 | 18 | 19 | 20 | } /* End event loop */ 21 | return (0); /* This line is never reached */ 22 | } 23 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/stepHours.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import calibrateTime 3 | import time 4 | 5 | s = serial.Serial("/dev/ttyUSB0", 9600, timeout=5) 6 | 7 | for hour in range(11,25): 8 | print "Moving to {}.".format(hour) 9 | calibrateTime.setTime(s, hour-2, 59, 59) 10 | time.sleep(2) 11 | for i in range(0, 60, 5): 12 | calibrateTime.setTime(s, hour-1, i, 00) 13 | time.sleep(0.5) 14 | calibrateTime.setTime(s, hour, 0, 0) 15 | discardThisInput = raw_input("\tpress return to continue\n") 16 | 17 | s.close() 18 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/_servoClockFunctions.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "servoSundial.h" 4 | // Note: Global variables (ticks, seconds, minutes, hours) 5 | // are declared in servoSundial.h 6 | // and defined in servoSundial.c 7 | 8 | // Realtime-clock handling functions 9 | 10 | // This sets up the interrupt clock 11 | void initTimer0_Clock(void); 12 | 13 | // These functions are called periodically 14 | // to update the global time variables 15 | // They cascade when needed (second -> minute) 16 | void everySecond(void); 17 | void everyMinute(void); 18 | void everyHour(void); 19 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/quickDemo/quickDemo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | 6 | // Store the 8-bit value 5 in EEPROM slot 0 7 | uint8_t *address = (uint8_t *) 0; 8 | eeprom_update_byte(address, 5); 9 | 10 | // Store the 16-bit value 12345 in EEPROM slots 5 and 6: 11 | eeprom_update_word((uint16_t *) 5, 12345); 12 | 13 | // Store a character array (string) in EEPROM slots 16-28: 14 | char *stringPointer = (char *) 16; 15 | char myString[] = "hello world."; 16 | eeprom_update_block(myString, stringPointer, sizeof(myString)); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter05_Serial-IO/serialOrgan/organ.c: -------------------------------------------------------------------------------- 1 | /* 2 | Simple routines to play notes out to a speaker 3 | */ 4 | 5 | #include 6 | #include 7 | #include "organ.h" 8 | #include "pinDefines.h" 9 | 10 | void playNote(uint16_t period, uint16_t duration) { 11 | uint16_t elapsed; 12 | uint16_t i; 13 | for (elapsed = 0; elapsed < duration; elapsed += period) { 14 | /* For loop with variable delay selects the pitch */ 15 | for (i = 0; i < period; i++) { 16 | _delay_us(1); 17 | } 18 | SPEAKER_PORT ^= (1 << SPEAKER); 19 | } 20 | } 21 | 22 | void rest(uint16_t duration) { 23 | do { 24 | _delay_us(1); 25 | } while (--duration); 26 | } 27 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/avrMusicBox/organ.c: -------------------------------------------------------------------------------- 1 | /* 2 | Simple routines to play notes out to a speaker 3 | */ 4 | 5 | #include 6 | #include 7 | #include "organ.h" 8 | #include "pinDefines.h" 9 | 10 | void playNote(uint16_t period, uint16_t duration) { 11 | uint16_t elapsed; 12 | uint16_t i; 13 | for (elapsed = 0; elapsed < duration; elapsed += period) { 14 | /* For loop with variable delay selects the pitch */ 15 | for (i = 0; i < period; i++) { 16 | _delay_us(1); 17 | } 18 | SPEAKER_PORT ^= (1 << SPEAKER); 19 | } 20 | } 21 | 22 | void rest(uint16_t duration) { 23 | do { 24 | _delay_us(1); 25 | } while (--duration); 26 | } 27 | -------------------------------------------------------------------------------- /setupProject/macros.h: -------------------------------------------------------------------------------- 1 | 2 | /* Standard Macros */ 3 | /* You can totally get by without these, but why? */ 4 | 5 | /* Make sure we've already got io / sfr / pindefs loaded */ 6 | #ifndef _AVR_IO_H_ 7 | #include 8 | #endif 9 | 10 | /* Reminder: the following useful bit-twiddling macros are 11 | always included in avr/sfr_defs.h, which is called from 12 | avr/io.h 13 | 14 | bit_is_set(sfr, bit) 15 | bit_is_clear(sfr, bit) 16 | loop_until_bit_is_set(sfr, bit) 17 | loop_until_bit_is_clear(sfr, bit) 18 | 19 | */ 20 | 21 | /* Define up the full complement of bit-twiddling macros */ 22 | #define BV(bit) (1 << bit) 23 | #define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= BV(bit)) // old sbi() 24 | #define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &= ~BV(bit)) // old cbi() 25 | #define toggle_bit(sfr, bit) (_SFR_BYTE(sfr) ^= BV(bit)) 26 | 27 | -------------------------------------------------------------------------------- /AVR-Programming-Library/macros.h: -------------------------------------------------------------------------------- 1 | 2 | /* Standard Macros */ 3 | /* You can totally get by without these, but why? */ 4 | 5 | /* Make sure we've already got io / sfr / pindefs loaded */ 6 | #ifndef _AVR_IO_H_ 7 | #include 8 | #endif 9 | 10 | /* Reminder: the following useful bit-twiddling macros are 11 | always included in avr/sfr_defs.h, which is called from 12 | avr/io.h 13 | 14 | bit_is_set(sfr, bit) 15 | bit_is_clear(sfr, bit) 16 | loop_until_bit_is_set(sfr, bit) 17 | loop_until_bit_is_clear(sfr, bit) 18 | 19 | */ 20 | 21 | /* Define up the full complement of bit-twiddling macros */ 22 | #define BV(bit) (1 << bit) 23 | #define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= BV(bit)) // old sbi() 24 | #define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &= ~BV(bit)) // old cbi() 25 | #define toggle_bit(sfr, bit) (_SFR_BYTE(sfr) ^= BV(bit)) 26 | 27 | -------------------------------------------------------------------------------- /Chapter17_I2C/i2cThermometer/i2c.h: -------------------------------------------------------------------------------- 1 | // Functions for i2c communication 2 | #include 3 | #include "pinDefines.h" 4 | 5 | void initI2C(void); 6 | /* Sets pullups and initializes bus speed to 100kHz (at FCPU=8MHz) */ 7 | 8 | void i2cWaitForComplete(void); 9 | /* Waits until the hardware sets the TWINT flag */ 10 | 11 | void i2cStart(void); 12 | /* Sends a start condition (sets TWSTA) */ 13 | void i2cStop(void); 14 | /* Sends a stop condition (sets TWSTO) */ 15 | 16 | void i2cSend(uint8_t data); 17 | /* Loads data, sends it out, waiting for completion */ 18 | 19 | uint8_t i2cReadAck(void); 20 | /* Read in from slave, sending ACK when done (sets TWEA) */ 21 | uint8_t i2cReadNoAck(void); 22 | /* Read in from slave, sending NOACK when done (no TWEA) */ 23 | -------------------------------------------------------------------------------- /Chapter17_I2C/loggingThermometer/i2c.h: -------------------------------------------------------------------------------- 1 | // Functions for i2c communication 2 | #include 3 | #include "pinDefines.h" 4 | 5 | void initI2C(void); 6 | /* Sets pullups and initializes bus speed to 100kHz (at FCPU=8MHz) */ 7 | 8 | void i2cWaitForComplete(void); 9 | /* Waits until the hardware sets the TWINT flag */ 10 | 11 | void i2cStart(void); 12 | /* Sends a start condition (sets TWSTA) */ 13 | void i2cStop(void); 14 | /* Sends a stop condition (sets TWSTO) */ 15 | 16 | void i2cSend(uint8_t data); 17 | /* Loads data, sends it out, waiting for completion */ 18 | 19 | uint8_t i2cReadAck(void); 20 | /* Read in from slave, sending ACK when done (sets TWEA) */ 21 | uint8_t i2cReadNoAck(void); 22 | /* Read in from slave, sending NOACK when done (no TWEA) */ 23 | -------------------------------------------------------------------------------- /Chapter02_Programming-AVRs/blinkLED_AVR_style/blinkLED_AVRStyle.c: -------------------------------------------------------------------------------- 1 | /* Blinker Demo II */ 2 | 3 | #include 4 | #include 5 | 6 | #define LED PB0 7 | #define LED_DDR DDRB 8 | #define LED_PORT PORTB 9 | 10 | #define DELAYTIME 200 11 | 12 | #define setBit(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit)) 13 | #define clearBit(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit)) 14 | #define toggleBit(sfr, bit) (_SFR_BYTE(sfr) ^= (1 << bit)) 15 | 16 | int main(void) { 17 | 18 | // Init 19 | setBit(LED_DDR, LED); /* set LED pin for output */ 20 | 21 | // Mainloop 22 | while (1) { 23 | 24 | setBit(LED_PORT, LED); 25 | _delay_ms(DELAYTIME); 26 | 27 | clearBit(LED_PORT, LED); 28 | _delay_ms(DELAYTIME); 29 | 30 | } 31 | return 0; /* end mainloop */ 32 | } 33 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/Find2Code476.m: -------------------------------------------------------------------------------- 1 | clear all 2 | %use an optimizer to find the best parameters 3 | %for an utterance 4 | %The encoder/decoder go into an iterative scheme to find the 5 | %best 3 break points and 4 reconstruction values 6 | %===================================%the Encoder 7 | [d,r] = wavread('C:\Documents and Settings\bruce land\My Documents\Matlab\Speech\SineSynth\test4small.WAV'); %4 8 | %scale to about unity 9 | res = 1/(max(max(d),abs(min(d)) )); 10 | dd = diff(d * res); 11 | 12 | %parameters 13 | value = [-.16, -.026 .026 .16]; 14 | brkpt1=-0.05; brkpt2=0 ; brkpt3=0.05; 15 | %initial parameter guess 16 | p0 = [brkpt1, brkpt2, brkpt3, ... 17 | value(1),value(2),value(3),value(4) ]; 18 | 19 | p = fminsearch(@FindOpt,p0,[],d,dd); 20 | %ChiMin = fmins ('chisq', density0, options, [], smat, observed, 21 | %fixdensity); 22 | 23 | %=================================%print parameters 24 | p -------------------------------------------------------------------------------- /Chapter05_Serial-IO/serialLoopback/serialLoopback.c: -------------------------------------------------------------------------------- 1 | /* 2 | A simple test of serial-port functionality. 3 | Takes in a character at a time and sends it right back out, 4 | displaying the ASCII value on the LEDs. 5 | */ 6 | 7 | // ------- Preamble -------- // 8 | #include 9 | #include 10 | #include "pinDefines.h" 11 | #include "USART.h" 12 | 13 | int main(void) { 14 | char serialCharacter; 15 | 16 | // -------- Inits --------- // 17 | LED_DDR = 0xff; /* set up LEDs for output */ 18 | initUSART(); 19 | printString("Hello World!\r\n"); /* to test */ 20 | 21 | // ------ Event loop ------ // 22 | while (1) { 23 | 24 | serialCharacter = receiveByte(); 25 | transmitByte(serialCharacter); 26 | LED_PORT = serialCharacter; 27 | /* display ascii/numeric value of character */ 28 | 29 | } /* End event loop */ 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/bossButton/bossButton.py: -------------------------------------------------------------------------------- 1 | ## Simple demo 2 | ## Sits forever listening to serial port 3 | ## When you press button, opens website of your choosing. 4 | ## Extend this to many buttons and you'll have a physical 5 | ## web-launcher. 6 | 7 | BOSS_SITE = "http://www.cartalk.com/content/boss-redirect" 8 | ## or perhaps more topical... 9 | XKCD = "http://xkcd.com/353/" 10 | 11 | SERIAL_PORT = "/dev/ttyUSB0" 12 | BAUD_RATE = 9600 13 | 14 | import serial 15 | import webbrowser 16 | 17 | sp = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout = 5) 18 | sp.flush() 19 | print ("Boss Button") 20 | 21 | while(1): # Sit and wait forever 22 | response = sp.read(1) # get one byte 23 | if response == "O": 24 | print ("Got OK Byte. Waiting for button press.") 25 | elif response == b"X": 26 | print ("Got Boss Byte! Alarm!") 27 | webbrowser.open(BOSS_SITE) 28 | else: 29 | print ("Got nothing. Still waiting.") 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/simpleButton/simpleButton.c: -------------------------------------------------------------------------------- 1 | /* 2 | Demo of the simplest on/off button code 3 | Button connected to PD2 4 | LEDs connected to PB0..PB7 5 | */ 6 | 7 | // ------- Preamble -------- // 8 | #include 9 | #include 10 | 11 | int main(void) { 12 | // -------- Inits --------- // 13 | PORTD |= (1 << PD2); /* initialize pullup resistor on our input pin */ 14 | DDRB = 0xff; /* set up all LEDs for output */ 15 | 16 | // ------ Event loop ------ // 17 | while (1) { 18 | if (bit_is_clear(PIND, PD2)) { /* look for button press */ 19 | /* equivalent to if ((PIND & (1 << PD2)) == 0 ){ */ 20 | PORTB = 0b00111100; /* pressed */ 21 | } 22 | else { /* not pressed */ 23 | PORTB = 0b11000011; 24 | } 25 | } /* End event loop */ 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter09_Introduction-to-Timer-Counter-Hardware/reactionTimer/support.h: -------------------------------------------------------------------------------- 1 | 2 | /* Support functions that otherwise make the main code more readable */ 3 | 4 | /* Includes */ 5 | #include 6 | #include 7 | #include "USART.h" 8 | 9 | /* Function Prototypes in support.c */ 10 | 11 | void printMilliseconds(uint16_t value); 12 | /* Given a value in milliseconds, prints out how many seconds 13 | you took over the serial port. Does ascii conversion, prints 14 | decimal point, and drops extra leading zeros. 15 | */ 16 | 17 | void printComments(uint16_t value); 18 | /* Given a value in milliseconds, rates your reaction time */ 19 | 20 | void randomDelay(void); 21 | /* Waits for a "random" delay from 1 - 3.5 sec */ 22 | /* Requires timer 1 initialized and running */ 23 | /* It's not really random, but very hard to control 24 | like coin-flipping. */ 25 | -------------------------------------------------------------------------------- /Chapter03_Digital-Output/povToy/povToy.c: -------------------------------------------------------------------------------- 1 | // POV toy demo framework // 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | 7 | // -------- Functions --------- // 8 | void POVDisplay(uint8_t oneByte) { 9 | PORTB = oneByte; 10 | _delay_ms(2); 11 | } 12 | 13 | int main(void) { 14 | // -------- Inits --------- // 15 | DDRB = 0xff; /* Set up all of LED pins for output */ 16 | // ------ Event loop ------ // 17 | while (1) { /* mainloop */ 18 | POVDisplay(0b00001110); 19 | POVDisplay(0b00011000); 20 | POVDisplay(0b10111101); 21 | POVDisplay(0b01110110); 22 | POVDisplay(0b00111100); 23 | POVDisplay(0b00111100); 24 | POVDisplay(0b00111100); 25 | POVDisplay(0b01110110); 26 | POVDisplay(0b10111101); 27 | POVDisplay(0b00011000); 28 | POVDisplay(0b00001110); 29 | 30 | PORTB = 0; 31 | _delay_ms(10); 32 | } /* end mainloop */ 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter17_I2C/i2cThermometer/i2c.c: -------------------------------------------------------------------------------- 1 | #include "i2c.h" 2 | 3 | void initI2C(void) { 4 | TWBR = 32; /* set bit rate, see p. 242 */ 5 | /* 8MHz / (16+2*TWBR*1) ~= 100kHz */ 6 | TWCR |= (1 << TWEN); /* enable */ 7 | } 8 | 9 | void i2cWaitForComplete(void) { 10 | loop_until_bit_is_set(TWCR, TWINT); 11 | } 12 | 13 | void i2cStart(void) { 14 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTA)); 15 | i2cWaitForComplete(); 16 | } 17 | 18 | void i2cStop(void) { 19 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTO)); 20 | } 21 | 22 | uint8_t i2cReadAck(void) { 23 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWEA)); 24 | i2cWaitForComplete(); 25 | return (TWDR); 26 | } 27 | 28 | uint8_t i2cReadNoAck(void) { 29 | TWCR = (_BV(TWINT) | _BV(TWEN)); 30 | i2cWaitForComplete(); 31 | return (TWDR); 32 | } 33 | 34 | void i2cSend(uint8_t data) { 35 | TWDR = data; 36 | TWCR = (_BV(TWINT) | _BV(TWEN)); /* init and enable */ 37 | i2cWaitForComplete(); 38 | } 39 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/bossButton/bossButton.c: -------------------------------------------------------------------------------- 1 | /* 2 | bossButton.c 3 | 4 | As long as we've got a button wired up to the AVR, 5 | might as well have some fun. 6 | 7 | Upload this code to your AVR, run bossButton.py. 8 | Press button. 9 | 10 | */ 11 | 12 | // ------- Preamble -------- // 13 | #include 14 | #include 15 | #include "pinDefines.h" 16 | #include "USART.h" 17 | 18 | static inline void blinkLED(void) { 19 | LED_PORT = (1 << LED0); 20 | _delay_ms(1000); 21 | LED_PORT &= ~(1 << LED0); 22 | } 23 | 24 | 25 | int main(void) { 26 | 27 | // -------- Inits --------- // 28 | BUTTON_PORT |= (1 << BUTTON); /* input mode, turn on pullup */ 29 | 30 | LED_DDR = (1 << LED0); 31 | blinkLED(); 32 | 33 | initUSART(); 34 | transmitByte('O'); 35 | 36 | // ------ Event loop ------ // 37 | while (1) { 38 | 39 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 40 | transmitByte('X'); 41 | blinkLED(); 42 | } 43 | 44 | } /* End event loop */ 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Chapter09_Introduction-to-Timer-Counter-Hardware/timerAudio/scale8.h: -------------------------------------------------------------------------------- 1 | /* Scale in the key of 1/200 */ 2 | 3 | /* 4 | These are periods -- if you delay this long, 5 | then toggle the speaker pin, you'll get approximate 6 | pitches. 7 | 8 | This is the 8-bit version. The pitches get less accurate 9 | as they get higher. 10 | 11 | */ 12 | 13 | #define Gx0 252 14 | #define A0 238 15 | #define Ax0 224 16 | #define B0 212 17 | #define C1 200 18 | #define Cx0 189 19 | #define D1 178 20 | #define Dx0 168 21 | #define E1 159 22 | #define F1 150 23 | #define Fx1 141 24 | #define G1 133 25 | #define Gx1 126 26 | #define A1 119 27 | #define Ax1 112 28 | #define B1 106 29 | #define C2 100 30 | #define Cx2 94 31 | #define D2 89 32 | #define Dx2 84 33 | #define E2 79 34 | #define F2 75 35 | #define Fx2 71 36 | #define G2 67 37 | #define Gx2 63 38 | #define A2 59 39 | #define Ax2 56 40 | #define B2 53 41 | #define C3 50 42 | #define Cx3 47 43 | #define D3 44 44 | #define Dx3 42 45 | #define E3 40 46 | #define F3 37 47 | #define Fx3 35 48 | #define G3 33 49 | -------------------------------------------------------------------------------- /Chapter02_Programming-AVRs/blinkLED/blinkLED.c: -------------------------------------------------------------------------------- 1 | /* Blinker Demo */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | 7 | 8 | int main(void) { 9 | 10 | // -------- Inits --------- // 11 | DDRB |= 0b00000001; /* Data Direction Register B: 12 | writing a one to the bit 13 | enables output. */ 14 | 15 | // ------ Event loop ------ // 16 | while (1) { 17 | 18 | PORTB = 0b00000001; /* Turn on first LED bit/pin in PORTB */ 19 | _delay_ms(1000); /* wait */ 20 | 21 | PORTB = 0b00000000; /* Turn off all B pins, including LED */ 22 | _delay_ms(1000); /* wait */ 23 | 24 | } /* End event loop */ 25 | return 0; /* This line is never reached */ 26 | } 27 | -------------------------------------------------------------------------------- /Chapter17_I2C/loggingThermometer/i2c.c: -------------------------------------------------------------------------------- 1 | #include "i2c.h" 2 | 3 | void initI2C(void) { 4 | /* set pullups for SDA, SCL lines */ 5 | I2C_SDA_PORT |= ((1 << I2C_SDA) | (1 << I2C_SCL)); 6 | TWBR = 32; /* set bit rate (p.242): 8MHz / (16+2*TWBR*1) ~= 100kHz */ 7 | TWCR |= (1 << TWEN); /* enable */ 8 | } 9 | 10 | void i2cWaitForComplete(void) { 11 | loop_until_bit_is_set(TWCR, TWINT); 12 | } 13 | 14 | void i2cStart(void) { 15 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTA)); 16 | i2cWaitForComplete(); 17 | } 18 | 19 | void i2cStop(void) { 20 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTO)); 21 | } 22 | 23 | uint8_t i2cReadAck(void) { 24 | TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWEA)); 25 | i2cWaitForComplete(); 26 | return (TWDR); 27 | } 28 | 29 | uint8_t i2cReadNoAck(void) { 30 | TWCR = (_BV(TWINT) | _BV(TWEN)); 31 | i2cWaitForComplete(); 32 | return (TWDR); 33 | } 34 | 35 | void i2cSend(uint8_t data) { 36 | TWDR = data; 37 | TWCR = (_BV(TWINT) | _BV(TWEN)); /* init and enable */ 38 | i2cWaitForComplete(); 39 | } 40 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/_servoSerialHelpers.c: -------------------------------------------------------------------------------- 1 | /* Functions for serial port output formatting and input */ 2 | #include "_servoSerialHelpers.h" 3 | 4 | void printTime(uint8_t hours, uint8_t minutes, uint8_t seconds) { 5 | printByte(hours); 6 | transmitByte(':'); 7 | printByte(minutes); 8 | transmitByte(':'); 9 | printByte(seconds); 10 | transmitByte('\r'); 11 | transmitByte('\n'); 12 | } 13 | 14 | void pollSerial(void) { 15 | /* Poll for serial input -- to set the time. */ 16 | char input; 17 | if (bit_is_set(UCSR0A, RXC0)) { 18 | input = UDR0; 19 | if (input == 'S') { /* enter set-time mode */ 20 | printString("Setting time...\r\n"); 21 | printString("Hour: "); 22 | hours = getNumber(); 23 | printString("\r\nMinutes: "); 24 | minutes = getNumber(); 25 | printString("\r\nSeconds: "); 26 | seconds = getNumber(); 27 | printString("\r\n"); 28 | ticks = 0; 29 | if ((hours >= START_TIME) && (hours < STOP_TIME)) { 30 | setServoPosition(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chapter03_Digital-Output/povToy_cylonEyes/cylonEyes_POV.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cylon eyes actually turns out to be a decent POV routine. 4 | The only change here is in DELAYTIME. 5 | 6 | */ 7 | 8 | 9 | #include /* Defines pins, ports, etc */ 10 | #include /* Functions to waste time */ 11 | 12 | #define DELAYTIME 2 /* milliseconds */ 13 | 14 | int main(void) { 15 | uint8_t i=0; 16 | DDRB = 0b11111111; /* Data Direction Register B: all on */ 17 | 18 | while (1) { 19 | 20 | while (i < 7) { 21 | PORTB = (1 << i); /* illuminate only i'th pin */ 22 | _delay_ms(DELAYTIME); /* wait */ 23 | i = i + 1; /* move to the next LED */ 24 | } 25 | 26 | while (i > 0) { 27 | PORTB = (1 << i); /* illuminate only i'th pin */ 28 | _delay_ms(DELAYTIME); /* wait */ 29 | i = i - 1; /* move to the previous LED */ 30 | } 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/talkingVoltmeter/cornell/dpcm_2bit/sineWave.py: -------------------------------------------------------------------------------- 1 | ## Demo python program to create sine wave 2 | 3 | from struct import pack, unpack 4 | from math import sin, pi 5 | import wave 6 | import os 7 | import random 8 | 9 | 10 | RATE = 44100 11 | 12 | ## GENERATE MONO FILE ## 13 | wv = wave.open('test_mono.wav', 'w') 14 | wv.setparams((1, 2, RATE, 0, 'NONE', 'not compressed')) 15 | maxVol=2**15-1.0 #maximum amplitude 16 | wvData="" 17 | for i in range(0, RATE*3): 18 | wvData+=pack('h', maxVol*sin(2*pi*i*440.0/RATE)) 19 | 20 | wv.writeframes(wvData) 21 | wv.close() 22 | os.system("mplayer test_mono.wav") 23 | 24 | ## GENERATE STEREO FILE ## 25 | wv = wave.open('test_stereo.wav', 'w') 26 | wv.setparams((2, 2, RATE, 0, 'NONE', 'not compressed')) 27 | maxVol=2**15-1.0 #maximum amplitude 28 | waveData = "" 29 | for i in range(0, RATE*3): 30 | t = 2*pi*i/RATE # time-step in radians*sec 31 | waveData+=pack('h', maxVol*sin(t*440.0)) #440Hz left 32 | waveData+=pack('h', maxVol*sin(t*220.0)) #220Hz right 33 | 34 | 35 | wv.writeframes(waveData) 36 | wv.close() 37 | os.system("mplayer test_stereo.wav") 38 | 39 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2014 Elliot Williams 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | Have fun! 24 | 25 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/progmemDemo1/progmemDemo1.c: -------------------------------------------------------------------------------- 1 | /* First steps into using program memory */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include "USART.h" 7 | 8 | const char myVeryLongString[] PROGMEM = "\r\nHi there, \ 9 | this is an example of a long string.\r\n\ 10 | The kind that you wouldn't want to store in RAM.\r\n"; 11 | const uint16_t sixteenBits PROGMEM = 12345; 12 | 13 | int main(void) { 14 | initUSART(); 15 | char oneLetter; 16 | uint8_t i; 17 | 18 | while (1) { 19 | for (i = 0; i < sizeof(myVeryLongString); i++) { 20 | oneLetter = pgm_read_byte(&(myVeryLongString[i])); 21 | transmitByte(oneLetter); 22 | _delay_ms(100); /* slow it down to simulate typing effect :) */ 23 | } 24 | _delay_ms(1000); 25 | 26 | printWord(&sixteenBits); /* this throws a compiler warning... */ 27 | transmitByte('\r'); 28 | transmitByte('\n'); 29 | printWord(pgm_read_word(&sixteenBits)); 30 | } /* End event loop */ 31 | return 0; /* This line is never reached */ 32 | } 33 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/eememDemo/eememDemo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | /* #include */ 5 | /* #include */ 6 | 7 | #define STRING_LEN 80 8 | 9 | // Define EEMEM variables 10 | uint8_t eepromCounter EEMEM = 0; 11 | char eepromString[STRING_LEN] EEMEM = "Welcome to the EEMEM Demo.\r\n"; 12 | uint16_t eepromWord EEMEM = 12345; 13 | 14 | int main(void) { 15 | 16 | initUSART(); 17 | char ramString[STRING_LEN]; 18 | uint8_t counter; 19 | 20 | while (1) { 21 | printString("\r\n------------------\r\n"); 22 | eeprom_read_block(ramString, eepromString, STRING_LEN); 23 | printString(ramString); 24 | 25 | printString("\r\nThe counter reads: "); 26 | counter = eeprom_read_byte(&eepromCounter); 27 | printByte(counter); 28 | 29 | printString("\r\nMy uint16_t value is: "); 30 | printWord(eeprom_read_word(&eepromWord)); 31 | 32 | printString("\r\n Enter a new introduction string below:\r\n"); 33 | readString(ramString, STRING_LEN); 34 | eeprom_update_block(ramString, eepromString, STRING_LEN); 35 | counter++; 36 | eeprom_update_byte(&eepromCounter, counter); 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_quasiRandomToggle/quasiRandomToggle.c: -------------------------------------------------------------------------------- 1 | /* Cylon Eyes */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | 7 | #define DELAYTIME 45 /* milliseconds */ 8 | #define LED_PORT PORTB 9 | #define LED_PIN PINB 10 | #define LED_DDR DDRB 11 | 12 | int main(void) { 13 | 14 | // -------- Inits --------- // 15 | uint16_t x = 0x1234; 16 | uint8_t y; 17 | LED_DDR = 0xff; /* Data Direction Register B: 18 | all set up for output */ 19 | 20 | // ------ Event loop ------ // 21 | while (1) { 22 | 23 | x = 2053 * x + 13849; /* "random" number generator */ 24 | y = (x >> 8) & 0b00000111; /* pick three bits from high byte */ 25 | LED_PORT ^= (1 << y); /* toggle one bit */ 26 | _delay_ms(100); 27 | 28 | } /* End event loop */ 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/toggleButton/toggleButton.c: -------------------------------------------------------------------------------- 1 | /* 2 | Demonstrates using state to detect button presses 3 | */ 4 | 5 | // ------- Preamble -------- // 6 | #include 7 | #include "pinDefines.h" 8 | 9 | int main(void) { 10 | // -------- Inits --------- // 11 | uint8_t buttonWasPressed; /* state */ 12 | BUTTON_PORT |= (1 << BUTTON); /* enable the pullup on the button */ 13 | LED_DDR = (1 << LED0); /* set up LED for output */ 14 | 15 | // ------ Event loop ------ // 16 | while (1) { 17 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { /* button is pressed now */ 18 | if (buttonWasPressed == 0) { /* but wasn't last time through */ 19 | LED_PORT ^= (1 << LED0); /* do whatever */ 20 | buttonWasPressed = 1; /* update the state */ 21 | } 22 | } 23 | else { /* button is not pressed now */ 24 | buttonWasPressed = 0; /* update the state */ 25 | } 26 | } /* End event loop */ 27 | return 0; /* This line is never reached */ 28 | } 29 | -------------------------------------------------------------------------------- /Chapter07_Analog-to-Digital-Conversion-I/nightLight/nightLight.c: -------------------------------------------------------------------------------- 1 | // Quick and dirty adjustable-threshold night-light. 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include "pinDefines.h" 7 | 8 | uint16_t readADC(uint8_t channel) { 9 | ADMUX = (0xf0 & ADMUX) | channel; 10 | ADCSRA |= (1 << ADSC); 11 | loop_until_bit_is_clear(ADCSRA, ADSC); 12 | return (ADC); 13 | } 14 | 15 | int main(void) { 16 | // -------- Inits --------- // 17 | uint16_t lightThreshold; 18 | uint16_t sensorValue; 19 | // Set up ADC 20 | ADMUX |= (1 << REFS0); /* reference voltage on AVCC */ 21 | ADCSRA |= (1 << ADPS1) | (1 << ADPS0); /* ADC clock prescaler /8 */ 22 | ADCSRA |= (1 << ADEN); /* enable ADC */ 23 | 24 | LED_DDR = 0xff; 25 | // ------ Event loop ------ // 26 | while (1) { 27 | 28 | lightThreshold = readADC(POT); 29 | sensorValue = readADC(LIGHT_SENSOR); 30 | 31 | if (sensorValue < lightThreshold) { 32 | LED_PORT = 0xff; 33 | } 34 | else { 35 | LED_PORT = 0x00; 36 | } 37 | } /* End event loop */ 38 | return 0; /* This line is never reached */ 39 | } 40 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/progmemDemo3/progmemDemo3.c: -------------------------------------------------------------------------------- 1 | /* Third step into using program memory */ 2 | /* Passing pointers to functions */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "USART.h" 8 | 9 | const char myVeryLongString1[] PROGMEM = "\r\nHi there, \ 10 | this is an example of a long string.\r\n\ 11 | The kind that you wouldn't want to store in RAM.\r\n"; 12 | const char myVeryLongString2[] PROGMEM = "All work and no play \ 13 | makes Jack something something.\r\n"; 14 | 15 | void printString_Progmem(const char *stringP) { 16 | char oneLetter; 17 | while ((oneLetter = pgm_read_byte(stringP))) { 18 | transmitByte(oneLetter); 19 | stringP++; 20 | _delay_ms(100); /* only b/c it's cute */ 21 | } 22 | } 23 | 24 | int main(void) { 25 | initUSART(); 26 | while (1) { 27 | printString_Progmem(&myVeryLongString1[0]); 28 | printString_Progmem(&myVeryLongString1[50]); 29 | printString_Progmem(myVeryLongString2); 30 | _delay_ms(1000); 31 | } /* End event loop */ 32 | return 0; /* This line is never reached */ 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08_Hardware-Interrupts/capSense/serialScope.py: -------------------------------------------------------------------------------- 1 | import serial 2 | 3 | def readValue(serialPort): 4 | return(ord(serialPort.read(1))) 5 | 6 | def plotValue(value): 7 | """ Displays the value on a scaled scrolling bargraph""" 8 | leadingSpaces = "-" * int(value*(SCREEN_WIDTH-3) / 255) 9 | print(f"{leadingSpaces} {value:03}") 10 | 11 | def cheapoScope(serialPort): 12 | while(1): 13 | newValue = readValue(serialPort) 14 | plotValue(newValue) 15 | 16 | 17 | if __name__ == "__main__": 18 | ## list all serial ports being used: python -m serial.tools.list_ports 19 | PORT = '/dev/ttyUSB0' # update to whatever port is listed in serial.tools.list_ports 20 | BAUDRATE = 9600 21 | TIMEOUT = None 22 | SCREEN_WIDTH = 80 23 | 24 | ## Take command-line arguments to override defaults above 25 | import sys 26 | if len(sys.argv) == 3: 27 | port = sys.argv[1] 28 | baudrate = int(sys.argv[2]) 29 | else: # nothing passed, use defaults 30 | print ("Optional arguments port, baudrate set to defaults.") 31 | port, baudrate = (PORT, BAUDRATE) 32 | 33 | serialPort = serial.Serial(port, baudrate, timeout=TIMEOUT) 34 | serialPort.flush() 35 | cheapoScope(serialPort) 36 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/favoriteColor/favoriteColor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define STRING_MAXLEN 0x20 /* 32 characters */ 6 | #define STRING_ADDRESS 0x20 7 | #define COUNTER_ADDRESS 0x10 8 | 9 | 10 | int main(void) { 11 | 12 | char myString[STRING_MAXLEN]; 13 | char *eepromAddress = (char *) STRING_ADDRESS; 14 | uint16_t counter; 15 | 16 | initUSART(); 17 | 18 | while (1) { 19 | // Read from EEPROM and print out 20 | eeprom_read_block(myString, eepromAddress, STRING_MAXLEN); 21 | counter = eeprom_read_word((uint16_t *) COUNTER_ADDRESS); 22 | printString("\r\nYour old favorite color is: "); 23 | printString(myString); 24 | 25 | // Take input, store in EEPROM 26 | printString("\r\n\r\n Type your new favorite color. "); 27 | readString(myString, sizeof(myString)); 28 | /* pass by address, function will change its values */ 29 | eeprom_update_block(myString, eepromAddress, STRING_MAXLEN); 30 | counter++; 31 | printString("Thanks! \r\nYou've answered the same question "); 32 | printWord(counter); 33 | printString(" times. \r\n"); 34 | eeprom_update_word((uint16_t *) COUNTER_ADDRESS, counter); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Chapter07_Analog-to-Digital-Conversion-I/slowScope/serialScope.py: -------------------------------------------------------------------------------- 1 | import serial 2 | 3 | def readValue(serialPort): 4 | return(ord(serialPort.read(1))) 5 | 6 | def plotValue(value): 7 | """ Displays the value on a scaled scrolling bargraph""" 8 | leadingSpaces = "-" * int(value*(SCREEN_WIDTH-3) / 255) 9 | print(f"{leadingSpaces} {value:03}") 10 | 11 | def cheapoScope(serialPort): 12 | while(1): 13 | newValue = readValue(serialPort) 14 | plotValue(newValue) 15 | 16 | 17 | if __name__ == "__main__": 18 | ## list all serial ports being used: python -m serial.tools.list_ports 19 | PORT = '/dev/ttyUSB0' # update to whatever port is listed in serial.tools.list_ports 20 | BAUDRATE = 9600 21 | TIMEOUT = None 22 | SCREEN_WIDTH = 80 23 | 24 | ## Take command-line arguments to override defaults above 25 | import sys 26 | if len(sys.argv) == 3: 27 | port = sys.argv[1] 28 | baudrate = int(sys.argv[2]) 29 | else: # nothing passed, use defaults 30 | print ("Optional arguments port, baudrate set to defaults.") 31 | port, baudrate = (PORT, BAUDRATE) 32 | 33 | serialPort = serial.Serial(port, baudrate, timeout=TIMEOUT) 34 | serialPort.flush() 35 | cheapoScope(serialPort) 36 | -------------------------------------------------------------------------------- /Chapter10_Pulse-Width-Modulation/bruteForcePWM/pwm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Quick and dirty PWM Demo 3 | */ 4 | 5 | // ------- Preamble -------- // 6 | #include /* Defines pins, ports, etc */ 7 | #include /* Functions to waste time */ 8 | #include "pinDefines.h" 9 | 10 | #define LED_DELAY 2 11 | 12 | int main(void) { 13 | 14 | uint8_t brightness = 0; 15 | int8_t direction = 1; 16 | uint8_t i; 17 | 18 | // -------- Inits --------- // 19 | 20 | LED_DDR = 0xff; /* Init all LEDs */ 21 | 22 | // ------ Event loop ------ // 23 | while (1) { 24 | 25 | // PWM 26 | for (i = 0; i < 255; i++) { 27 | if (i < brightness) { 28 | LED_PORT = 0xff; /* turn on */ 29 | } 30 | else { 31 | LED_PORT = 0; /* turn off */ 32 | } 33 | _delay_us(LED_DELAY); 34 | } 35 | 36 | // Brighten and dim 37 | if (brightness == 0) { 38 | direction = 1; 39 | } 40 | if (brightness == 255) { 41 | direction = -1; 42 | } 43 | brightness += direction; 44 | 45 | } /* End event loop */ 46 | return 0; /* This line is never reached */ 47 | } 48 | -------------------------------------------------------------------------------- /Chapter07_Analog-to-Digital-Conversion-I/slowScope/slowScope.c: -------------------------------------------------------------------------------- 1 | // Slow-scope. A free-running AVR / ADC "oscilloscope" 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include "pinDefines.h" 7 | #include "USART.h" 8 | 9 | #define SAMPLE_DELAY 20 /* ms, controls the scroll-speed of the scope */ 10 | 11 | // -------- Functions --------- // 12 | static inline void initFreerunningADC(void) { 13 | ADMUX |= (1 << REFS0); /* reference voltage on AVCC */ 14 | ADCSRA |= (1 << ADPS1) | (1 << ADPS0); /* ADC clock prescaler /8 */ 15 | 16 | ADMUX |= (1 << ADLAR); /* left-adjust result, return only 8 bits */ 17 | 18 | ADCSRA |= (1 << ADEN); /* enable ADC */ 19 | ADCSRA |= (1 << ADATE); /* auto-trigger enable */ 20 | ADCSRA |= (1 << ADSC); /* start first conversion */ 21 | } 22 | 23 | int main(void) { 24 | // -------- Inits --------- // 25 | initUSART(); 26 | initFreerunningADC(); 27 | // ------ Event loop ------ // 28 | while (1) { 29 | transmitByte(ADCH); /* transmit the high byte, left-adjusted */ 30 | _delay_ms(SAMPLE_DELAY); 31 | } /* End event loop */ 32 | return 0; /* This line is never reached */ 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08_Hardware-Interrupts/helloPinChangeInterrupt/helloPinChangeInterrupt.c: -------------------------------------------------------------------------------- 1 | /* Demo using pin-change interrupts and in-ISR debouncing routine */ 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include 7 | #include "pinDefines.h" 8 | 9 | 10 | ISR(PCINT2_vect) { /* Run every time button state changes */ 11 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 12 | LED_PORT |= (1 << LED1); 13 | } 14 | else { 15 | LED_PORT &= ~(1 << LED1); 16 | } 17 | } 18 | 19 | void initPinChangeInterrupt18(void) { 20 | PCICR |= (1 << PCIE2); /* set pin-change interrupt for D pins */ 21 | PCMSK2 |= (1 << PCINT18); /* set mask to look for PCINT18 / PD2 */ 22 | sei(); /* set (global) interrupt enable bit */ 23 | } 24 | 25 | int main(void) { 26 | // -------- Inits --------- // 27 | LED_DDR = 0xff; /* all LEDs active */ 28 | BUTTON_PORT |= (1 << BUTTON); /* pullup */ 29 | initPinChangeInterrupt18(); 30 | 31 | // ------ Event loop ------ // 32 | while (1) { 33 | 34 | _delay_ms(200); 35 | LED_PORT ^= (1 << LED0); 36 | 37 | } /* End event loop */ 38 | return 0; /* This line is never reached */ 39 | } 40 | -------------------------------------------------------------------------------- /AVR-Programming-Library/binaryMacro.h: -------------------------------------------------------------------------------- 1 | /* Binary constant generator macro 2 | By Tom Torfs - donated to the public domain 3 | */ 4 | 5 | /* All macro's evaluate to compile-time constants */ 6 | 7 | /* *** helper macros *** / 8 | 9 | /* turn a numeric literal into a hex constant 10 | (avoids problems with leading zeroes) 11 | 8-bit constants max value 0x11111111, always fits in unsigned long 12 | */ 13 | #define HEX__(n) 0x##n##LU 14 | 15 | /* 8-bit conversion function */ 16 | #define B8__(x) ((x&0x0000000FLU)?1:0) \ 17 | +((x&0x000000F0LU)?2:0) \ 18 | +((x&0x00000F00LU)?4:0) \ 19 | +((x&0x0000F000LU)?8:0) \ 20 | +((x&0x000F0000LU)?16:0) \ 21 | +((x&0x00F00000LU)?32:0) \ 22 | +((x&0x0F000000LU)?64:0) \ 23 | +((x&0xF0000000LU)?128:0) 24 | 25 | /* *** user macros *** / 26 | 27 | /* for upto 8-bit binary constants */ 28 | #define B8(d) ((unsigned char)B8__(HEX__(d))) 29 | 30 | /* for upto 16-bit binary constants, MSB first */ 31 | #define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \ 32 | + B8(dlsb)) 33 | 34 | /* for upto 32-bit binary constants, MSB first */ 35 | #define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \ 36 | + ((unsigned long)B8(db2)<<16) \ 37 | + ((unsigned long)B8(db3)<<8) \ 38 | + B8(dlsb)) 39 | 40 | /* Sample usage: 41 | B8(01010101) = 85 42 | B16(10101010,01010101) = 43605 43 | B32(10000000,11111111,10101010,01010101) = 2164238933 44 | */ 45 | 46 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_naive/cylonEyes_naive.c: -------------------------------------------------------------------------------- 1 | #include /* Defines pins, ports, etc */ 2 | #define F_CPU 1000000UL /* Sets up the chip speed for delay.h */ 3 | #include /* Functions to waste time */ 4 | 5 | #define DELAYTIME 75 /* milliseconds */ 6 | 7 | int main(void) { 8 | 9 | DDRB = 0b11111111; /* Data Direction Register B: 10 | all set up for output */ 11 | 12 | while (1) { 13 | PORTB = 0b00000001; 14 | _delay_ms(DELAYTIME); 15 | PORTB = 0b00000010; 16 | _delay_ms(DELAYTIME); 17 | PORTB = 0b00000100; 18 | _delay_ms(DELAYTIME); 19 | PORTB = 0b00001000; 20 | _delay_ms(DELAYTIME); 21 | PORTB = 0b00010000; 22 | _delay_ms(DELAYTIME); 23 | PORTB = 0b00100000; 24 | _delay_ms(DELAYTIME); 25 | PORTB = 0b01000000; 26 | _delay_ms(DELAYTIME); 27 | PORTB = 0b10000000; 28 | _delay_ms(DELAYTIME); 29 | PORTB = 0b01000000; 30 | _delay_ms(DELAYTIME); 31 | PORTB = 0b00100000; 32 | _delay_ms(DELAYTIME); 33 | PORTB = 0b00010000; 34 | _delay_ms(DELAYTIME); 35 | PORTB = 0b00001000; 36 | _delay_ms(DELAYTIME); 37 | PORTB = 0b00000100; 38 | _delay_ms(DELAYTIME); 39 | PORTB = 0b00000010; 40 | _delay_ms(DELAYTIME); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullSaw15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullTri15.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSaw15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullTri15.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/fatSaw/fullSaw15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSquare15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSaw15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullTri15.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSaw15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullTri15.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSquare15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSquare15.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare15[256] = { 2 | 0, 1, 3, 4, 5, 6, 7, 7, 3 | 7, 7, 7, 7, 8, 9, 10, 12, 4 | 13, 15, 17, 18, 20, 21, 21, 22, 5 | 22, 22, 22, 22, 22, 23, 24, 25, 6 | 27, 29, 31, 33, 34, 35, 36, 36, 7 | 36, 36, 36, 36, 36, 37, 38, 39, 8 | 41, 43, 45, 47, 48, 50, 51, 51, 9 | 51, 51, 51, 51, 51, 51, 52, 53, 10 | 54, 56, 58, 61, 63, 64, 66, 66, 11 | 67, 66, 66, 65, 65, 65, 65, 66, 12 | 68, 70, 72, 75, 77, 79, 81, 82, 13 | 82, 82, 81, 80, 79, 78, 78, 78, 14 | 80, 82, 85, 88, 92, 95, 97, 99, 15 | 100, 99, 98, 95, 93, 90, 88, 88, 16 | 89, 91, 96, 101, 108, 115, 121, 125, 17 | 127, 125, 119, 108, 93, 74, 51, 26, 18 | 0, -27, -52, -75, -94, -109, -120, -126, 19 | -128, -126, -122, -116, -109, -102, -97, -92, 20 | -90, -89, -89, -91, -94, -96, -99, -100, 21 | -101, -100, -98, -96, -93, -89, -86, -83, 22 | -81, -79, -79, -79, -80, -81, -82, -83, 23 | -83, -83, -82, -80, -78, -76, -73, -71, 24 | -69, -67, -66, -66, -66, -66, -67, -67, 25 | -68, -67, -67, -65, -64, -62, -59, -57, 26 | -55, -54, -53, -52, -52, -52, -52, -52, 27 | -52, -52, -52, -51, -49, -48, -46, -44, 28 | -42, -40, -39, -38, -37, -37, -37, -37, 29 | -37, -37, -37, -36, -35, -34, -32, -30, 30 | -28, -26, -25, -24, -23, -23, -23, -23, 31 | -23, -23, -22, -22, -21, -19, -18, -16, 32 | -14, -13, -11, -10, -9, -8, -8, -8, 33 | -8, -8, -8, -7, -6, -5, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/generateScale.py: -------------------------------------------------------------------------------- 1 | 2 | ## File to generate equal-tempered scale for use with DDS 3 | 4 | 5 | import math # because music is math 6 | 7 | scale = ['C', 'Cx', 'D', 'Dx', 'E', 'F', 'Fx', 'G', 'Gx', 'A', 'Ax', 'B'] 8 | 9 | def octave(baseLength): 10 | pitches = [baseLength * math.exp(x*math.log(2)/12) for x in range(0, 12)] 11 | pitches = [int(round(x)) for x in pitches] 12 | return( zip(scale, pitches) ) 13 | 14 | 15 | def writeScaleHeader(basePitch, octaves, filename="scale.h"): 16 | outfile = open(filename, "w") 17 | outfile.write('''/* 18 | 19 | Scales for use with DDS synthesis. 20 | 21 | Aimed roughly at having A2 be at 440Hz, 22 | when the chip is clocked at 8MHz and 23 | using 8-bit resolution on the PWM. 24 | 25 | Tune it by tweaking basePitch. 26 | 27 | */ 28 | 29 | ''') 30 | for i in range(0, octaves): 31 | for note, pitch in octave(basePitch * 2**i): 32 | if pitch < 30000: 33 | noteString = note + str(i) 34 | print("#define {:<5}{:>6}").format(noteString, pitch) 35 | outfile.write("#define {:<5}{:>6}\n".format(noteString, pitch)) 36 | outfile.close() 37 | 38 | ###################################################################### 39 | 40 | if __name__ == "__main__": 41 | 42 | writeScaleHeader(basePitch=130, octaves=5) 43 | 44 | 45 | -------------------------------------------------------------------------------- /Chapter03_Digital-Output/povToy_1up/1up.c: -------------------------------------------------------------------------------- 1 | /* 2 | POV demo by Patrick Roanhouse 3 | */ 4 | 5 | #include 6 | #include 7 | #define DELAYTIME 2 /* ms */ 8 | 9 | uint8_t Star1UP[] = { 10 | 0b10000100, 11 | 0b01101100, 12 | 0b01111110, 13 | 0b00011111, 14 | 0b01111110, 15 | 0b01101100, 16 | 0b10000100, 17 | 0b00000000, 18 | 0b00000000, 19 | 0b00000000, 20 | 0b10000010, 21 | 0b11111111, 22 | 0b11111111, 23 | 0b10000000, 24 | 0b00000000, 25 | 0b00000000, 26 | 0b01111111, 27 | 0b11111111, 28 | 0b10000000, 29 | 0b11111111, 30 | 0b01111111, 31 | 0b00000000, 32 | 0b00000000, 33 | 0b11111111, 34 | 0b11111111, 35 | 0b00110011, 36 | 0b00110011, 37 | 0b00011110, 38 | 0b00011110, 39 | }; 40 | 41 | 42 | int main(void) { 43 | uint8_t i; 44 | 45 | DDRB = 0xff; /* all output */ 46 | 47 | while (1) { /* mainloop */ 48 | for (i = 0; i < sizeof(Star1UP); i++) { 49 | /* sizeof(Star1UP) returns the number of bytes in our array, */ 50 | PORTB = Star1UP[i]; 51 | _delay_ms(DELAYTIME); 52 | } 53 | 54 | PORTB = 0; /* blank for gap between repetitions */ 55 | _delay_ms(5 * DELAYTIME); 56 | 57 | } /* end mainloop */ 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullSaw7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullTri7.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSaw7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullTri7.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/fatSaw/fullSaw7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/progmemDemo2/progmemDemo2.c: -------------------------------------------------------------------------------- 1 | /* Second steps into using program memory */ 2 | /* Storing the addresses in pointers */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "USART.h" 8 | 9 | const char myVeryLongString[] PROGMEM = "\r\nHi there, \ 10 | this is an example of a long string.\r\n\ 11 | The kind that you wouldn't want to store in RAM.\r\n"; 12 | const uint16_t sixteenBits PROGMEM = 12345; 13 | 14 | int main(void) { 15 | initUSART(); 16 | 17 | const char *stringPointer; 18 | const uint16_t *wordPointer; 19 | uint8_t i; 20 | char oneLetter; 21 | 22 | stringPointer = &myVeryLongString[0]; /* address of first char */ 23 | // stringPointer = myVeryLongString; /* same as above */ 24 | wordPointer = &sixteenBits; /* address of first byte */ 25 | 26 | while (1) { 27 | for (i = 0; i < sizeof(myVeryLongString); i++) { 28 | oneLetter = pgm_read_byte(stringPointer + i); 29 | transmitByte(oneLetter); 30 | _delay_ms(100); /* slow it down to simulate typing effect :) */ 31 | } 32 | _delay_ms(1000); 33 | 34 | printWord(pgm_read_word(wordPointer)); 35 | } /* End event loop */ 36 | return 0; /* This line is never reached */ 37 | } 38 | -------------------------------------------------------------------------------- /Chapter08_Hardware-Interrupts/helloInterrupt/helloInterrupt.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Demo of using interrupts for doing what they do best -- 4 | two things at once. 5 | 6 | Flashes LED0 at a fixed rate, interrupting whenever button is pressed. 7 | 8 | */ 9 | 10 | // ------- Preamble -------- // 11 | #include 12 | #include 13 | #include 14 | #include "pinDefines.h" 15 | 16 | ISR(INT0_vect) { /* Run every time there is a change on button */ 17 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 18 | LED_PORT |= (1 << LED1); 19 | } 20 | else { 21 | LED_PORT &= ~(1 << LED1); 22 | } 23 | } 24 | 25 | void initInterrupt0(void) { 26 | EIMSK |= (1 << INT0); /* enable INT0 */ 27 | EICRA |= (1 << ISC00); /* trigger when button changes */ 28 | sei(); /* set (global) interrupt enable bit */ 29 | } 30 | 31 | int main(void) { 32 | // -------- Inits --------- // 33 | LED_DDR = 0xff; /* all LEDs active */ 34 | BUTTON_PORT |= (1 << BUTTON); /* pullup */ 35 | initInterrupt0(); 36 | 37 | // ------ Event loop ------ // 38 | while (1) { 39 | 40 | _delay_ms(200); 41 | LED_PORT ^= (1 << LED0); 42 | 43 | } /* End event loop */ 44 | return 0; /* This line is never reached */ 45 | } 46 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSquare7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSaw7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullTri7.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes/cylonEyes.c: -------------------------------------------------------------------------------- 1 | /* Cylon Eyes */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | 7 | #define DELAYTIME 85 /* milliseconds */ 8 | #define LED_PORT PORTB 9 | #define LED_PIN PINB 10 | #define LED_DDR DDRB 11 | 12 | int main(void) { 13 | 14 | // -------- Inits --------- // 15 | uint8_t i=0; 16 | LED_DDR = 0xff; /* Data Direction Register B: 17 | all set up for output */ 18 | 19 | // ------ Event loop ------ // 20 | while (1) { 21 | 22 | while (i < 7) { 23 | LED_PORT = (1 << i); /* illuminate only i'th pin */ 24 | _delay_ms(DELAYTIME); /* wait */ 25 | i = i + 1; /* move to the next LED */ 26 | } 27 | 28 | while (i > 0) { 29 | LED_PORT = (1 << i); /* illuminate only i'th pin */ 30 | _delay_ms(DELAYTIME); /* wait */ 31 | i = i - 1; /* move to the previous LED */ 32 | } 33 | 34 | } /* End event loop */ 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSaw7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullTri7.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSquare7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter10_Pulse-Width-Modulation/pwm/pwm.c: -------------------------------------------------------------------------------- 1 | /* Quick and dirty PWM Demo */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | #include "pinDefines.h" 7 | 8 | #define LED_DELAY 20 /* microseconds */ 9 | 10 | void pwmAllPins(uint8_t brightness) { 11 | uint8_t i; 12 | LED_PORT = 0xff; /* turn on */ 13 | for (i = 0; i < 255; i++) { 14 | if (i >= brightness) { /* once it's been on long enough */ 15 | LED_PORT = 0; /* turn off */ 16 | } 17 | _delay_us(LED_DELAY); 18 | } 19 | } 20 | 21 | int main(void) { 22 | 23 | uint8_t brightness = 0; 24 | int8_t direction = 1; 25 | 26 | // -------- Inits --------- // 27 | 28 | // Init all LEDs 29 | LED_DDR = 0xff; 30 | // ------ Event loop ------ // 31 | while (1) { 32 | // Brighten and dim 33 | if (brightness == 0) { 34 | direction = 1; 35 | } 36 | if (brightness == 255) { 37 | direction = -1; 38 | } 39 | brightness += direction; 40 | pwmAllPins(brightness); 41 | 42 | 43 | } /* End event loop */ 44 | return 0; /* This line is never reached */ 45 | } 46 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSquare7.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare7[256] = { 2 | 0, 1, 3, 5, 7, 8, 10, 11, 3 | 12, 13, 14, 15, 15, 15, 15, 16, 4 | 16, 16, 16, 16, 16, 16, 16, 17, 5 | 17, 18, 19, 20, 21, 23, 24, 26, 6 | 28, 30, 32, 34, 36, 38, 39, 41, 7 | 43, 44, 45, 46, 47, 47, 48, 48, 8 | 48, 48, 48, 48, 48, 47, 47, 47, 9 | 47, 47, 48, 49, 50, 51, 52, 54, 10 | 55, 57, 60, 62, 64, 66, 69, 71, 11 | 73, 75, 77, 79, 80, 81, 82, 82, 12 | 82, 82, 82, 81, 80, 80, 79, 78, 13 | 77, 76, 75, 75, 75, 76, 76, 78, 14 | 79, 81, 84, 87, 90, 94, 98, 102, 15 | 106, 110, 114, 117, 121, 123, 125, 127, 16 | 127, 127, 125, 122, 119, 114, 108, 101, 17 | 93, 84, 74, 63, 51, 39, 26, 13, 18 | 0, -14, -27, -40, -52, -64, -75, -85, 19 | -94, -102, -109, -115, -120, -123, -126, -128, 20 | -128, -128, -126, -124, -122, -118, -115, -111, 21 | -107, -103, -99, -95, -91, -88, -85, -82, 22 | -80, -79, -77, -77, -76, -76, -76, -77, 23 | -78, -79, -80, -81, -81, -82, -83, -83, 24 | -83, -83, -83, -82, -81, -80, -78, -76, 25 | -74, -72, -70, -67, -65, -63, -61, -58, 26 | -56, -55, -53, -52, -51, -50, -49, -48, 27 | -48, -48, -48, -48, -49, -49, -49, -49, 28 | -49, -49, -49, -48, -48, -47, -46, -45, 29 | -44, -42, -40, -39, -37, -35, -33, -31, 30 | -29, -27, -25, -24, -22, -21, -20, -19, 31 | -18, -18, -17, -17, -17, -17, -17, -17, 32 | -17, -17, -16, -16, -16, -16, -15, -14, 33 | -13, -12, -11, -9, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/fatSaw/fatSaw.h: -------------------------------------------------------------------------------- 1 | 2 | // ------- Preamble -------- // 3 | #include /* Defines pins, ports, etc */ 4 | #include /* Functions to waste time */ 5 | #include 6 | #include 7 | #include "pinDefines.h" 8 | #include "macros.h" 9 | #include "fullSaw15.h" 10 | 11 | #define BASEPITCH 220 /* in tuningWord steps, which are ~1/2 Hz */ 12 | #define PHASE_RATE 7 /* controls speed of phasing effect */ 13 | 14 | #define NUMBER_OSCILLATORS 4 15 | /* 2 and 4 work just fine. 16 | 8 and 16 take too long to maintain our 31.25kHz sample rate 17 | so the pitch shifts downwards and there's all sorts of aliasing. 18 | If you're just after scary sounds, 8 and 16 are awesome, but you may want 19 | to increase the BASEPITCH to compensate. */ 20 | 21 | #define OSCILLATOR_SHIFT 2 22 | /* This is the number of bits to shift when volume mixing. 23 | 2**OSCILLATOR_SHIFT = NUMBER_OSCILLATORS 24 | If you don't change this to match the number of oscillators, you'll 25 | get clipping and digital distortion. */ 26 | 27 | 28 | static inline void initTimer0(void){ 29 | set_bit(TCCR0A, WGM00); /* Fast PWM mode */ 30 | set_bit(TCCR0A, WGM01); /* Fast PWM mode */ 31 | 32 | set_bit(TCCR0A, COM0A1); /* PWM output on OCR0A */ 33 | set_bit(SPEAKER_DDR, SPEAKER); /* enable output on pin */ 34 | 35 | set_bit(TCCR0B, CS00); /* Clock with /1 prescaler */ 36 | } 37 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullTriangle.h: -------------------------------------------------------------------------------- 1 | int8_t fullTriangle[256] = { 2 | 0, 1, 3, 5, 7, 9, 11, 13, 3 | 15, 17, 19, 21, 23, 25, 27, 29, 4 | 31, 33, 35, 37, 39, 41, 43, 45, 5 | 47, 49, 51, 53, 55, 57, 59, 61, 6 | 63, 65, 67, 69, 71, 73, 75, 77, 7 | 79, 81, 83, 85, 87, 89, 91, 93, 8 | 95, 97, 99, 101, 103, 105, 107, 109, 9 | 111, 113, 115, 117, 119, 121, 123, 125, 10 | 127, 125, 123, 121, 119, 117, 115, 113, 11 | 111, 109, 107, 105, 103, 101, 99, 97, 12 | 95, 93, 91, 89, 87, 85, 83, 81, 13 | 79, 77, 75, 73, 71, 69, 67, 65, 14 | 63, 61, 59, 57, 55, 53, 51, 49, 15 | 47, 45, 43, 41, 39, 37, 35, 33, 16 | 31, 29, 27, 25, 23, 21, 19, 17, 17 | 15, 13, 11, 9, 7, 5, 3, 1, 18 | 0, -2, -4, -6, -8, -10, -12, -14, 19 | -16, -18, -20, -22, -24, -26, -28, -30, 20 | -32, -34, -36, -38, -40, -42, -44, -46, 21 | -48, -50, -52, -54, -56, -58, -60, -62, 22 | -64, -66, -68, -70, -72, -74, -76, -78, 23 | -80, -82, -84, -86, -88, -90, -92, -94, 24 | -96, -98, -100, -102, -104, -106, -108, -110, 25 | -112, -114, -116, -118, -120, -122, -124, -126, 26 | -128, -126, -124, -122, -120, -118, -116, -114, 27 | -112, -110, -108, -106, -104, -102, -100, -98, 28 | -96, -94, -92, -90, -88, -86, -84, -82, 29 | -80, -78, -76, -74, -72, -70, -68, -66, 30 | -64, -62, -60, -58, -56, -54, -52, -50, 31 | -48, -46, -44, -42, -40, -38, -36, -34, 32 | -32, -30, -28, -26, -24, -22, -20, -18, 33 | -16, -14, -12, -10, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullTriangle.h: -------------------------------------------------------------------------------- 1 | int8_t fullTriangle[256] = { 2 | 0, 1, 3, 5, 7, 9, 11, 13, 3 | 15, 17, 19, 21, 23, 25, 27, 29, 4 | 31, 33, 35, 37, 39, 41, 43, 45, 5 | 47, 49, 51, 53, 55, 57, 59, 61, 6 | 63, 65, 67, 69, 71, 73, 75, 77, 7 | 79, 81, 83, 85, 87, 89, 91, 93, 8 | 95, 97, 99, 101, 103, 105, 107, 109, 9 | 111, 113, 115, 117, 119, 121, 123, 125, 10 | 127, 125, 123, 121, 119, 117, 115, 113, 11 | 111, 109, 107, 105, 103, 101, 99, 97, 12 | 95, 93, 91, 89, 87, 85, 83, 81, 13 | 79, 77, 75, 73, 71, 69, 67, 65, 14 | 63, 61, 59, 57, 55, 53, 51, 49, 15 | 47, 45, 43, 41, 39, 37, 35, 33, 16 | 31, 29, 27, 25, 23, 21, 19, 17, 17 | 15, 13, 11, 9, 7, 5, 3, 1, 18 | 0, -2, -4, -6, -8, -10, -12, -14, 19 | -16, -18, -20, -22, -24, -26, -28, -30, 20 | -32, -34, -36, -38, -40, -42, -44, -46, 21 | -48, -50, -52, -54, -56, -58, -60, -62, 22 | -64, -66, -68, -70, -72, -74, -76, -78, 23 | -80, -82, -84, -86, -88, -90, -92, -94, 24 | -96, -98, -100, -102, -104, -106, -108, -110, 25 | -112, -114, -116, -118, -120, -122, -124, -126, 26 | -128, -126, -124, -122, -120, -118, -116, -114, 27 | -112, -110, -108, -106, -104, -102, -100, -98, 28 | -96, -94, -92, -90, -88, -86, -84, -82, 29 | -80, -78, -76, -74, -72, -70, -68, -66, 30 | -64, -62, -60, -58, -56, -54, -52, -50, 31 | -48, -46, -44, -42, -40, -38, -36, -34, 32 | -32, -30, -28, -26, -24, -22, -20, -18, 33 | -16, -14, -12, -10, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullSaw3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/fullTri3.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSaw3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullTri3.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullTriangle.h: -------------------------------------------------------------------------------- 1 | int8_t fullTriangle[256] = { 2 | 0, 1, 3, 5, 7, 9, 11, 13, 3 | 15, 17, 19, 21, 23, 25, 27, 29, 4 | 31, 33, 35, 37, 39, 41, 43, 45, 5 | 47, 49, 51, 53, 55, 57, 59, 61, 6 | 63, 65, 67, 69, 71, 73, 75, 77, 7 | 79, 81, 83, 85, 87, 89, 91, 93, 8 | 95, 97, 99, 101, 103, 105, 107, 109, 9 | 111, 113, 115, 117, 119, 121, 123, 125, 10 | 127, 125, 123, 121, 119, 117, 115, 113, 11 | 111, 109, 107, 105, 103, 101, 99, 97, 12 | 95, 93, 91, 89, 87, 85, 83, 81, 13 | 79, 77, 75, 73, 71, 69, 67, 65, 14 | 63, 61, 59, 57, 55, 53, 51, 49, 15 | 47, 45, 43, 41, 39, 37, 35, 33, 16 | 31, 29, 27, 25, 23, 21, 19, 17, 17 | 15, 13, 11, 9, 7, 5, 3, 1, 18 | 0, -2, -4, -6, -8, -10, -12, -14, 19 | -16, -18, -20, -22, -24, -26, -28, -30, 20 | -32, -34, -36, -38, -40, -42, -44, -46, 21 | -48, -50, -52, -54, -56, -58, -60, -62, 22 | -64, -66, -68, -70, -72, -74, -76, -78, 23 | -80, -82, -84, -86, -88, -90, -92, -94, 24 | -96, -98, -100, -102, -104, -106, -108, -110, 25 | -112, -114, -116, -118, -120, -122, -124, -126, 26 | -128, -126, -124, -122, -120, -118, -116, -114, 27 | -112, -110, -108, -106, -104, -102, -100, -98, 28 | -96, -94, -92, -90, -88, -86, -84, -82, 29 | -80, -78, -76, -74, -72, -70, -68, -66, 30 | -64, -62, -60, -58, -56, -54, -52, -50, 31 | -48, -46, -44, -42, -40, -38, -36, -34, 32 | -32, -30, -28, -26, -24, -22, -20, -18, 33 | -16, -14, -12, -10, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSquare3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullTriangle.h: -------------------------------------------------------------------------------- 1 | int8_t fullTriangle[256] = { 2 | 0, 1, 3, 5, 7, 9, 11, 13, 3 | 15, 17, 19, 21, 23, 25, 27, 29, 4 | 31, 33, 35, 37, 39, 41, 43, 45, 5 | 47, 49, 51, 53, 55, 57, 59, 61, 6 | 63, 65, 67, 69, 71, 73, 75, 77, 7 | 79, 81, 83, 85, 87, 89, 91, 93, 8 | 95, 97, 99, 101, 103, 105, 107, 109, 9 | 111, 113, 115, 117, 119, 121, 123, 125, 10 | 127, 125, 123, 121, 119, 117, 115, 113, 11 | 111, 109, 107, 105, 103, 101, 99, 97, 12 | 95, 93, 91, 89, 87, 85, 83, 81, 13 | 79, 77, 75, 73, 71, 69, 67, 65, 14 | 63, 61, 59, 57, 55, 53, 51, 49, 15 | 47, 45, 43, 41, 39, 37, 35, 33, 16 | 31, 29, 27, 25, 23, 21, 19, 17, 17 | 15, 13, 11, 9, 7, 5, 3, 1, 18 | 0, -2, -4, -6, -8, -10, -12, -14, 19 | -16, -18, -20, -22, -24, -26, -28, -30, 20 | -32, -34, -36, -38, -40, -42, -44, -46, 21 | -48, -50, -52, -54, -56, -58, -60, -62, 22 | -64, -66, -68, -70, -72, -74, -76, -78, 23 | -80, -82, -84, -86, -88, -90, -92, -94, 24 | -96, -98, -100, -102, -104, -106, -108, -110, 25 | -112, -114, -116, -118, -120, -122, -124, -126, 26 | -128, -126, -124, -122, -120, -118, -116, -114, 27 | -112, -110, -108, -106, -104, -102, -100, -98, 28 | -96, -94, -92, -90, -88, -86, -84, -82, 29 | -80, -78, -76, -74, -72, -70, -68, -66, 30 | -64, -62, -60, -58, -56, -54, -52, -50, 31 | -48, -46, -44, -42, -40, -38, -36, -34, 32 | -32, -30, -28, -26, -24, -22, -20, -18, 33 | -16, -14, -12, -10, -8, -6, -4, -2 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSaw3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullTri3.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/fatSaw/fullSaw3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSaw3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSaw3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullTri3.h: -------------------------------------------------------------------------------- 1 | int8_t fullTri3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSquare3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSquare3.h: -------------------------------------------------------------------------------- 1 | int8_t fullSquare3[256] = { 2 | 0, 2, 4, 6, 8, 10, 12, 14, 3 | 16, 18, 20, 22, 23, 25, 27, 28, 4 | 29, 31, 32, 33, 34, 35, 35, 36, 5 | 37, 37, 38, 38, 38, 38, 39, 39, 6 | 39, 39, 39, 38, 38, 38, 38, 38, 7 | 38, 38, 38, 38, 38, 38, 38, 38, 8 | 39, 39, 40, 40, 41, 42, 43, 44, 9 | 45, 46, 47, 49, 51, 52, 54, 56, 10 | 58, 61, 63, 65, 68, 70, 73, 76, 11 | 79, 81, 84, 87, 90, 93, 96, 98, 12 | 101, 104, 106, 109, 111, 114, 116, 118, 13 | 120, 121, 123, 124, 125, 126, 126, 127, 14 | 127, 127, 126, 126, 125, 124, 122, 120, 15 | 118, 116, 113, 110, 107, 104, 100, 96, 16 | 92, 87, 83, 78, 72, 67, 62, 56, 17 | 50, 44, 38, 32, 25, 19, 12, 6, 18 | 0, -7, -13, -20, -26, -33, -39, -45, 19 | -51, -57, -63, -68, -73, -79, -84, -88, 20 | -93, -97, -101, -105, -108, -111, -114, -117, 21 | -119, -121, -123, -125, -126, -127, -127, -128, 22 | -128, -128, -127, -127, -126, -125, -124, -122, 23 | -121, -119, -117, -115, -112, -110, -107, -105, 24 | -102, -99, -97, -94, -91, -88, -85, -82, 25 | -80, -77, -74, -71, -69, -66, -64, -62, 26 | -59, -57, -55, -53, -52, -50, -48, -47, 27 | -46, -45, -44, -43, -42, -41, -41, -40, 28 | -40, -39, -39, -39, -39, -39, -39, -39, 29 | -39, -39, -39, -39, -39, -39, -40, -40, 30 | -40, -40, -40, -39, -39, -39, -39, -38, 31 | -38, -37, -36, -36, -35, -34, -33, -32, 32 | -30, -29, -28, -26, -24, -23, -21, -19, 33 | -17, -15, -13, -11, -9, -7, -5, -3 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dialTone/fullSine.h: -------------------------------------------------------------------------------- 1 | int8_t fullSine[256] = { 2 | 0, 3, 6, 9, 12, 15, 18, 21, 3 | 24, 27, 30, 34, 37, 39, 42, 45, 4 | 48, 51, 54, 57, 60, 62, 65, 68, 5 | 70, 73, 75, 78, 80, 83, 85, 87, 6 | 90, 92, 94, 96, 98, 100, 102, 104, 7 | 106, 107, 109, 110, 112, 113, 115, 116, 8 | 117, 118, 120, 121, 122, 122, 123, 124, 9 | 125, 125, 126, 126, 126, 127, 127, 127, 10 | 127, 127, 127, 127, 126, 126, 126, 125, 11 | 125, 124, 123, 122, 122, 121, 120, 118, 12 | 117, 116, 115, 113, 112, 110, 109, 107, 13 | 106, 104, 102, 100, 98, 96, 94, 92, 14 | 90, 87, 85, 83, 80, 78, 75, 73, 15 | 70, 68, 65, 62, 60, 57, 54, 51, 16 | 48, 45, 42, 39, 37, 34, 30, 27, 17 | 24, 21, 18, 15, 12, 9, 6, 3, 18 | 0, -4, -7, -10, -13, -16, -19, -22, 19 | -25, -28, -31, -35, -38, -40, -43, -46, 20 | -49, -52, -55, -58, -61, -63, -66, -69, 21 | -71, -74, -76, -79, -81, -84, -86, -88, 22 | -91, -93, -95, -97, -99, -101, -103, -105, 23 | -107, -108, -110, -111, -113, -114, -116, -117, 24 | -118, -119, -121, -122, -123, -123, -124, -125, 25 | -126, -126, -127, -127, -127, -128, -128, -128, 26 | -128, -128, -128, -128, -127, -127, -127, -126, 27 | -126, -125, -124, -123, -123, -122, -121, -119, 28 | -118, -117, -116, -114, -113, -111, -110, -108, 29 | -107, -105, -103, -101, -99, -97, -95, -93, 30 | -91, -88, -86, -84, -81, -79, -76, -74, 31 | -71, -69, -66, -63, -61, -58, -55, -52, 32 | -49, -46, -43, -40, -38, -35, -31, -28, 33 | -25, -22, -19, -16, -13, -10, -7, -4 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/progmemDemo4/progmemDemo4.c: -------------------------------------------------------------------------------- 1 | /* Fourth step into using program memory */ 2 | /* Passing data array pointers to functions */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "USART.h" 8 | 9 | const uint16_t myData[] PROGMEM = 10 | { 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 10000 }; 11 | const uint16_t myData2[] PROGMEM = { 123, 456, 789, 012, 345, 678, 999 }; 12 | 13 | void printData_Progmem(const uint16_t * dataPointer, uint8_t length) { 14 | while (length) { 15 | printWord((uint16_t) dataPointer); /* print out address */ 16 | printString(": "); 17 | printWord(pgm_read_word(dataPointer)); /* print out data */ 18 | printString("\r\n"); 19 | dataPointer++; /* move to next byte */ 20 | length--; /* one less byte to go */ 21 | _delay_ms(100); 22 | } 23 | } 24 | 25 | int main(void) { 26 | initUSART(); 27 | while (1) { 28 | printData_Progmem(myData, sizeof(myData) / 2); 29 | printString("\r\n"); 30 | _delay_ms(1000); 31 | printData_Progmem(myData2, sizeof(myData2) / sizeof(myData2[0])); 32 | printString("\r\n"); 33 | _delay_ms(1000); 34 | } /* End event loop */ 35 | return 0; /* This line is never reached */ 36 | } 37 | -------------------------------------------------------------------------------- /AVR-Programming-Library/README.md: -------------------------------------------------------------------------------- 1 | AVR-Programming-Library 2 | ======================= 3 | 4 | Files that are re-used throughout the book *Make: AVR Programming* 5 | 6 | * **pinDefines.h** 7 | Includes all of the pin definitions for the projects in *Make: AVR Programming*. When you 8 | need to know what to hook up where, have a look here. 9 | 10 | * **USART.c** and **USART.h** 11 | These are the main utility files used for serial input/output in the book. They're not 12 | particularly clever, but they have a tiny memory and resource footprint and get you 13 | up and running very quickly. 14 | 15 | * **binaryMacro.h** 16 | If you're using a compiler other than a recent AVR-GCC, it may not support 17 | native binary digits (e.g. 0b00111010). If so, this include file has a pre-processor 18 | macro that will let you enter them similarly: B8(01010101). 19 | 20 | * **macros.h** 21 | This file includes pre-processor macro definitions for bit-twiddling: 22 | set_bit, clear_bit, and toggle_bit. Useful for those days when you're feeling 23 | lazy, or have forgotten your bit-wise logic operations. 24 | 25 | * **portpins.h** 26 | This is a recent version of the portpins.h file included with the Arduino environment. 27 | It includes the AVR pin definitions of the form PB1 and similar. The version included 28 | with Arduino is very old -- you'll want to replace it with this one if you want to write 29 | in C using the Arduino IDE. Or you can include this file directly in your code. 30 | 31 | -------------------------------------------------------------------------------- /Chapter07_Analog-to-Digital-Conversion-I/lightSensor/lightSensor.c: -------------------------------------------------------------------------------- 1 | // Quick Demo of light sensor 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include "pinDefines.h" 7 | 8 | // -------- Functions --------- // 9 | static inline void initADC0(void) { 10 | ADMUX |= (1 << REFS0); /* reference voltage on AVCC */ 11 | ADCSRA |= (1 << ADPS2); /* ADC clock prescaler /16 */ 12 | ADCSRA |= (1 << ADEN); /* enable ADC */ 13 | } 14 | 15 | int main(void) { 16 | 17 | // -------- Inits --------- // 18 | uint8_t ledValue; 19 | uint16_t adcValue; 20 | uint8_t i; 21 | 22 | initADC0(); 23 | LED_DDR = 0xff; 24 | 25 | // ------ Event loop ------ // 26 | while (1) { 27 | 28 | ADCSRA |= (1 << ADSC); /* start ADC conversion */ 29 | loop_until_bit_is_clear(ADCSRA, ADSC); /* wait until done */ 30 | adcValue = ADC; /* read ADC in */ 31 | /* Have 10 bits, want 3 (eight LEDs after all) */ 32 | ledValue = (adcValue >> 7); 33 | /* Light up all LEDs up to ledValue */ 34 | LED_PORT = 0; 35 | for (i = 0; i <= ledValue; i++) { 36 | LED_PORT |= (1 << i); 37 | } 38 | _delay_ms(50); 39 | } /* End event loop */ 40 | return 0; /* This line is never reached */ 41 | } 42 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/fullSine.h: -------------------------------------------------------------------------------- 1 | int8_t fullSine[256] = { 2 | 0, 3, 6, 9, 12, 15, 18, 21, 3 | 24, 27, 30, 34, 37, 39, 42, 45, 4 | 48, 51, 54, 57, 60, 62, 65, 68, 5 | 70, 73, 75, 78, 80, 83, 85, 87, 6 | 90, 92, 94, 96, 98, 100, 102, 104, 7 | 106, 107, 109, 110, 112, 113, 115, 116, 8 | 117, 118, 120, 121, 122, 122, 123, 124, 9 | 125, 125, 126, 126, 126, 127, 127, 127, 10 | 127, 127, 127, 127, 126, 126, 126, 125, 11 | 125, 124, 123, 122, 122, 121, 120, 118, 12 | 117, 116, 115, 113, 112, 110, 109, 107, 13 | 106, 104, 102, 100, 98, 96, 94, 92, 14 | 90, 87, 85, 83, 80, 78, 75, 73, 15 | 70, 68, 65, 62, 60, 57, 54, 51, 16 | 48, 45, 42, 39, 37, 34, 30, 27, 17 | 24, 21, 18, 15, 12, 9, 6, 3, 18 | 0, -4, -7, -10, -13, -16, -19, -22, 19 | -25, -28, -31, -35, -38, -40, -43, -46, 20 | -49, -52, -55, -58, -61, -63, -66, -69, 21 | -71, -74, -76, -79, -81, -84, -86, -88, 22 | -91, -93, -95, -97, -99, -101, -103, -105, 23 | -107, -108, -110, -111, -113, -114, -116, -117, 24 | -118, -119, -121, -122, -123, -123, -124, -125, 25 | -126, -126, -127, -127, -127, -128, -128, -128, 26 | -128, -128, -128, -128, -127, -127, -127, -126, 27 | -126, -125, -124, -123, -123, -122, -121, -119, 28 | -118, -117, -116, -114, -113, -111, -110, -108, 29 | -107, -105, -103, -101, -99, -97, -95, -93, 30 | -91, -88, -86, -84, -81, -79, -76, -74, 31 | -71, -69, -66, -63, -61, -58, -55, -52, 32 | -49, -46, -43, -40, -38, -35, -31, -28, 33 | -25, -22, -19, -16, -13, -10, -7, -4 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/fullSine.h: -------------------------------------------------------------------------------- 1 | int8_t fullSine[256] = { 2 | 0, 3, 6, 9, 12, 15, 18, 21, 3 | 24, 27, 30, 34, 37, 39, 42, 45, 4 | 48, 51, 54, 57, 60, 62, 65, 68, 5 | 70, 73, 75, 78, 80, 83, 85, 87, 6 | 90, 92, 94, 96, 98, 100, 102, 104, 7 | 106, 107, 109, 110, 112, 113, 115, 116, 8 | 117, 118, 120, 121, 122, 122, 123, 124, 9 | 125, 125, 126, 126, 126, 127, 127, 127, 10 | 127, 127, 127, 127, 126, 126, 126, 125, 11 | 125, 124, 123, 122, 122, 121, 120, 118, 12 | 117, 116, 115, 113, 112, 110, 109, 107, 13 | 106, 104, 102, 100, 98, 96, 94, 92, 14 | 90, 87, 85, 83, 80, 78, 75, 73, 15 | 70, 68, 65, 62, 60, 57, 54, 51, 16 | 48, 45, 42, 39, 37, 34, 30, 27, 17 | 24, 21, 18, 15, 12, 9, 6, 3, 18 | 0, -4, -7, -10, -13, -16, -19, -22, 19 | -25, -28, -31, -35, -38, -40, -43, -46, 20 | -49, -52, -55, -58, -61, -63, -66, -69, 21 | -71, -74, -76, -79, -81, -84, -86, -88, 22 | -91, -93, -95, -97, -99, -101, -103, -105, 23 | -107, -108, -110, -111, -113, -114, -116, -117, 24 | -118, -119, -121, -122, -123, -123, -124, -125, 25 | -126, -126, -127, -127, -127, -128, -128, -128, 26 | -128, -128, -128, -128, -127, -127, -127, -126, 27 | -126, -125, -124, -123, -123, -122, -121, -119, 28 | -118, -117, -116, -114, -113, -111, -110, -108, 29 | -107, -105, -103, -101, -99, -97, -95, -93, 30 | -91, -88, -86, -84, -81, -79, -76, -74, 31 | -71, -69, -66, -63, -61, -58, -55, -52, 32 | -49, -46, -43, -40, -38, -35, -31, -28, 33 | -25, -22, -19, -16, -13, -10, -7, -4 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_interrupts/fullSine.h: -------------------------------------------------------------------------------- 1 | int8_t fullSine[256] = { 2 | 0, 3, 6, 9, 12, 15, 18, 21, 3 | 24, 27, 30, 34, 37, 39, 42, 45, 4 | 48, 51, 54, 57, 60, 62, 65, 68, 5 | 70, 73, 75, 78, 80, 83, 85, 87, 6 | 90, 92, 94, 96, 98, 100, 102, 104, 7 | 106, 107, 109, 110, 112, 113, 115, 116, 8 | 117, 118, 120, 121, 122, 122, 123, 124, 9 | 125, 125, 126, 126, 126, 127, 127, 127, 10 | 127, 127, 127, 127, 126, 126, 126, 125, 11 | 125, 124, 123, 122, 122, 121, 120, 118, 12 | 117, 116, 115, 113, 112, 110, 109, 107, 13 | 106, 104, 102, 100, 98, 96, 94, 92, 14 | 90, 87, 85, 83, 80, 78, 75, 73, 15 | 70, 68, 65, 62, 60, 57, 54, 51, 16 | 48, 45, 42, 39, 37, 34, 30, 27, 17 | 24, 21, 18, 15, 12, 9, 6, 3, 18 | 0, -4, -7, -10, -13, -16, -19, -22, 19 | -25, -28, -31, -35, -38, -40, -43, -46, 20 | -49, -52, -55, -58, -61, -63, -66, -69, 21 | -71, -74, -76, -79, -81, -84, -86, -88, 22 | -91, -93, -95, -97, -99, -101, -103, -105, 23 | -107, -108, -110, -111, -113, -114, -116, -117, 24 | -118, -119, -121, -122, -123, -123, -124, -125, 25 | -126, -126, -127, -127, -127, -128, -128, -128, 26 | -128, -128, -128, -128, -127, -127, -127, -126, 27 | -126, -125, -124, -123, -123, -122, -121, -119, 28 | -118, -117, -116, -114, -113, -111, -110, -108, 29 | -107, -105, -103, -101, -99, -97, -95, -93, 30 | -91, -88, -86, -84, -81, -79, -76, -74, 31 | -71, -69, -66, -63, -61, -58, -55, -52, 32 | -49, -46, -43, -40, -38, -35, -31, -28, 33 | -25, -22, -19, -16, -13, -10, -7, -4 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/debouncer/debouncer.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include "pinDefines.h" 6 | 7 | #include 8 | #define DEBOUNCE_TIME 1000 /* microseconds */ 9 | 10 | uint8_t debounce(void) { 11 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { /* button is pressed now */ 12 | _delay_us(DEBOUNCE_TIME); 13 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { /* still pressed */ 14 | return (1); 15 | } 16 | } 17 | return 0; 18 | } 19 | 20 | int main(void) { 21 | // -------- Inits --------- // 22 | uint8_t buttonWasPressed=0; /* state */ 23 | BUTTON_PORT |= (1 << BUTTON); /* enable the pullup on the button */ 24 | LED_DDR = (1 << LED0); /* set up LED for output */ 25 | 26 | // ------ Event loop ------ // 27 | while (1) { 28 | if (debounce()) { /* debounced button press */ 29 | if (buttonWasPressed == 0) { /* but wasn't last time through */ 30 | LED_PORT ^= (1 << LED0); /* do whatever */ 31 | buttonWasPressed = 1; /* update the state */ 32 | } 33 | } 34 | else { /* button is not pressed now */ 35 | buttonWasPressed = 0; /* update the state */ 36 | } 37 | 38 | } /* End event loop */ 39 | return 0; /* This line is never reached */ 40 | } 41 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/_servoClockFunctions.c: -------------------------------------------------------------------------------- 1 | #include "_servoClockFunctions.h" 2 | 3 | // Realtime-clock handling functions 4 | void initTimer0_Clock(void) { 5 | /* Normal mode, just used for the overflow interrupt */ 6 | TCCR0B |= (1 << CS00); /* 8 MHz clock = ~31250 overflows per second */ 7 | TIMSK0 |= (1 << TOIE0); /* timer overflow interrupt enable */ 8 | } 9 | 10 | void everySecond(void) { 11 | seconds++; 12 | if (seconds > 59) { 13 | seconds = 0; 14 | everyMinute(); 15 | } 16 | LED_PORT ^= (1 << LED0); /* blink */ 17 | printTime(hours, minutes, seconds); /* serial output */ 18 | /* Turn off servo motor after three seconds into new minute */ 19 | if (seconds == 3) { 20 | disableServo(); 21 | } 22 | } 23 | void everyMinute(void) { 24 | minutes++; 25 | if (minutes > 59) { 26 | minutes = 0; 27 | everyHour(); 28 | } 29 | // If during business hours, set servo to new minute 30 | // Otherwise, don't need to move motor when laser is off 31 | if ((hours >= START_TIME) && (hours < STOP_TIME)) { 32 | setServoPosition(); 33 | enableServo(); 34 | LASER_PORT |= (1 << LASER); /* make sure laser is on */ 35 | } 36 | else { /* make sure laser is off */ 37 | LASER_PORT &= ~(1 << LASER); 38 | } 39 | } 40 | void everyHour(void) { 41 | hours++; 42 | if (hours > 23) { /* loop around at end of day */ 43 | hours = 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Chapter05_Serial-IO/serialOrgan/scaleGenerator.py: -------------------------------------------------------------------------------- 1 | # scaleGenerator.py 2 | # Scales are in terms of times per cycle (period) rather 3 | # than pitch. 4 | # 5 | 6 | import math 7 | 8 | SCALE = ['C', 'Cx', 'D', 'Dx', 'E', 'F', 'Fx', 'G', 'Gx', 'A', 'Ax', 'B'] 9 | 10 | def calculateOctave(baseLength): 11 | periods = [baseLength / math.exp(x*math.log(2)/12) for x in range(0, 12)] 12 | periods = [int(round(x)) for x in periods] 13 | return( zip(SCALE, periods) ) 14 | 15 | def makePitches(basePitch, numOctaves): 16 | pitchList = [] 17 | for octave in range(0, numOctaves): 18 | for note, period in calculateOctave(basePitch / 2**octave): 19 | if period < 65500: 20 | noteString = note + str(octave) 21 | pitchList.append((noteString,period)) 22 | return(pitchList) 23 | 24 | def makeDefines(basePitch, numOctaves): 25 | pitchList = makePitches(basePitch, numOctaves) 26 | defineString = "// Scale in the key of {} \n".format(basePitch) 27 | defineString += "// Automatically generated by scaleGenerator.py \n\n" 28 | for (note, length) in pitchList: 29 | defineString += "#define {:<5}{:>6}\n".format(note, length) 30 | return(defineString) 31 | 32 | if __name__ == "__main__": 33 | 34 | ## Change these if you like 35 | BASEPITCH = 25000 36 | OCTAVES = 8 37 | OUTFILE = "scale16.h" 38 | 39 | ## Write it out to a file 40 | out = open(OUTFILE, "w") 41 | out.write(makeDefines(BASEPITCH, OCTAVES)) 42 | out.close() 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/avrMusicBox/scaleGenerator.py: -------------------------------------------------------------------------------- 1 | # scaleGenerator.py 2 | # Scales are in terms of times per cycle (period) rather 3 | # than pitch. 4 | # 5 | 6 | import math 7 | 8 | SCALE = ['C', 'Cx', 'D', 'Dx', 'E', 'F', 'Fx', 'G', 'Gx', 'A', 'Ax', 'B'] 9 | 10 | def calculateOctave(baseLength): 11 | periods = [baseLength / math.exp(x*math.log(2)/12) for x in range(0, 12)] 12 | periods = [int(round(x)) for x in periods] 13 | return( zip(SCALE, periods) ) 14 | 15 | def makePitches(basePitch, numOctaves): 16 | pitchList = [] 17 | for octave in range(0, numOctaves): 18 | for note, period in calculateOctave(basePitch / 2**octave): 19 | if period < 65500: 20 | noteString = note + str(octave) 21 | pitchList.append((noteString,period)) 22 | return(pitchList) 23 | 24 | def makeDefines(basePitch, numOctaves): 25 | pitchList = makePitches(basePitch, numOctaves) 26 | defineString = "// Scale in the key of {} \n".format(basePitch) 27 | defineString += "// Automatically generated by scaleGenerator.py \n\n" 28 | for (note, length) in pitchList: 29 | defineString += "#define {:<5}{:>6}\n".format(note, length) 30 | return(defineString) 31 | 32 | if __name__ == "__main__": 33 | 34 | ## Change these if you like 35 | BASEPITCH = 10000 36 | OCTAVES = 8 37 | OUTFILE = "scale16.h" 38 | 39 | ## Write it out to a file 40 | out = open(OUTFILE, "w") 41 | out.write(makeDefines(BASEPITCH, OCTAVES)) 42 | out.close() 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /setupProject/setupProject.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | ## Simple Python routine for creating a new AVR project 3 | ## Feel free to extend this to meet your needs 4 | 5 | ## In particular, main.h includes nearly every AVR library you'll ever need 6 | ## which is no problem, b/c the linker will just ignore the unused ones. 7 | ## But if you're not using them, it might cause confusion later. 8 | ## Trim them down to fit? 9 | 10 | ## Or, if you're feeling DIY, you can just copy the Makefile, main.c and main.h 11 | ## into a new directory yourself. The other files are optional, but handy. 12 | 13 | import os 14 | import shutil 15 | import sys 16 | 17 | ## Get command-line input 18 | class UsageError(Exception): 19 | pass 20 | try: 21 | newProjectName = sys.argv[1] 22 | except IndexError: 23 | raise(UsageError("Please specify a project name on the command-line.\n")) 24 | 25 | ## Create new project directory... 26 | ## ... in parent directory 27 | ## relativeDirectory = os.path.join(os.path.pardir, newProjectName) 28 | ## ... or in this directory, and you get to move it yourself. 29 | relativeDirectory = newProjectName 30 | os.mkdir(relativeDirectory) 31 | 32 | ## Files copied directly over... 33 | def copyToNewDirectory(whichFile, newDirectory): 34 | shutil.copy(whichFile, newDirectory) 35 | ## ... these ones. 36 | for filename in ["Makefile", "main.c", "main.h", "USART.h", "USART.c", "macros.h"]: 37 | copyToNewDirectory(filename, relativeDirectory) 38 | 39 | print "Copied Makefile, main.c, and main.h into %s." % relativeDirectory 40 | print "Time to start coding." 41 | 42 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/toggleButton_debounced/toggleButton_debounced.c: -------------------------------------------------------------------------------- 1 | /* 2 | Demonstrates using state to detect button presses 3 | */ 4 | 5 | // ------- Preamble -------- // 6 | #include 7 | #include "pinDefines.h" 8 | 9 | #include 10 | #define DEBOUNCE_TIME 5 /* microseconds */ 11 | 12 | uint8_t debouncePress(void) { 13 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { /* button is pressed now */ 14 | _delay_ms(DEBOUNCE_TIME); 15 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { /* still pressed */ 16 | return (1); 17 | } 18 | } 19 | return 0; 20 | } 21 | 22 | int main(void) { 23 | // -------- Inits --------- // 24 | uint8_t buttonWasPressed=0; /* state */ 25 | BUTTON_PORT |= (1 << BUTTON); /* enable the pullup on the button */ 26 | LED_DDR = (1 << LED0); /* set up LED for output */ 27 | 28 | // ------ Event loop ------ // 29 | while (1) { 30 | if (debouncePress()) { 31 | if (buttonWasPressed == 0) { /* but wasn't last time through */ 32 | LED_PORT ^= (1 << LED0); /* do whatever */ 33 | buttonWasPressed = 1; /* update the state */ 34 | } 35 | } 36 | else { /* button is not pressed now */ 37 | buttonWasPressed = 0; /* update the state */ 38 | } 39 | 40 | } /* End event loop */ 41 | return 0; /* This line is never reached */ 42 | } 43 | -------------------------------------------------------------------------------- /Chapter03_Digital-Output/povToy_invaders/invaders.c: -------------------------------------------------------------------------------- 1 | /* 2 | Space Invaders POV demo by Elliot Williams 3 | This version stores the displays in arrays, 4 | loops over their elements in a function. 5 | */ 6 | 7 | #include 8 | #include 9 | #define DELAYTIME 2 /* ms */ 10 | 11 | #define LED_PORT PORTB 12 | #define LED_DDR DDRB 13 | 14 | uint8_t invaderData1[] = { 15 | 0b01110000, 16 | 0b00011000, 17 | 0b11111101, 18 | 0b10110110, 19 | 0b00111100, 20 | 0b00111100, 21 | 0b00111100, 22 | 0b10110110, 23 | 0b11111101, 24 | 0b00011000, 25 | 0b01110000 26 | }; 27 | 28 | uint8_t invaderData2[] = { 29 | 0b00001110, 30 | 0b00011000, 31 | 0b10111101, 32 | 0b01110110, 33 | 0b00111100, 34 | 0b00111100, 35 | 0b00111100, 36 | 0b01110110, 37 | 0b10111101, 38 | 0b00011000, 39 | 0b00001110 40 | }; 41 | 42 | 43 | void pause(void){ 44 | uint8_t i; 45 | for (i=0; i<5; i++){ 46 | _delay_ms(DELAYTIME); 47 | } 48 | } 49 | 50 | void POVDisplay(uint8_t povData[], uint8_t numberRows) { 51 | uint8_t i; 52 | for (i = 0; i < numberRows; ++i) { 53 | LED_PORT = povData[i]; 54 | _delay_ms(DELAYTIME); 55 | } 56 | pause(); 57 | } 58 | 59 | int main(void) { 60 | 61 | LED_DDR = 0xff; /* set all LEDs to output */ 62 | 63 | while (1) { /* mainloop */ 64 | 65 | POVDisplay(invaderData1, sizeof(invaderData1)); 66 | POVDisplay(invaderData2, sizeof(invaderData2)); 67 | 68 | } /* end mainloop */ 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/vigenereCipher/vigenereCipher.c_outline: -------------------------------------------------------------------------------- 1 | /* 2 | Vigenere Cipher encoder / decoder demo 3 | And an excuse to play around with EEPROM memory 4 | */ 5 | 6 | #include "vigenereCipher.h" 7 | 8 | // -------- Functions --------- // 9 | 10 | void printFromEEPROM(char *eepromString); 11 | void enterText(char text[]); 12 | void displayCodes(void); 13 | void changeCode(char codeBuffer[]); 14 | void selectCode(char code[]); 15 | void encodeVigenere(char text[], char code[]); 16 | void decodeVigenere(char text[], char code[]); 17 | 18 | int main(void) { 19 | // -------- Inits --------- // 20 | 21 | char textBuffer[MAX_TEXT_LENGTH]; 22 | char codeString[CODE_LEN]; 23 | char input; 24 | initUSART(); 25 | 26 | // ------ Event loop ------ // 27 | while (1) { 28 | 29 | // Menu 30 | printFromEEPROM(welcomeString); 31 | // .... more fany menu printing 32 | printFromEEPROM(menuDecode); 33 | input = receiveByte(); 34 | 35 | switch (input) { 36 | case 'e': // encode 37 | encodeVigenere(textBuffer, codeString); 38 | break; 39 | case 'd': // decode 40 | decodeVigenere(textBuffer, codeString); 41 | break; 42 | case 'n': // new text 43 | printFromEEPROM(promptTypeText); 44 | enterText(textBuffer); 45 | break; 46 | case 'c': // choose code 47 | selectCode(codeString); 48 | break; 49 | case 'x': // change code 50 | changeCode(codeString); 51 | break; 52 | } 53 | } /* End event loop */ 54 | return (0); /* This line is never reached */ 55 | } 56 | -------------------------------------------------------------------------------- /Chapter10_Pulse-Width-Modulation/pwm_cross-fading_cylons/cross-fading_cylons.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Cross-fading Cylon Eyes 4 | A PWM demo 5 | 6 | */ 7 | 8 | // ------- Preamble -------- // 9 | #include /* Defines pins, ports, etc */ 10 | #include /* Functions to waste time */ 11 | #include "pinDefines.h" 12 | 13 | 14 | int main(void) { 15 | 16 | uint8_t thisEye = 0; 17 | uint8_t nextEye = 1; 18 | uint8_t brightness = 0; 19 | int8_t direction = 1; 20 | uint8_t i; 21 | 22 | // -------- Inits --------- // 23 | 24 | // Init all LEDs 25 | LED_DDR = 0xff; 26 | SPEAKER_DDR |= (1 << SPEAKER); 27 | // ------ Event loop ------ // 28 | while (1) { 29 | 30 | // PWM 31 | for (brightness = 0; brightness < 255; brightness++) { 32 | for (i = 0; i < 255; i++) { 33 | if (i < brightness) { 34 | LED_PORT &= ~(1 << thisEye); /* dimming */ 35 | LED_PORT |= (1 << nextEye); /* getting brighter */ 36 | } 37 | else { 38 | LED_PORT |= (1 << thisEye); 39 | LED_PORT &= ~(1 << nextEye); 40 | } 41 | LED_PORT &= ~(1 << thisEye); /* make sure it's off */ 42 | } 43 | } 44 | 45 | // Cylon Scan 46 | thisEye += direction; /* move on to next eye */ 47 | 48 | if (thisEye == 0) { 49 | direction = 1; 50 | } 51 | if (thisEye == 7) { 52 | direction = -1; 53 | } 54 | 55 | nextEye = thisEye + direction; 56 | 57 | 58 | } /* End event loop */ 59 | return 0; /* This line is never reached */ 60 | } 61 | -------------------------------------------------------------------------------- /Chapter16_SPI/spiEEPROMDemo/spiEEPROMDemo.c: -------------------------------------------------------------------------------- 1 | /* SPI EEPROM 25LC256 Demo */ 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | 7 | #include "pinDefines.h" 8 | 9 | #include "USART.h" 10 | #include "25LC256.h" 11 | 12 | int main(void) { 13 | uint8_t i; 14 | uint8_t address; 15 | 16 | // -------- Inits --------- // 17 | initSPI(); 18 | initUSART(); 19 | 20 | // ------ Event loop ------ // 21 | while (1) { 22 | printString("\r\n==== EEPROM Memory Playground ====\r\n"); 23 | printString("Address Value\r\n"); 24 | 25 | for (i = 0; i < 10; i++) { /* print out first ten bytes of memory */ 26 | printString(" "); 27 | printByte(i); 28 | printString(" "); 29 | printByte(EEPROM_readByte(i)); 30 | printString("\r\n"); 31 | } 32 | printString(" [e] to erase all memory\r\n"); 33 | printString(" [w] to write byte to memory\r\n\r\n"); 34 | 35 | switch (receiveByte()) { /* take input */ 36 | case 'e': 37 | printString("Clearing EEPROM, this could take a few seconds.\r\n"); 38 | EEPROM_clearAll(); 39 | break; 40 | case 'w': 41 | printString("Which memory slot would you like to write to?\r\n"); 42 | address = getNumber(); 43 | printString("\r\nWhat number would you like to store there?\r\n"); 44 | i = getNumber(); 45 | EEPROM_writeByte(address, i); 46 | printString("\r\n"); 47 | break; 48 | default: 49 | printString("What??\r\n"); 50 | } 51 | 52 | 53 | } /* End event loop */ 54 | return 0; /* This line is never reached */ 55 | } 56 | -------------------------------------------------------------------------------- /Chapter06_Digital-Input/avrMusicBox/avrMusicBox.c: -------------------------------------------------------------------------------- 1 | // Music Box Input Demo 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include "organ.h" 7 | #include "scale16.h" 8 | #include "pinDefines.h" 9 | 10 | #define SONG_LENGTH (sizeof(song) / sizeof(uint16_t)) 11 | 12 | int main(void) { 13 | const uint16_t song[] = { 14 | E6, E6, E6, C6, E6, G6, G5, 15 | C6, G5, E5, A5, B5, Ax5, A5, 16 | G5, E6, G6, A6, F6, G6, E6, C6, D6, B5, 17 | C6, G5, E5, A5, B5, Ax5, A5, 18 | G5, E6, G6, A6, F6, G6, E6, C6, D6, B5, 19 | /* etc */ 20 | }; 21 | /* starting at end b/c routine starts by incrementing and then playing 22 | this makes the song start at the beginning after reboot */ 23 | uint8_t whichNote = SONG_LENGTH - 1; 24 | uint8_t wasButtonPressed = 0; 25 | 26 | // -------- Inits --------- // 27 | SPEAKER_DDR |= (1 << SPEAKER); /* speaker for output */ 28 | BUTTON_PORT |= (1 << BUTTON); /* pullup on button */ 29 | 30 | // ------ Event loop ------ // 31 | while (1) { 32 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 33 | if (!wasButtonPressed) { /* if it's a new press ... */ 34 | whichNote++; /* advance to next note */ 35 | /* but don't run over the end */ 36 | if (whichNote == SONG_LENGTH) { 37 | whichNote = 0; 38 | } 39 | wasButtonPressed = 1; 40 | } 41 | playNote(song[whichNote], 1600); 42 | } 43 | else { 44 | wasButtonPressed = 0; 45 | } 46 | } /* End event loop */ 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter10_Pulse-Width-Modulation/pwmOnAnyPin/pwmOnAnyPin.c: -------------------------------------------------------------------------------- 1 | // Quick and dirty demo of how to get PWM on any pin with interrupts 2 | // ------- Preamble -------- // 3 | #include 4 | #include 5 | #include 6 | #include "pinDefines.h" 7 | 8 | #define DELAY 3 9 | 10 | volatile uint8_t brightnessA; 11 | volatile uint8_t brightnessB; 12 | 13 | // -------- Functions --------- // 14 | static inline void initTimer0(void) { 15 | /* must be /64 or more for ISR timing */ 16 | TCCR0B |= (1 << CS01) | (1 << CS00); 17 | /* both output compare interrupts */ 18 | TIMSK0 |= ((1 << OCIE0A) | (1 << OCIE1B)); 19 | TIMSK0 |= (1 << TOIE0); /* overflow interrupt enable */ 20 | sei(); 21 | } 22 | 23 | ISR(TIMER0_OVF_vect) { 24 | LED_PORT = 0xff; 25 | OCR0A = brightnessA; 26 | OCR0B = brightnessB; 27 | } 28 | ISR(TIMER0_COMPA_vect) { 29 | LED_PORT &= 0b11110000; /* turn off low four LEDs */ 30 | } 31 | ISR(TIMER0_COMPB_vect) { 32 | LED_PORT &= 0b00001111; /* turn off high four LEDs */ 33 | } 34 | 35 | int main(void) { 36 | // -------- Inits --------- // 37 | 38 | uint8_t i; 39 | LED_DDR = 0xff; 40 | initTimer0(); 41 | 42 | // ------ Event loop ------ // 43 | while (1) { 44 | 45 | for (i = 0; i < 255; i++) { 46 | _delay_ms(DELAY); 47 | brightnessA = i; 48 | brightnessB = 255 - i; 49 | } 50 | 51 | for (i = 254; i > 0; i--) { 52 | _delay_ms(DELAY); 53 | brightnessA = i; 54 | brightnessB = 255 - i; 55 | } 56 | 57 | } /* End event loop */ 58 | return 0; /* This line is never reached */ 59 | } 60 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/scale.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Scales for use with DDS synthesis. 4 | 5 | Aimed roughly at having A2 be at 440Hz, 6 | when the chip is clocked at 8MHz and 7 | using 8-bit resolution on the PWM. 8 | 9 | Tune it if you'd like. 10 | 11 | */ 12 | 13 | #define C0 130 14 | #define Cx0 138 15 | #define D0 146 16 | #define Dx0 155 17 | #define E0 164 18 | #define F0 174 19 | #define Fx0 184 20 | #define G0 195 21 | #define Gx0 206 22 | #define A0 219 23 | #define Ax0 232 24 | #define B0 245 25 | #define C1 260 26 | #define Cx1 275 27 | #define D1 292 28 | #define Dx1 309 29 | #define E1 328 30 | #define F1 347 31 | #define Fx1 368 32 | #define G1 390 33 | #define Gx1 413 34 | #define A1 437 35 | #define Ax1 463 36 | #define B1 491 37 | #define C2 520 38 | #define Cx2 551 39 | #define D2 584 40 | #define Dx2 618 41 | #define E2 655 42 | #define F2 694 43 | #define Fx2 735 44 | #define G2 779 45 | #define Gx2 825 46 | #define A2 875 47 | #define Ax2 927 48 | #define B2 982 49 | #define C3 1040 50 | #define Cx3 1102 51 | #define D3 1167 52 | #define Dx3 1237 53 | #define E3 1310 54 | #define F3 1388 55 | #define Fx3 1471 56 | #define G3 1558 57 | #define Gx3 1651 58 | #define A3 1749 59 | #define Ax3 1853 60 | #define B3 1963 61 | #define C4 2080 62 | #define Cx4 2204 63 | #define D4 2335 64 | #define Dx4 2474 65 | #define E4 2621 66 | #define F4 2776 67 | #define Fx4 2942 68 | #define G4 3116 69 | #define Gx4 3302 70 | #define A4 3498 71 | #define Ax4 3706 72 | #define B4 3927 73 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_halfStepping/cylonEyes_halfStepping.c: -------------------------------------------------------------------------------- 1 | /* Cylon Eyes 2 | Half-stepping turns the next light on for a little bit, 3 | makes the pattern visually smoother, improves overall 4 | cylonity. 5 | */ 6 | 7 | // ------- Preamble -------- // 8 | #include /* Defines pins, ports, etc */ 9 | #include /* Functions to waste time */ 10 | 11 | #define DELAYTIME 85 /* milliseconds, 50-75 is good for smooth eyes */ 12 | 13 | int main(void) { 14 | 15 | // -------- Inits --------- // 16 | uint8_t i; 17 | DDRB = 0xff; /* Data Direction Register B: 18 | all set up for output */ 19 | 20 | // ------ Event loop ------ // 21 | while (1) { /* mainloop */ 22 | 23 | for (i = 0; i < 7; i++) { /* count i from 0 to 6 */ 24 | PORTB |= (1 << i); /* turn on led i */ 25 | _delay_ms(DELAYTIME); /* wait */ 26 | 27 | PORTB |= (1 << (i + 1)); /* turn the next led on */ 28 | _delay_ms(DELAYTIME / 2); 29 | 30 | PORTB &= ~(1 << i); /* turn off led i */ 31 | } 32 | 33 | for (i = 7; i > 0; i--) { /* count i from 7 to 1 */ 34 | PORTB |= (1 << i); 35 | _delay_ms(DELAYTIME); 36 | 37 | PORTB |= (1 << (i - 1)); /* turn the next led on */ 38 | _delay_ms(DELAYTIME / 2); 39 | 40 | PORTB &= ~(1 << i); /* turn off led i */ 41 | } 42 | 43 | } /* End event loop */ 44 | return 0; 45 | } /* end main */ 46 | -------------------------------------------------------------------------------- /Chapter09_Introduction-to-Timer-Counter-Hardware/timerAudio/timerAudio.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Quick audio demo using Timer 0 to generate audio frequencies directly. 4 | 5 | */ 6 | 7 | // ------- Preamble -------- // 8 | #include /* Defines pins, ports, etc */ 9 | #include /* Functions to waste time */ 10 | #include "pinDefines.h" 11 | #include "scale8.h" /* 8-bit scale */ 12 | 13 | static inline void initTimer(void) { 14 | TCCR0A |= (1 << WGM01); /* CTC mode */ 15 | TCCR0A |= (1 << COM0A0); /* Toggles pin each cycle through */ 16 | TCCR0B |= (1 << CS00) | (1 << CS01); /* CPU clock / 64 */ 17 | } 18 | 19 | static inline void playNote(uint8_t period, uint16_t duration) { 20 | 21 | TCNT0 = 0; /* reset the counter */ 22 | OCR0A = period; /* set pitch */ 23 | SPEAKER_DDR |= (1 << SPEAKER); /* enable output on speaker */ 24 | 25 | while (duration) { /* Variable delay */ 26 | _delay_ms(1); 27 | duration--; 28 | } 29 | SPEAKER_DDR &= ~(1 << SPEAKER); /* turn speaker off */ 30 | } 31 | 32 | int main(void) { 33 | // -------- Inits --------- // 34 | initTimer(); 35 | // ------ Event loop ------ // 36 | while (1) { 37 | /* Play some notes */ 38 | playNote(C2, 200); 39 | playNote(E2, 200); 40 | playNote(G2, 200); 41 | playNote(C3, 400); 42 | 43 | _delay_ms(1000); 44 | _delay_ms(1000); 45 | _delay_ms(1000); 46 | 47 | } /* End event loop */ 48 | return 0; /* This line is never reached */ 49 | } 50 | -------------------------------------------------------------------------------- /setupProject/USART.h: -------------------------------------------------------------------------------- 1 | /* Functions to initialize, send, receive over USART 2 | 3 | initUSART requires BAUD to be defined in order to calculate 4 | the bit-rate multiplier. 5 | */ 6 | 7 | #ifndef BAUD /* if not defined in Makefile... */ 8 | #define BAUD 9600 /* set a safe default baud rate */ 9 | #endif 10 | 11 | /* These are defined for convenience */ 12 | #define USART_HAS_DATA bit_is_set(UCSR0A, RXC0) 13 | #define USART_READY bit_is_set(UCSR0A, UDRE0) 14 | 15 | /* Takes the defined BAUD and F_CPU, 16 | calculates the bit-clock multiplier, 17 | and configures the hardware USART */ 18 | void initUSART(void); 19 | 20 | /* Blocking transmit and receive functions. 21 | When you call receiveByte() your program will hang until 22 | data comes through. We'll improve on this later. */ 23 | void transmitByte(uint8_t data); 24 | uint8_t receiveByte(void); 25 | 26 | void printString(const char myString[]); 27 | /* Utility function to transmit an entire string from RAM */ 28 | void readString(char myString[], uint8_t maxLength); 29 | /* Define a string variable, pass it to this function 30 | The string will contain whatever you typed over serial */ 31 | 32 | void printByte(uint8_t byte); 33 | /* Prints a byte out as its 3-digit ascii equivalent */ 34 | void printWord(uint16_t word); 35 | /* Prints a word (16-bits) out as its 5-digit ascii equivalent */ 36 | 37 | void printBinaryByte(uint8_t byte); 38 | /* Prints a byte out in 1s and 0s */ 39 | char nibbleToHex(uint8_t nibble); 40 | void printHexByte(uint8_t byte); 41 | /* Prints a byte out in hexadecimal */ 42 | uint8_t getNumber(void); 43 | /* takes in up to three ascii digits, 44 | converts them to a byte when press enter */ 45 | -------------------------------------------------------------------------------- /Chapter10_Pulse-Width-Modulation/pwmTimers/pwmTimers.c: -------------------------------------------------------------------------------- 1 | /* PWM Demo with serial control over three LEDs */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | #include "pinDefines.h" 7 | #include "USART.h" 8 | 9 | static inline void initTimers(void) { 10 | // Timer 1 A,B 11 | TCCR1A |= (1 << WGM10); /* Fast PWM mode, 8-bit */ 12 | TCCR1B |= (1 << WGM12); /* Fast PWM mode, pt.2 */ 13 | TCCR1B |= (1 << CS11); /* PWM Freq = F_CPU/8/256 */ 14 | TCCR1A |= (1 << COM1A1); /* PWM output on OCR1A */ 15 | TCCR1A |= (1 << COM1B1); /* PWM output on OCR1B */ 16 | 17 | // Timer 2 18 | TCCR2A |= (1 << WGM20); /* Fast PWM mode */ 19 | TCCR2A |= (1 << WGM21); /* Fast PWM mode, pt.2 */ 20 | TCCR2B |= (1 << CS21); /* PWM Freq = F_CPU/8/256 */ 21 | TCCR2A |= (1 << COM2A1); /* PWM output on OCR2A */ 22 | } 23 | 24 | int main(void) { 25 | 26 | uint8_t brightness; 27 | 28 | // -------- Inits --------- // 29 | 30 | initTimers(); 31 | initUSART(); 32 | printString("-- LED PWM Demo --\r\n"); 33 | 34 | /* enable output on LED pins, triggered by PWM hardware */ 35 | LED_DDR |= (1 << LED1); 36 | LED_DDR |= (1 << LED2); 37 | LED_DDR |= (1 << LED3); 38 | 39 | // ------ Event loop ------ // 40 | while (1) { 41 | 42 | printString("\r\nEnter (0-255) for PWM duty cycle: "); 43 | brightness = getNumber(); 44 | OCR2A = OCR1B; 45 | OCR1B = OCR1A; 46 | OCR1A = brightness; 47 | 48 | } /* End event loop */ 49 | return 0; /* This line is never reached */ 50 | } 51 | -------------------------------------------------------------------------------- /Chapter15_Advanced-Motors/hBridgeWorkout/hBridgeWorkout.c: -------------------------------------------------------------------------------- 1 | // Simple demo of an h-bridge 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include 7 | #include "pinDefines.h" 8 | 9 | static inline void setBridgeState(uint8_t bridgeA, uint8_t bridgeB) { 10 | /* Utility function that lights LEDs when it energizes a bridge side */ 11 | if (bridgeA) { 12 | PORTD |= (1 << PD6); 13 | LED_PORT |= (1 << LED0); 14 | } 15 | else { 16 | PORTD &= ~(1 << PD6); 17 | LED_PORT &= ~(1 << LED0); 18 | } 19 | if (bridgeB) { 20 | PORTD |= (1 << PD5); 21 | LED_PORT |= (1 << LED1); 22 | } 23 | else { 24 | PORTD &= ~(1 << PD5); 25 | LED_PORT &= ~(1 << LED1); 26 | } 27 | } 28 | 29 | 30 | int main(void) { 31 | // -------- Inits --------- // 32 | 33 | DDRD |= (1 << PD6); /* now hooked up to bridge, input1 */ 34 | DDRD |= (1 << PD5); /* now hooked up to bridge, input2 */ 35 | LED_DDR |= (1 << LED0); 36 | LED_DDR |= (1 << LED1); 37 | 38 | // ------ Event loop ------ // 39 | while (1) { 40 | 41 | setBridgeState(1, 0); /* "forward" */ 42 | _delay_ms(2000); 43 | 44 | setBridgeState(0, 0); /* both low stops motor */ 45 | _delay_ms(2000); 46 | 47 | setBridgeState(0, 1); /* "reverse" */ 48 | _delay_ms(2000); 49 | 50 | setBridgeState(1, 1); /* both high also stops motor */ 51 | _delay_ms(2000); 52 | 53 | // For extra-quick braking, energize the motor backwards 54 | setBridgeState(1, 0); 55 | _delay_ms(2000); 56 | setBridgeState(0, 1); 57 | _delay_ms(75); /* tune this time to match your system */ 58 | setBridgeState(0, 0); 59 | _delay_ms(2000); 60 | 61 | } /* End event loop */ 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/fatSaw/fatSaw.c: -------------------------------------------------------------------------------- 1 | /* 2 | Direct-digital synthesis 3 | Phasing saw waves demo 4 | 5 | */ 6 | 7 | #include "fatSaw.h" 8 | 9 | int main(void) { 10 | 11 | uint16_t accumulators[NUMBER_OSCILLATORS]; 12 | uint8_t waveStep; 13 | int16_t mixer = 0; 14 | uint8_t i; 15 | 16 | // -------- Inits --------- // 17 | 18 | clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */ 19 | initTimer0(); 20 | SPEAKER_DDR |= (1 << SPEAKER); /* speaker output */ 21 | LED_DDR |= (1 << LED0); 22 | 23 | // Init all to same phase 24 | for (i = 0; i < NUMBER_OSCILLATORS; i++) { 25 | accumulators[i] = 0; 26 | } 27 | 28 | // ------ Event loop ------ // 29 | while (1) { 30 | 31 | /* Load in the PWM value when ready */ 32 | loop_until_bit_is_set(TIFR0, TOV0); /* wait until overflow bit set */ 33 | OCR0A = 128 + mixer; /* signed-integers need shifting up */ 34 | TIFR0 |= (1 << TOV0); /* re-set the overflow bit */ 35 | 36 | /* Update all accumulators, mix together */ 37 | mixer = 0; 38 | for (i = 0; i < NUMBER_OSCILLATORS; i++) { 39 | accumulators[i] += BASEPITCH; 40 | waveStep = accumulators[i] >> 8; 41 | 42 | // Add extra phase increment. 43 | // Makes shifting overtones when 44 | // different frequency components add, subtract 45 | if (waveStep == 0) { /* roughly once per cycle */ 46 | accumulators[i] += PHASE_RATE * i; /* add extra phase */ 47 | } 48 | 49 | mixer += fullSaw15[waveStep]; 50 | } 51 | mixer = mixer >> OSCILLATOR_SHIFT; 52 | /* Dividing by bitshift is very fast. */ 53 | 54 | } /* End event loop */ 55 | return 0; /* This line is never reached */ 56 | } 57 | -------------------------------------------------------------------------------- /Chapter19_EEPROM/vigenereCipher/vigenereCipher.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "USART.h" 5 | 6 | #define MAX_TEXT_LENGTH 256 7 | #define CODE_LEN 64 8 | 9 | // -------- Global Variables --------- // 10 | char EEMEM code0[CODE_LEN] = "ettubrute"; 11 | char EEMEM code1[CODE_LEN] = "attackatdawn"; 12 | char EEMEM code2[CODE_LEN] = "theraininspainfallsmainlyontheplain"; 13 | char EEMEM code3[CODE_LEN] = "ablewasiereisawelba"; 14 | char *codePointers[] = { code0, code1, code2, code3 }; 15 | 16 | // Menu strings. Why not store them in EEPROM? 17 | char EEMEM welcomeString[] = "\r\n--== Vigenere Cipher ==--\r\n"; 18 | char EEMEM menuEncode[] = " [e] to encode text\r\n"; 19 | char EEMEM menuDecode[] = " [d] to decode text\r\n\r\n"; 20 | char EEMEM menuEnterText[] = " [n] to enter new text\r\n"; 21 | char EEMEM menuCodeText[] = " [c] to select your code phrase\r\n"; 22 | char EEMEM menuChangeCode[] = " [x] to modify code phrases\r\n"; 23 | char EEMEM promptCode[] = "code: "; 24 | char EEMEM promptText[] = "\r\ntext: "; 25 | 26 | char EEMEM promptSelectCode[] = "Select codephrase:\r\n\r\n"; 27 | char EEMEM promptTypeText[] = "Type your text: "; 28 | 29 | // Given the address of an EEPROM string, prints it out 30 | // Used for menu items 31 | void printFromEEPROM(char *eepromString); 32 | 33 | // Takes input from serial, stores it in the text array 34 | void enterText(char text[]); 35 | 36 | // Reads code phrases out of EEPROM and prints them. 37 | // Uses the codeBuffer for temporary storage 38 | void displayCodes(void); 39 | 40 | // Changes a code phrase, both in EEPROM and the current code 41 | void changeCode(char codeBuffer[]); 42 | 43 | // Pick a code phrase from EEPROM 44 | void selectCode(char code[]); 45 | 46 | // Encodes the passed text string, in place 47 | void encodeVigenere(char text[], char code[]); 48 | 49 | // Decodes the passed text string, in place 50 | void decodeVigenere(char text[], char code[]); 51 | -------------------------------------------------------------------------------- /Chapter11_Driving-Servo-Motors/servoSundial/servoSundial.h: -------------------------------------------------------------------------------- 1 | /* Quasi-realtime-clock with servo sundial. */ 2 | 3 | // ------- Includes -------- // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "pinDefines.h" 9 | #include "USART.h" 10 | 11 | // Global variables that take care of clock 12 | extern volatile uint16_t ticks; 13 | extern volatile uint8_t hours; /* arbitrary default time */ 14 | extern volatile uint8_t minutes; 15 | extern volatile uint8_t seconds; 16 | 17 | // ------- Defines -------- // 18 | #define PULSE_MIN 1000 /* experiment with these values */ 19 | #define PULSE_MAX 2000 /* to match your own servo */ 20 | #define PULSE_RANGE (PULSE_MAX - PULSE_MIN) 21 | #define PULSE_OVER 3000 /* Must be larger than PULSE_MAX */ 22 | 23 | #define START_TIME 10 /* 10 am */ 24 | #define STOP_TIME 22 /* 10 pm */ 25 | #define HOURS_RANGE (STOP_TIME - START_TIME - 1) 26 | 27 | #define LASER PB2 28 | #define LASER_PORT PORTB 29 | #define LASER_DDR DDRB 30 | 31 | #define SERVO PB1 32 | #define SERVO_PORT PORTB 33 | #define SERVO_DDR DDRB 34 | 35 | #define OVERFLOWS_PER_SECOND 31250 /* nominal, should calibrate */ 36 | 37 | 38 | // Serial input and output functions 39 | void pollSerial(void); 40 | void printTime(uint8_t hours, uint8_t minutes, uint8_t seconds); 41 | 42 | // Servo setup and utility functions 43 | void initTimer1_Servo(void); 44 | void enableServo(void); 45 | void disableServo(void); 46 | void setServoPosition(void); 47 | 48 | // Realtime-clock handling functions 49 | // Use the globals ticks, hours, minutes, seconds 50 | void initTimer0_Clock(void); 51 | void everyHour(void); 52 | void everyMinute(void); 53 | void everySecond(void); 54 | -------------------------------------------------------------------------------- /AVR-Programming-Library/USART.h: -------------------------------------------------------------------------------- 1 | /* Functions to initialize, send, receive over USART 2 | 3 | initUSART requires BAUD to be defined in order to calculate 4 | the bit-rate multiplier. 5 | */ 6 | 7 | #ifndef BAUD /* if not defined in Makefile... */ 8 | #define BAUD 9600 /* set a safe default baud rate */ 9 | #endif 10 | 11 | /* These are defined for convenience */ 12 | #define USART_HAS_DATA bit_is_set(UCSR0A, RXC0) 13 | #define USART_READY bit_is_set(UCSR0A, UDRE0) 14 | 15 | /* Takes the defined BAUD and F_CPU, 16 | calculates the bit-clock multiplier, 17 | and configures the hardware USART */ 18 | void initUSART(void); 19 | 20 | /* Blocking transmit and receive functions. 21 | When you call receiveByte() your program will hang until 22 | data comes through. We'll improve on this later. */ 23 | void transmitByte(uint8_t data); 24 | uint8_t receiveByte(void); 25 | 26 | void printString(const char myString[]); 27 | /* Utility function to transmit an entire string from RAM */ 28 | void readString(char myString[], uint8_t maxLength); 29 | /* Define a string variable, pass it to this function 30 | The string will contain whatever you typed over serial */ 31 | 32 | void printByte(uint8_t byte); 33 | /* Prints a byte out as its 3-digit ascii equivalent */ 34 | void printWord(uint16_t word); 35 | /* Prints a word (16-bits) out as its 5-digit ascii equivalent */ 36 | 37 | void printBinaryByte(uint8_t byte); 38 | /* Prints a byte out in 1s and 0s */ 39 | char nibbleToHex(uint8_t nibble); 40 | char nibbleToHexCharacter(uint8_t nibble); 41 | void printHexByte(uint8_t byte); 42 | /* Prints a byte out in hexadecimal */ 43 | uint8_t getNumber(void); 44 | /* takes in up to three ascii digits, 45 | converts them to a byte when press enter */ 46 | -------------------------------------------------------------------------------- /Chapter05_Serial-IO/serialOrgan/autoPlay.py: -------------------------------------------------------------------------------- 1 | ## Scripting in python to drive the serial-port organ 2 | 3 | ## So far, the "protocol" is simple. 4 | ## Python routine sends a note, waits for a return character, then sends next, etc. 5 | ## Organ listens for notes, when it gets one sends an 'N' to say it's ready 6 | 7 | import serial 8 | 9 | def playString(noteString, serialPort): 10 | for letter in noteString: 11 | print(letter) 12 | serialPort.write(letter.encode()) 13 | returnValue = serialPort.read(1) 14 | 15 | if __name__ == "__main__": 16 | 17 | import time 18 | from urllib.request import urlopen 19 | 20 | ## Need to consider alternatives for Mac / Windows 21 | ## list all serial ports being used: python -m serial.tools.list_ports 22 | PORT = "/dev/ttyUSB0" # Change this to the current serial port being used 23 | BAUD = 9600 24 | 25 | s = serial.Serial(PORT, BAUD) 26 | s.flush() 27 | ## flush clears the buffer so that we're starting fresh 28 | ## More on serial buffers later. 29 | 30 | ## An intentional example. You can use this for playing music on purpose. 31 | playString("f g h j k l ; ]'[", s) 32 | input("Press enter for next demo\n") 33 | 34 | ## A fun / stupid example. You can just type stuff and see what comes out. 35 | playString("hello there, this is a random string turned into 'music'", s) 36 | input("Press enter for next demo\n") 37 | 38 | ## Website no longer alive... skipping: 39 | ## A really frivolous example. Play websites! 40 | ## Bonus points for first person to tweet themselves a song. 41 | #print ("Downloading song data from http://serialorgansongs.jottit.com/...") 42 | #import re 43 | #contentFilter = re.compile(r'

(.*?)

') 44 | #songSite = urlopen("http://serialorgansongs.jottit.com/").read() 45 | #songText = contentFilter.findall(songSite)[0] 46 | #playString(songText, s) 47 | 48 | ## Or interactive 49 | mySong = input("\nType in your own song: ") 50 | playString(mySong, s) 51 | -------------------------------------------------------------------------------- /Chapter14_Switches/dcMotorWorkout/dcMotorWorkout.c: -------------------------------------------------------------------------------- 1 | /* Demos PWM control of a DC motor */ 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include 7 | #include "pinDefines.h" 8 | #include "USART.h" 9 | 10 | #define SPEED_STEP_DELAY 2 /* milliseconds */ 11 | 12 | // -------- Functions --------- // 13 | static inline void initTimer0(void) { 14 | TCCR0A |= (1 << WGM00); /* Fast PWM mode */ 15 | TCCR0A |= (1 << WGM01); /* Fast PWM mode, pt.2 */ 16 | TCCR0A |= (1 << COM0B1); /* output PWM to pin */ 17 | TCCR0B |= (1 << CS02); /* Clock with /1024 prescaler */ 18 | //TCCR0B |= (1 << CS00); /* Clock with /1024 prescaler, pt.2 */ 19 | } 20 | 21 | 22 | int main(void) { 23 | 24 | uint8_t updateSpeed; 25 | 26 | // -------- Inits --------- // 27 | initTimer0(); 28 | OCR0B = 0; 29 | 30 | ANTENNA_DDR |= (1 << ANTENNA); /* now hooked up to MOSFET, output */ 31 | LED_DDR |= (1 << LED0); 32 | LED_DDR |= (1 << LED1); 33 | 34 | initUSART(); 35 | printString("DC Motor Workout\r\n"); 36 | 37 | // ------ Event loop ------ // 38 | while (1) { 39 | 40 | updateSpeed = getNumber(); 41 | 42 | /* Ramp up/down to desired speed */ 43 | if (OCR0B < updateSpeed) { 44 | LED_PORT |= (1 << LED0); 45 | while (OCR0B < updateSpeed) { 46 | OCR0B++; 47 | _delay_ms(SPEED_STEP_DELAY); 48 | } 49 | } 50 | else { 51 | LED_PORT |= (1 << LED1); 52 | while (OCR0B > updateSpeed) { 53 | OCR0B--; 54 | _delay_ms(SPEED_STEP_DELAY); 55 | } 56 | } 57 | LED_PORT = 0; /* all off */ 58 | 59 | } /* End event loop */ 60 | return 0; /* This line is never reached */ 61 | } 62 | -------------------------------------------------------------------------------- /Chapter17_I2C/i2cThermometer/i2cThermometer.c: -------------------------------------------------------------------------------- 1 | /* Reads LM75 Thermometer and Prints Value over Serial */ 2 | 3 | // ------- Preamble -------- // 4 | #include 5 | #include 6 | #include 7 | 8 | #include "pinDefines.h" 9 | #include "USART.h" 10 | #include "i2c.h" 11 | 12 | // -------- Defines -------- // 13 | 14 | #define LM75_ADDRESS_W 0b10010000 15 | #define LM75_ADDRESS_R 0b10010001 16 | #define LM75_TEMP_REGISTER 0b00000000 17 | #define LM75_CONFIG_REGISTER 0b00000001 18 | #define LM75_THYST_REGISTER 0b00000010 19 | #define LM75_TOS_REGISTER 0b00000011 20 | // -------- Functions --------- // 21 | 22 | int main(void) { 23 | 24 | uint8_t tempHighByte, tempLowByte; 25 | 26 | // -------- Inits --------- // 27 | clock_prescale_set(clock_div_1); /* 8MHz */ 28 | initUSART(); 29 | printString("\r\n==== i2c Thermometer ====\r\n"); 30 | initI2C(); 31 | 32 | // ------ Event loop ------ // 33 | while (1) { 34 | /* To set register, address LM75 in write mode */ 35 | i2cStart(); 36 | i2cSend(LM75_ADDRESS_W); 37 | i2cSend(LM75_TEMP_REGISTER); 38 | i2cStart(); /* restart, just send start again */ 39 | /* Setup and send address, with read bit */ 40 | i2cSend(LM75_ADDRESS_R); 41 | /* Now receive two bytes of temperature */ 42 | tempHighByte = i2cReadAck(); 43 | tempLowByte = i2cReadNoAck(); 44 | i2cStop(); 45 | 46 | // Print it out nicely over serial for now... 47 | printByte(tempHighByte); 48 | if (tempLowByte & _BV(7)) { 49 | printString(".5\r\n"); 50 | } 51 | else { 52 | printString(".0\r\n"); 53 | } 54 | 55 | /* Once per second */ 56 | _delay_ms(1000); 57 | 58 | } /* End event loop */ 59 | return 0; /* This line is never reached */ 60 | } 61 | -------------------------------------------------------------------------------- /Chapter09_Introduction-to-Timer-Counter-Hardware/amRadio/scale16.h: -------------------------------------------------------------------------------- 1 | /* Scale in the key of 1/10000 */ 2 | 3 | /* 4 | These are periods -- if you delay this long, 5 | then toggle the speaker pin, you'll get approximate 6 | pitches. 7 | 8 | This is the 16-bit version. The pitches get less accurate 9 | as they get higher, but not as bad as the 8-bit one. 10 | 11 | "x" denotes sharp. 12 | 13 | Can be generated by Python: 14 | 15 | import math 16 | scale = ['C', 'Cx', 'D', 'Dx', 'E', 'F', 'Fx', 'G', 'Gx', 'A', 'Ax', 'B'] 17 | 18 | def octave(baseLength): 19 | periods = [baseLength / math.exp(x*math.log(2)/12) for x in range(0, 12)] 20 | periods = [int(round(x)) for x in periods] 21 | return( zip(scale, periods) ) 22 | 23 | for i in range(0,4): 24 | for note, period in octave(10000 / 2**i): 25 | if period < 65500: 26 | noteString = note + str(i) 27 | print "#define {:<5}{:>6}".format(noteString, period) 28 | */ 29 | 30 | 31 | #define C0 10000 32 | #define Cx0 9439 33 | #define D0 8909 34 | #define Dx0 8409 35 | #define E0 7937 36 | #define F0 7492 37 | #define Fx0 7071 38 | #define G0 6674 39 | #define Gx0 6300 40 | #define A0 5946 41 | #define Ax0 5612 42 | #define B0 5297 43 | #define C1 5000 44 | #define Cx1 4719 45 | #define D1 4454 46 | #define Dx1 4204 47 | #define E1 3969 48 | #define F1 3746 49 | #define Fx1 3536 50 | #define G1 3337 51 | #define Gx1 3150 52 | #define A1 2973 53 | #define Ax1 2806 54 | #define B1 2649 55 | #define C2 2500 56 | #define Cx2 2360 57 | #define D2 2227 58 | #define Dx2 2102 59 | #define E2 1984 60 | #define F2 1873 61 | #define Fx2 1768 62 | #define G2 1669 63 | #define Gx2 1575 64 | #define A2 1487 65 | #define Ax2 1403 66 | #define B2 1324 67 | #define C3 1250 68 | #define Cx3 1180 69 | #define D3 1114 70 | #define Dx3 1051 71 | #define E3 992 72 | #define F3 936 73 | #define Fx3 884 74 | #define G3 834 75 | #define Gx3 787 76 | #define A3 743 77 | #define Ax3 702 78 | #define B3 662 79 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_8LFSR/8LFSR.c: -------------------------------------------------------------------------------- 1 | // ------- Preamble -------- // 2 | #include 3 | #include 4 | 5 | #define DELAY 100 /* ms */ 6 | 7 | static inline uint8_t LFSR8_step(uint8_t random); 8 | 9 | int main(void) { 10 | 11 | // -------- Inits --------- // 12 | 13 | DDRB = 0xff; /* output on all LEDs */ 14 | uint8_t random = 1; /* can't init to 0, any other is ok */ 15 | 16 | // ------ Event loop ------ // 17 | while (1) { 18 | 19 | /* Display and output */ 20 | random = LFSR8_step(random); 21 | PORTB = random; 22 | _delay_ms(DELAY); 23 | 24 | } /* End event loop */ 25 | return 0; 26 | } 27 | 28 | 29 | // ----------------- LFSR Routines ---------------- // 30 | 31 | inline uint8_t LFSR8_step(uint8_t random) { 32 | /* 33 | Takes an 8-bit number, takes one step in a () LFSR. 34 | [3, 4, 5, 7] is the set of taps for 8-bits that goes through 35 | the whole cycle before repeating. 36 | 37 | If you're really serious about randomness, you'll want a different 38 | algorithm. In fact, this is a great demo of how "predictable" 39 | the "pseudo-random" sequence is. 40 | 41 | Note that this is not a very efficient way to code this up, 42 | but it's meant mostly for teaching and is plenty fast 43 | because the compiler does an OK job with it. 44 | */ 45 | uint8_t tap1, tap2, tap3, tap4; 46 | uint8_t newBit; 47 | tap1 = 1 & (random >> 3); 48 | tap2 = 1 & (random >> 4); 49 | tap3 = 1 & (random >> 5); 50 | tap4 = 1 & (random >> 7); 51 | 52 | newBit = tap1 ^ tap2 ^ tap3 ^ tap4; 53 | random = ((random << 1) | newBit); 54 | return (random); 55 | } 56 | 57 | 58 | inline uint16_t LFSR16(uint16_t random) { 59 | // 3, 12, 14, 15 are the maximal taps for 16 bits. 60 | uint16_t tap1, tap2, tap3, tap4; 61 | uint16_t newBit; 62 | tap1 = 1 & (random >> 3); 63 | tap2 = 1 & (random >> 12); 64 | tap3 = 1 & (random >> 14); 65 | tap4 = 1 & (random >> 15); 66 | 67 | newBit = tap1 ^ tap2 ^ tap3 ^ tap4; 68 | random = ((random << 1) | newBit); 69 | return (random); 70 | } 71 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds/dds.c: -------------------------------------------------------------------------------- 1 | /* Direct-digital synthesis */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | #include 7 | 8 | #include "pinDefines.h" 9 | 10 | #include "fullSine.h" 11 | 12 | static inline void initTimer0(void) { 13 | TCCR0A |= (1 << COM0A1); /* PWM output on OCR0A */ 14 | SPEAKER_DDR |= (1 << SPEAKER); /* enable output on pin */ 15 | 16 | TCCR0A |= (1 << WGM00); /* Fast PWM mode */ 17 | TCCR0A |= (1 << WGM01); /* Fast PWM mode, pt.2 */ 18 | 19 | TCCR0B |= (1 << CS00); /* Clock with /1 prescaler */ 20 | } 21 | 22 | int main(void) { 23 | 24 | uint16_t accumulator = 0; 25 | uint16_t accumulatorSteps = 880; /* approx 440 Hz */ 26 | uint8_t waveStep; 27 | int8_t pwmValue; 28 | 29 | // -------- Inits --------- // 30 | 31 | clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */ 32 | initTimer0(); 33 | BUTTON_PORT |= (1 << BUTTON); /* pullup on button */ 34 | 35 | // ------ Event loop ------ // 36 | while (1) { 37 | 38 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 39 | 40 | SPEAKER_DDR |= (1 << SPEAKER); /* enable speaker */ 41 | accumulator += accumulatorSteps; /* advance accumulator */ 42 | waveStep = accumulator >> 8; /* which entry in lookup? */ 43 | pwmValue = fullSine[waveStep]; /* lookup voltage */ 44 | 45 | loop_until_bit_is_set(TIFR0, TOV0); /* wait for PWM cycle */ 46 | OCR0A = 128 + pwmValue; /* set new PWM value */ 47 | TIFR0 |= (1 << TOV0); /* reset PWM overflow bit */ 48 | } 49 | 50 | else { /* button not pressed */ 51 | SPEAKER_DDR &= ~(1 << SPEAKER); /* disable speaker */ 52 | } 53 | 54 | } /* End event loop */ 55 | return 0; /* This line is never reached */ 56 | } 57 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/dds_saw15/dds_saw15.c: -------------------------------------------------------------------------------- 1 | /* Direct-digital synthesis */ 2 | 3 | // ------- Preamble -------- // 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | #include 7 | 8 | #include "pinDefines.h" 9 | 10 | #include "fullSaw15.h" 11 | 12 | static inline void initTimer0(void) { 13 | TCCR0A |= (1 << COM0A1); /* PWM output on OCR0A */ 14 | SPEAKER_DDR |= (1 << SPEAKER); /* enable output on pin */ 15 | 16 | TCCR0A |= (1 << WGM00); /* Fast PWM mode */ 17 | TCCR0A |= (1 << WGM01); /* Fast PWM mode, pt.2 */ 18 | 19 | TCCR0B |= (1 << CS00); /* Clock with /1 prescaler */ 20 | } 21 | 22 | int main(void) { 23 | 24 | uint16_t accumulator = 0; 25 | uint16_t accumulatorSteps = 880; /* approx 440 Hz */ 26 | uint8_t waveStep; 27 | int8_t pwmValue; 28 | 29 | // -------- Inits --------- // 30 | 31 | clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */ 32 | initTimer0(); 33 | BUTTON_PORT |= (1 << BUTTON); /* pullup on button */ 34 | 35 | // ------ Event loop ------ // 36 | while (1) { 37 | 38 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 39 | 40 | SPEAKER_DDR |= (1 << SPEAKER); /* enable speaker */ 41 | accumulator += accumulatorSteps; /* advance accumulator */ 42 | waveStep = accumulator >> 8; /* which entry in lookup? */ 43 | pwmValue = fullSaw15[waveStep]; /* lookup voltage */ 44 | 45 | loop_until_bit_is_set(TIFR0, TOV0); /* wait for PWM cycle */ 46 | OCR0A = 128 + pwmValue; /* set new PWM value */ 47 | TIFR0 |= (1 << TOV0); /* reset PWM overflow bit */ 48 | } 49 | 50 | else { /* button not pressed */ 51 | SPEAKER_DDR &= ~(1 << SPEAKER); /* disable speaker */ 52 | } 53 | 54 | } /* End event loop */ 55 | return 0; /* This line is never reached */ 56 | } 57 | -------------------------------------------------------------------------------- /Chapter04_Bit-Twiddling/cylonEyes_16LFSR/16LFSR.c: -------------------------------------------------------------------------------- 1 | // ------- Preamble -------- // 2 | #include 3 | #include 4 | 5 | #define DELAY 100 /* ms */ 6 | 7 | static inline uint8_t LFSR8_step(uint8_t random); 8 | static inline uint16_t LFSR16(uint16_t random); 9 | 10 | int main(void) { 11 | 12 | // -------- Inits --------- // 13 | 14 | DDRB = 0xff; /* output on all LEDs */ 15 | uint16_t random = 123; /* can't init to 0, any other is ok */ 16 | 17 | // ------ Event loop ------ // 18 | while (1) { 19 | 20 | /* Display and output */ 21 | random = LFSR16(random); 22 | PORTB = (random >> 8); 23 | _delay_ms(DELAY); 24 | 25 | } /* End event loop */ 26 | return 0; 27 | } 28 | 29 | 30 | // ----------------- LFSR Routines ---------------- // 31 | 32 | inline uint8_t LFSR8_step(uint8_t random) { 33 | /* 34 | Takes an 8-bit number, takes one step in a () LFSR. 35 | [3, 4, 5, 7] is the set of taps for 8-bits that goes through 36 | the whole cycle before repeating. 37 | 38 | If you're really serious about randomness, you'll want a different 39 | algorithm. In fact, this is a great demo of how "predictable" 40 | the "pseudo-random" sequence is. 41 | 42 | Note that this is not a very efficient way to code this up, 43 | but it's meant mostly for teaching and is plenty fast 44 | because the compiler does an OK job with it. 45 | */ 46 | uint8_t tap1, tap2, tap3, tap4; 47 | uint8_t newBit; 48 | tap1 = 1 & (random >> 3); 49 | tap2 = 1 & (random >> 4); 50 | tap3 = 1 & (random >> 5); 51 | tap4 = 1 & (random >> 7); 52 | 53 | newBit = tap1 ^ tap2 ^ tap3 ^ tap4; 54 | random = ((random << 1) | newBit); 55 | return (random); 56 | } 57 | 58 | 59 | inline uint16_t LFSR16(uint16_t random) { 60 | // 3, 12, 14, 15 are the maximal taps for 16 bits. 61 | uint16_t tap1, tap2, tap3, tap4; 62 | uint16_t newBit; 63 | tap1 = 1 & (random >> 3); 64 | tap2 = 1 & (random >> 12); 65 | tap3 = 1 & (random >> 14); 66 | tap4 = 1 & (random >> 15); 67 | 68 | newBit = tap1 ^ tap2 ^ tap3 ^ tap4; 69 | random = ((random << 1) | newBit); 70 | return (random); 71 | } 72 | -------------------------------------------------------------------------------- /Chapter08_Hardware-Interrupts/capSense/capSense.c: -------------------------------------------------------------------------------- 1 | /* 2 | Capacitive touch sensor demo 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "pinDefines.h" 10 | #include "USART.h" 11 | 12 | #define SENSE_TIME 50 13 | #define THRESHOLD 12000 14 | 15 | // ------- Global Variables ---------- // 16 | volatile uint16_t chargeCycleCount; 17 | 18 | // ------- Functions -------- // 19 | 20 | void initPinChangeInterrupt(void) { 21 | PCICR |= (1 << PCIE1); /* enable Pin-change interrupts 1 (bank C) */ 22 | PCMSK1 |= (1 << PC1); /* enable specific interrupt for our pin PC1 */ 23 | } 24 | 25 | ISR(PCINT1_vect) { 26 | chargeCycleCount++; /* count this change */ 27 | 28 | CAP_SENSOR_DDR |= (1 << CAP_SENSOR); /* output mode */ 29 | _delay_us(1); /* charging delay */ 30 | 31 | CAP_SENSOR_DDR &= ~(1 << CAP_SENSOR); /* set as input */ 32 | PCIFR |= (1 << PCIF1); /* clear the pin-change interrupt */ 33 | } 34 | 35 | 36 | int main(void) { 37 | // -------- Inits --------- // 38 | clock_prescale_set(clock_div_1); /* full speed */ 39 | initUSART(); 40 | printString("==[ Cap Sensor ]==\r\n\r\n"); 41 | 42 | LED_DDR = 0xff; 43 | MCUCR |= (1 << PUD); /* disable all pullups */ 44 | CAP_SENSOR_PORT |= (1 << CAP_SENSOR); /* we can leave output high */ 45 | 46 | initPinChangeInterrupt(); 47 | 48 | // ------ Event loop ------ // 49 | while (1) { 50 | 51 | chargeCycleCount = 0; /* reset counter */ 52 | CAP_SENSOR_DDR |= (1 << CAP_SENSOR); /* start with cap charged */ 53 | sei(); /* start up interrupts, counting */ 54 | _delay_ms(SENSE_TIME); 55 | cli(); /* done */ 56 | if (chargeCycleCount < THRESHOLD) { 57 | LED_PORT = 0xff; 58 | } 59 | else { 60 | LED_PORT = 0; 61 | } 62 | printWord(chargeCycleCount); /* for fine tuning */ 63 | printString("\r\n"); 64 | 65 | } /* End event loop */ 66 | return 0; /* This line is never reached */ 67 | } 68 | -------------------------------------------------------------------------------- /Chapter13_Advanced-PWM-Tricks/adsr/adsr.h: -------------------------------------------------------------------------------- 1 | 2 | /*Include file for ADSR synth project. */ 3 | 4 | #include /* Defines pins, ports, etc */ 5 | #include /* Functions to waste time */ 6 | #include 7 | #include 8 | #include "pinDefines.h" 9 | #include "macros.h" 10 | #include "scale.h" 11 | #include "fullSaw7.h" /* a 7-harmonic bandlimited sawtooth */ 12 | /* see generateWavetables.py if you're interested */ 13 | #include "fullTriangle.h" 14 | #include "USART.h" 15 | 16 | #define FULL_VOLUME 31 /* 5-bit volumes */ 17 | 18 | // Default envelope values (slightly percussive) 19 | // Play around with these! 20 | #define ATTACK_RATE 8 /* 0-255 */ 21 | #define DECAY_RATE 120 /* 0-255 */ 22 | #define SUSTAIN_LEVEL 25 /* 0-255 */ 23 | #define SUSTAIN_TIME 4000 /* 0-65535 */ 24 | #define RELEASE_RATE 200 /* 0-65535 */ 25 | 26 | // Compute these constants 27 | #define ATTACK_TIME ATTACK_RATE * FULL_VOLUME 28 | #define DECAY_TIME (ATTACK_TIME + (FULL_VOLUME-SUSTAIN_LEVEL) * DECAY_RATE) 29 | #define RELEASE_TIME DECAY_TIME + SUSTAIN_TIME 30 | 31 | // -------------- Init Routines --------------- // 32 | 33 | static inline void initTimer0(void){ 34 | set_bit(TCCR0A, COM0A1); /* PWM output on OCR0A */ 35 | set_bit(SPEAKER_DDR, SPEAKER); /* enable output on pin */ 36 | 37 | set_bit(TCCR0A, WGM00); /* Fast PWM mode */ 38 | set_bit(TCCR0A, WGM01); /* Fast PWM mode, pt.2 */ 39 | 40 | set_bit(TCCR0B, CS00); /* Clock with /1 prescaler */ 41 | } 42 | 43 | static inline void initLEDs(void){ 44 | uint8_t i; 45 | LED_DDR = 0xff; /* All LEDs for diagnostics */ 46 | for (i=0; i<8; i++){ 47 | set_bit(LED_PORT, i); 48 | _delay_ms(100); 49 | clear_bit(LED_PORT, i); 50 | } 51 | } 52 | 53 | static inline uint16_t lookupPitch(char i){ 54 | switch(i){ 55 | case 'a': 56 | return(G1); 57 | case 's': 58 | return(A1); 59 | case 'd': 60 | return(B1); 61 | case 'f': 62 | return(C2); 63 | case 'g': 64 | return(D2); 65 | case 'h': 66 | return(E2); 67 | case 'j': 68 | return(F2); 69 | case 'k': 70 | return(G2); 71 | case 'l': 72 | return(A2); 73 | case ';': 74 | return(B2); 75 | case '\'': 76 | return(C3); 77 | } 78 | // Default value -- if press some other key 79 | return(C1); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /Chapter09_Introduction-to-Timer-Counter-Hardware/reactionTimer/reactionTimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | Press the button as quickly as you can after the LEDs light up. 3 | Your time is printed out over the serial port. 4 | */ 5 | 6 | // ------- Preamble -------- // 7 | #include 8 | #include 9 | #include 10 | #include "pinDefines.h" 11 | #include "USART.h" 12 | 13 | #include "support.h" 14 | 15 | static inline void initTimer1(void) { 16 | /* Normal mode (default), just counting */ 17 | TCCR1B |= (1 << CS11) | (1 << CS10); 18 | /* Clock speed: 1 MHz / 64, 19 | each tick is 64 microseconds ~= 15.6 per ms */ 20 | /* No special output modes */ 21 | } 22 | 23 | int main(void) { 24 | uint16_t timerValue; 25 | 26 | // -------- Inits --------- // 27 | 28 | initUSART(); 29 | initTimer1(); 30 | LED_DDR = 0xff; /* all LEDs for output */ 31 | BUTTON_PORT |= (1 << BUTTON); /* enable internal pull-up */ 32 | 33 | printString("\r\nReaction Timer:\r\n"); 34 | printString("---------------\r\n"); 35 | printString("Press any key to start.\r\n"); 36 | 37 | // ------ Event loop ------ // 38 | while (1) { 39 | 40 | receiveByte(); /* press any key */ 41 | printString("\r\nGet ready..."); 42 | randomDelay(); 43 | 44 | printString("\r\nGo!\r\n"); 45 | LED_PORT = 0xff; /* light LEDs */ 46 | TCNT1 = 0; /* reset counter */ 47 | 48 | if (bit_is_clear(BUTTON_PIN, BUTTON)) { 49 | /* Button pressed _exactly_ as LEDs light up. Suspicious. */ 50 | printString("You're only cheating yourself.\r\n"); 51 | } 52 | else { 53 | // Wait until button pressed, save timer value. 54 | loop_until_bit_is_clear(BUTTON_PIN, BUTTON); 55 | timerValue = TCNT1 >> 4; 56 | /* each tick is approx 1/16 milliseconds, so we bit-shift divide */ 57 | 58 | printMilliseconds(timerValue); 59 | printComments(timerValue); 60 | } 61 | 62 | // Clear LEDs and start again. 63 | LED_PORT = 0x00; 64 | printString("Press any key to try again.\r\n"); 65 | 66 | } /* End event loop */ 67 | return 0; /* This line is never reached */ 68 | } 69 | -------------------------------------------------------------------------------- /allProjectsList: -------------------------------------------------------------------------------- 1 | Chapter02_Programming-AVRs/blinkLED 2 | Chapter02_Programming-AVRs/blinkLED_AVR_style 3 | 4 | Chapter03_Digital-Output/povToy 5 | 6 | Chapter04_Bit-Twiddling/cylonEyes 7 | Chapter04_Bit-Twiddling/showingOffBits 8 | 9 | Chapter05_Serial-IO/serialLoopback 10 | Chapter05_Serial-IO/serialOrgan 11 | 12 | Chapter06_Digital-Input/avrMusicBox 13 | Chapter06_Digital-Input/bossButton 14 | Chapter06_Digital-Input/debouncer 15 | Chapter06_Digital-Input/simpleButton 16 | Chapter06_Digital-Input/toggleButton 17 | 18 | Chapter07_Analog-to-Digital-Conversion-I/lightSensor 19 | Chapter07_Analog-to-Digital-Conversion-I/nightLight 20 | Chapter07_Analog-to-Digital-Conversion-I/slowScope 21 | 22 | Chapter08_Hardware-Interrupts/capSense 23 | Chapter08_Hardware-Interrupts/helloInterrupt 24 | 25 | Chapter09_Introduction-to-Timer-Counter-Hardware/amRadio 26 | Chapter09_Introduction-to-Timer-Counter-Hardware/reactionTimer 27 | Chapter09_Introduction-to-Timer-Counter-Hardware/timerAudio 28 | 29 | Chapter10_Pulse-Width-Modulation/bruteForcePWM 30 | Chapter10_Pulse-Width-Modulation/pwm 31 | Chapter10_Pulse-Width-Modulation/pwmOnAnyPin 32 | Chapter10_Pulse-Width-Modulation/pwmTimers 33 | 34 | Chapter11_Driving-Servo-Motors/servoSundial 35 | Chapter11_Driving-Servo-Motors/servoWorkout 36 | 37 | Chapter12_Analog-to-Digital-Conversion-II/footstepDetector 38 | Chapter12_Analog-to-Digital-Conversion-II/voltmeter 39 | 40 | Chapter13_Advanced-PWM-Tricks/adsr 41 | Chapter13_Advanced-PWM-Tricks/arpeggiator 42 | Chapter13_Advanced-PWM-Tricks/dds 43 | Chapter13_Advanced-PWM-Tricks/dds_interrupts 44 | Chapter13_Advanced-PWM-Tricks/dds_saw15 45 | Chapter13_Advanced-PWM-Tricks/dialTone 46 | Chapter13_Advanced-PWM-Tricks/fatSaw 47 | 48 | Chapter14_Switches/dcMotorWorkout 49 | 50 | Chapter15_Advanced-Motors/hBridgeWorkout 51 | Chapter15_Advanced-Motors/stepperWorkout 52 | 53 | Chapter16_SPI/spiEEPROMDemo 54 | 55 | Chapter17_I2C/i2cThermometer 56 | Chapter17_I2C/loggingThermometer 57 | 58 | Chapter18_Using-Flash-Program-Memory/progmemDemo1 59 | Chapter18_Using-Flash-Program-Memory/progmemDemo2 60 | Chapter18_Using-Flash-Program-Memory/progmemDemo3 61 | Chapter18_Using-Flash-Program-Memory/progmemDemo4 62 | Chapter18_Using-Flash-Program-Memory/progmemDemo5 63 | Chapter18_Using-Flash-Program-Memory/talkingVoltmeter 64 | 65 | Chapter19_EEPROM/eememDemo 66 | Chapter19_EEPROM/favoriteColor 67 | Chapter19_EEPROM/quickDemo 68 | Chapter19_EEPROM/vigenereCipher 69 | 70 | -------------------------------------------------------------------------------- /setupProject/createPinDefines.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | ## Given a list of names and pin defines, runs through a routine that 4 | ## sets up a standard set of macros which can then be cut/paste or 5 | ## otherwise included. 6 | 7 | import sys 8 | try: 9 | outputFilename = sys.argv[1] 10 | except: 11 | print 12 | print 'No filename passed, saving to "pinDefinitions.h" in this directory.' 13 | outputFilename = "pinDefinitions.h" 14 | 15 | print 16 | print 17 | print "First we need to define macro names and the coresponding AVR pins." 18 | print "None of the names are case-sensitive -- all are converted to uppercase." 19 | print "When you're done, hit [enter] for the macro name." 20 | print " " 21 | 22 | 23 | nicknames = [] 24 | pinouts = [] 25 | while(True): 26 | nickname = raw_input("\nPin Macro Name: ").strip().upper() 27 | if (nickname == ""): 28 | break 29 | nicknames.append(nickname) 30 | pinout = raw_input("AVR Pinout: ").strip().upper() 31 | pinouts.append(pinout) 32 | 33 | output = "// ---------------\n// Pin Defines \n// ---------------\n\n" 34 | for (nickname, pinout) in zip(nicknames, pinouts): 35 | output += "#define %s %s\n" % (nickname, pinout) 36 | output += "#define %s_PORT PORT%s\n" % (nickname, pinout[1]) 37 | output += "#define %s_PIN PIN%s\n" % (nickname, pinout[1]) 38 | output += "#define %s_DDR DDR%s\n" % (nickname, pinout[1]) 39 | output += "#define %s_SET_OUTPUT %s_DDR |= _BV(%s)\n" %\ 40 | (nickname, nickname, nickname) 41 | output += "#define %s_SET_INPUT %s_DDR &= ~_BV(%s)\n" %\ 42 | (nickname, nickname, nickname) 43 | output += "#define %s_SET_HIGH %s_PORT |= _BV(%s)\n" % \ 44 | (nickname, nickname, nickname) 45 | output += "#define %s_SET_LOW %s_PORT &= ~_BV(%s)\n" % \ 46 | (nickname, nickname, nickname) 47 | output += "#define %s_TOGGLE %s_PORT ^= _BV(%s)\n" % \ 48 | (nickname, nickname, nickname) 49 | output += "#define %s_IS_HIGH (%s_PIN & _BV(%s))\n" % \ 50 | (nickname, nickname, nickname) 51 | output += "#define %s_IS_LOW !(%s_PIN & _BV(%s))\n" % \ 52 | (nickname, nickname, nickname) 53 | output += "\n" 54 | 55 | 56 | try: 57 | outfile = open(outputFilename, "w") 58 | outfile.write(output) 59 | outfile.close() 60 | except NameError: 61 | print output 62 | -------------------------------------------------------------------------------- /Chapter16_SPI/spiEEPROMDemo/25LC256.h: -------------------------------------------------------------------------------- 1 | /* SPI EEPROM 25LC256 Library */ 2 | #include 3 | #include "pinDefines.h" 4 | 5 | 6 | /* Which pin selects EEPROM as slave? */ 7 | #define SLAVE_SELECT SPI_SS_PORT &= ~(1 << SPI_SS) 8 | #define SLAVE_DESELECT SPI_SS_PORT |= (1 << SPI_SS) 9 | 10 | // Instruction Set -- from data sheet 11 | #define EEPROM_READ 0b00000011 /* read memory */ 12 | #define EEPROM_WRITE 0b00000010 /* write to memory */ 13 | 14 | #define EEPROM_WRDI 0b00000100 /* write disable */ 15 | #define EEPROM_WREN 0b00000110 /* write enable */ 16 | 17 | #define EEPROM_RDSR 0b00000101 /* read status register */ 18 | #define EEPROM_WRSR 0b00000001 /* write status register */ 19 | 20 | // EEPROM Status Register Bits -- from data sheet 21 | // Use these to parse status register 22 | #define EEPROM_WRITE_IN_PROGRESS 0 23 | #define EEPROM_WRITE_ENABLE_LATCH 1 24 | #define EEPROM_BLOCK_PROTECT_0 2 25 | #define EEPROM_BLOCK_PROTECT_1 3 26 | 27 | #define EEPROM_BYTES_PER_PAGE 64 28 | #define EEPROM_BYTES_MAX 0x7FFF 29 | 30 | // Functions 31 | 32 | /* Init SPI to run EEPROM with phase, polarity = 0,0 */ 33 | void initSPI(void); 34 | 35 | /* Generic. Just loads up HW SPI register and waits */ 36 | void SPI_tradeByte(uint8_t byte); 37 | 38 | /* splits 16-bit address into 2 bytes, sends both */ 39 | void EEPROM_send16BitAddress(uint16_t address); 40 | 41 | /* reads the EEPROM status register */ 42 | uint8_t EEPROM_readStatus(void); 43 | 44 | /* helper: sets EEPROM write enable */ 45 | void EEPROM_writeEnable(void); 46 | 47 | /* gets a byte from a given memory location */ 48 | uint8_t EEPROM_readByte(uint16_t address); 49 | 50 | /* gets two bytes from a given memory location */ 51 | uint16_t EEPROM_readWord(uint16_t address); 52 | 53 | /* writes a byte to a given memory location */ 54 | void EEPROM_writeByte(uint16_t address, uint8_t byte); 55 | 56 | /* gets two bytes to a given memory location */ 57 | void EEPROM_writeWord(uint16_t address, uint16_t word); 58 | 59 | /* sets every byte in memory to zero */ 60 | void EEPROM_clearAll(void); 61 | -------------------------------------------------------------------------------- /Chapter17_I2C/loggingThermometer/25LC256.h: -------------------------------------------------------------------------------- 1 | /* SPI EEPROM 25LC256 Library */ 2 | #include 3 | #include "pinDefines.h" 4 | 5 | 6 | /* Which pin selects EEPROM as slave? */ 7 | #define SLAVE_SELECT SPI_SS_PORT &= ~(1 << SPI_SS) 8 | #define SLAVE_DESELECT SPI_SS_PORT |= (1 << SPI_SS) 9 | 10 | // Instruction Set -- from data sheet 11 | #define EEPROM_READ 0b00000011 /* read memory */ 12 | #define EEPROM_WRITE 0b00000010 /* write to memory */ 13 | 14 | #define EEPROM_WRDI 0b00000100 /* write disable */ 15 | #define EEPROM_WREN 0b00000110 /* write enable */ 16 | 17 | #define EEPROM_RDSR 0b00000101 /* read status register */ 18 | #define EEPROM_WRSR 0b00000001 /* write status register */ 19 | 20 | // EEPROM Status Register Bits -- from data sheet 21 | // Use these to parse status register 22 | #define EEPROM_WRITE_IN_PROGRESS 0 23 | #define EEPROM_WRITE_ENABLE_LATCH 1 24 | #define EEPROM_BLOCK_PROTECT_0 2 25 | #define EEPROM_BLOCK_PROTECT_1 3 26 | 27 | #define EEPROM_BYTES_PER_PAGE 64 28 | #define EEPROM_BYTES_MAX 0x7FFF 29 | 30 | // Functions 31 | 32 | void initSPI(void); 33 | /* Init SPI to run EEPROM with phase, polarity = 0,0 */ 34 | 35 | void SPI_tradeByte(uint8_t byte); 36 | /* Generic. Just loads up HW SPI register and waits */ 37 | 38 | void EEPROM_send16BitAddress(uint16_t address); 39 | /* splits 16-bit address into 2 bytes, sends both */ 40 | 41 | uint8_t EEPROM_readStatus(void); 42 | /* reads the EEPROM status register */ 43 | 44 | void EEPROM_writeEnable(void); 45 | /* helper: sets EEPROM write enable */ 46 | 47 | uint8_t EEPROM_readByte(uint16_t address); 48 | /* gets a byte from a given memory location */ 49 | 50 | uint16_t EEPROM_readWord(uint16_t address); 51 | /* gets two bytes from a given memory location */ 52 | 53 | void EEPROM_writeByte(uint16_t address, uint8_t byte); 54 | /* writes a byte to a given memory location */ 55 | 56 | void EEPROM_writeWord(uint16_t address, uint16_t word); 57 | /* gets two bytes to a given memory location */ 58 | 59 | void EEPROM_clearAll(void); 60 | /* sets every byte in memory to zero */ 61 | -------------------------------------------------------------------------------- /Chapter18_Using-Flash-Program-Memory/progmemDemo5/progmemDemo5.c: -------------------------------------------------------------------------------- 1 | /* Fourth step into using program memory */ 2 | /* Passing data array pointers to functions */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "USART.h" 8 | 9 | const uint16_t myData[] PROGMEM = 10 | { 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 10000 }; 11 | 12 | const char string1[] PROGMEM = "Hey, string one!\r\n"; 13 | const char string2[] PROGMEM = "Oh my, string two!\r\n"; 14 | const char *const stringIndex[] PROGMEM = { string1, string2 }; 15 | 16 | 17 | void printData_Progmem(const uint16_t * dataPointer, uint8_t length) { 18 | while (length) { 19 | printWord((uint16_t) dataPointer); /* print out address */ 20 | printString(": "); 21 | printWord(pgm_read_word(dataPointer)); /* print out data */ 22 | printString("\r\n"); 23 | dataPointer++; /* move to next byte */ 24 | length--; /* one less byte to go */ 25 | _delay_ms(100); 26 | } 27 | } 28 | void printString_Progmem(const char *stringP) { 29 | char oneLetter; 30 | while ((oneLetter = pgm_read_byte(stringP))) { 31 | transmitByte(oneLetter); 32 | stringP++; 33 | } 34 | } 35 | 36 | int main(void) { 37 | initUSART(); 38 | 39 | uint8_t myArray[] = { 10, 11, 12 }; 40 | uint8_t *p; 41 | uint8_t i; 42 | p = &myArray[0]; 43 | for (i = 0; i < sizeof(myArray); i++) { 44 | printByte(*(p + i)); 45 | printString("\r\n"); 46 | _delay_ms(1000); 47 | } 48 | 49 | 50 | /* To use them: */ 51 | char *stringPointer; 52 | /* Get the pointer to the string you want from PROGMEM */ 53 | 54 | stringPointer = (char *) pgm_read_word(&stringIndex[0]); 55 | printString_Progmem(stringPointer); 56 | /* or */ 57 | stringPointer = (char *) pgm_read_word(&stringIndex[1]); 58 | printString_Progmem(&stringPointer[0]); 59 | /* or */ 60 | printString_Progmem(PSTR("And this string got inlined.\r\n")); 61 | 62 | while (1) { 63 | printData_Progmem(myData, sizeof(myData) / sizeof(myData[0])); 64 | printString("\r\n"); 65 | _delay_ms(1000); 66 | } /* End event loop */ 67 | return 0; /* This line is never reached */ 68 | } 69 | --------------------------------------------------------------------------------