Skip to content

Instantly share code, notes, and snippets.

@raphaelschaad
Last active November 18, 2015 10:00
Show Gist options
  • Save raphaelschaad/a05001b26214e95ab63a to your computer and use it in GitHub Desktop.
Save raphaelschaad/a05001b26214e95ab63a to your computer and use it in GitHub Desktop.
//
// att45_schaad1.c
//
// Created by Raphael Schaad on 2015-11-16.
// 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. iotn45.h for our chip, defining PORTB/DDRB/PBn -- 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/output_devices/H-bridge/hello.H-bridge.44.png
// With my redesign and enhancements: http://fab.cba.mit.edu/classes/863.15/section.CBA/people/Schaad/week9-output-devices.html
#define BTN1 (1 << PB2) // left (pin 7)
#define BTN2 (1 << PB3) // center (pin 2)
#define BTN3 (1 << PB4) // right (pin 3)
#define MOTORCCW (1 << PB0) // IN1 (pin 5)
#define MOTORCW (1 << PB1) // IN2 (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
// Bootloader calls main(void) when the chip gets power
int main() {
// Configure digital I/O pins DDRB (bits are 0-based index)
output(DDRB, MOTORCCW);
output(DDRB, MOTORCW);
// For input, also turn on pullup resistors with set(PORTB, BTNn)
input(DDRB, BTN1);
set(PORTB, BTN1);
input(DDRB, BTN2);
set(PORTB, BTN2);
input(DDRB, BTN3);
set(PORTB, BTN3);
// PWM to slow motor down
const double kPWMOnDuration = 1.0; // in ms
const double kPWMSleepDuration = 10.0; // in ms
bool motorCWOn = false;
bool motorCCWOn = false;
// Spin event loop
while (true) {
if (motorCWOn) {
set(PORTB, MOTORCW);
_delay_ms(kPWMOnDuration);
clear(PORTB, MOTORCW);
_delay_ms(kPWMSleepDuration);
} else {
clear(PORTB, MOTORCW);
}
if (motorCCWOn) {
set(PORTB, MOTORCCW);
_delay_ms(kPWMOnDuration);
clear(PORTB, MOTORCCW);
_delay_ms(kPWMSleepDuration);
} else {
clear(PORTB, MOTORCCW);
}
// Once center button is pressed, turn motor CW.
if (!pin_test(PINB, BTN2)) {
motorCWOn = true;
}
// Once right button is hit, turn motor off.
if (!pin_test(PINB, BTN3)) {
motorCWOn = false;
// Clear immediately because of following delay stalling the event loop.
clear(PORTB, MOTORCW);
// Lift flag off the right button by turning motor back CCW just a bit.
const unsigned int kCount = 30;
unsigned int i;
for (i = 0; i < kCount; ++i) {
set(PORTB, MOTORCCW);
_delay_ms(kPWMOnDuration);
clear(PORTB, MOTORCCW);
_delay_ms(kPWMSleepDuration);
}
// Wait for 7 seconds, and turn motor back CCW.
_delay_ms(7000.0);
motorCCWOn = true;
}
// Once left button is hit, turn motor off.
if (!pin_test(PINB, BTN1)) {
motorCCWOn = false;
}
}
// When main(void) exits, the chip goes idle
return 0;
}
#
# att45_schaad1.make
#
# Created by Raphael Schaad on 2015-11-16.
# This is free and unencumbered software released into the public domain.
#
PROJECT=att45_schaad1
SOURCES=$(PROJECT).c
MMCU=attiny45
CFLAGS=-mmcu=$(MMCU) -Wall -Os
$(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 t45 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment