I had a hell of a time trying to get this to work. Most of the code out there is for the ATTiny85 with the Arduino bootloader, which I’m not using. A lot of the code that I found was old and/or wrong. The AVR programming documentation is somewhat terse and hard to deal with.. not fun at all. All I wanted to do was to find a way to put the ATTiny13A to sleep in power save mode, then wake it up again with the watchdog timer. This just for blinking an LED slowly (slower than in this code) for use as decorative elements in model making. The models are small so the LEDs will be powered by small cells such as LR44’s or R2032’s, so I need to be power efficient. At time of writing, I still haven’t got Atmel Studio (formerly AVR Studio) to run AVRDude properly, but it works fine on the command line, so that’s a fight for another day. On that note – if you want to develop code for the ATTiny13A without the Arduino IDE, you need to install WINAVR even if you are using Atmel Studio. Also, if you’re on Windows, and you’re using a USBASP to program the Tiny, google for an app called “Zadig”. It can install the correct driver for you – you need to choose libusbK rather than the default option.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
// Power down sleep re-awoken by watchdog timer demo // for the ATTiny13A // Connect LED to PB3 (pin 2 on the ATTiny13A) #include <avr/io.h> #include <avr/wdt.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <util/delay.h> // Utility macros #define adc_disable() (ADCSRA &= ~(1<<ADEN)) #define adc_enable() (ADCSRA |= (1<<ADEN)) #define _BV(bit) (1 << (bit)) // this appears all over code that I've seen on the internet, but it's not in the avr headers??? int main (void) { adc_disable(); // ADC uses ~320uA wdt_enable(WDTO_2S); // set the watchdog to roughly 2 seconds WDTCR |= _BV(WDTIE); // enable watchdog timer interrupt DDRB = 0b00001000; // set PB3 to be output set_sleep_mode(SLEEP_MODE_PWR_DOWN); while (1) { cli(); if (1) // or put a sleep condition in here { sleep_enable(); sei(); sleep_cpu(); sleep_disable(); } sei(); // PB3 high - LED on PORTB = 0b00001000; _delay_ms(60); // PB3 low PORTB = 0b00000000; _delay_ms(100); // don't need this, but was here for testing } return 1; } |