Last active
November 25, 2015 18:51
-
-
Save raphaelschaad/39b1aee15d8aab48e73a to your computer and use it in GitHub Desktop.
AVR-C code + makefile. See: http://fab.cba.mit.edu/classes/863.15/section.CBA/people/Schaad/week8-embedded-programming.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// att44_schaad1.c | |
// | |
// Created by Raphael Schaad on 2015-11-03. | |
// This is free and unencumbered software released into the public domain. | |
// | |
// Import headers installed with CrossPack-AVR (/usr/local/CrossPack-AVR/) | |
#include "stdbool.h" // So we have 'true' and 'false' instead of 1 and 0 (might have memory implications) -- lib/gcc/avr/4.8.1/include/ | |
#include <avr/io.h> // Umbrella header including e.g. iotn44a.h for our chip, defining PORTx/DDRx/Pxn etc. (mapping to addresses from data sheet) -- avr/include/avr/ | |
#include <util/delay.h> // _delay_us/ms convenience functions for actual time values rather than number of cycles -- avr/include/util | |
// Hardware: | |
// Based on Neil Gershenfeld's board: http://academy.cba.mit.edu/classes/embedded_programming/index.html#echo | |
// With my redesign and enhancements: http://fab.cba.mit.edu/classes/863.15/section.CBA/people/Schaad/week6-electronics-design.html | |
#define LED1 (1 << PB2) // red (pin 5) | |
#define LED2 (1 << PA2) // green (pin 11) | |
#define LED3 (1 << PA3) // green (pin 10) | |
#define BTN1 (1 << PA7) // (pin 6) | |
// Convenience macros | |
#define output(directions, pin) (directions |= pin) // set port direction for output | |
#define input(directions, pin) (directions &= (~pin)) // set port direction for input | |
#define set(port, pin) (port |= pin) // set port pin | |
#define clear(port, pin) (port &= (~pin)) // clear port pin | |
#define pin_test(pins, pin) (pins & pin) // test for port pin | |
#define bit_test(byte, bit) (byte & (1 << bit)) // test for bit set | |
// Copied configuration defines -- but I find this abstraction more confusing | |
// #define input_port PORTA // BTN1 is on port A | |
// #define input_direction DDRA // DDRA defines input/output for port A | |
// #define input_pin (1 << PA7) // BTN1 is on pin 7 of port A | |
// #define input_pins PINA // PINA is the register that is read to detect input high or low. | |
// #define output_port PORTB // Port B will be used for the LED | |
// #define output_direction DDRB // DDRB defines input/output for port B | |
// #define output_pin (1 << PB2) // LED1 is on pin 2 of port B | |
// Bootloader calls main(void) when the chip gets power | |
int main() { | |
// Set clock divider to 1 (default is 8, from CKDIV8 LFuse). | |
// The internal clock of t44/45 is max 8MHz but on this board we configure LFuse to use an external 20MHz resonator. | |
// This needs to be reflected in the Makefile with F_CPU = 20000000. | |
CLKPR = (1 << CLKPCE); | |
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); | |
// Configure digital I/O pins DDRA & DDRB (bits are 0-based index) | |
output(DDRB, LED1); // PB2 as output by setting bit 2 in register DDRB (= 0b00000100) | |
output(DDRA, LED2); | |
output(DDRA, LED3); | |
input(DDRA, BTN1); // PB7 as input by setting bit 7 in register DDRA (= 0b10000000) ... | |
set(PORTA, BTN1); // ... and on PORTA (= 0b10000000; turns on pullup resistor) | |
// Turn LED1 ON by default | |
set(PORTB, LED1); // PORTB = 0b00000100; | |
// Spin event loop | |
while (true) { | |
// Blink LED2/3 on button press | |
if (pin_test(PINA, BTN1)) { // (PINA & 0b10000000) == 1 | |
set(PORTB, LED1); | |
clear(PORTA, LED2); | |
clear(PORTA, LED3); | |
} else { | |
clear(PORTB, LED1); | |
if (pin_test(PINA, LED2)) { | |
set(PORTA, LED3); | |
clear(PORTA, LED2); | |
} else { | |
set(PORTA, LED2); | |
clear(PORTA, LED3); | |
} | |
_delay_ms(1000.0); | |
} | |
} | |
// When main(void) exits, the chip goes idle | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# att44_schaad1.make | |
# | |
# Created by Raphael Schaad on 2015-11-03. | |
# This is free and unencumbered software released into the public domain. | |
# | |
PROJECT=att44_schaad1 | |
SOURCES=$(PROJECT).c | |
MMCU=attiny44 | |
F_CPU = 20000000 | |
CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU) | |
$(PROJECT).hex: $(PROJECT).out | |
avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\ | |
avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out | |
$(PROJECT).out: $(SOURCES) | |
avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES) | |
program-usbtiny: $(PROJECT).hex | |
avrdude -p t44 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex | |
program-usbtiny-fuses: $(PROJECT).hex | |
avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment