Because the Arduino 1.8.5 did not accept the fuse settings in the boards.txt included in
the attiny13 core from Core13 download | SourceForge.net, I decided to try MicroCode.
No problem setting the fuses: 9.6Mhz, B.O.D 1.8v on the attiny13a.
Also compiling the sketch worked without errors.
However, the adc function I used to read an 8 bit value just returned a fixed value...
After a lot of tests, I did find a solution, but wonder why there is a difference.
Here is a test program which works using the attiny13 core.
When I uncomment the delay(1) just after the while(1) it also works using MicroCore.
Am I missing something?
#define DEBUG
#include <avr/sleep.h> // Sleep Modes
#include <avr/power.h> // Power management
#include <avr/interrupt.h>
#include <avr/wdt.h> // Watchdog timer
#include <stdlib.h>
#ifdef DEBUG
#include <BasicSerial.h> //Pin 5 = tx, 115200
#endif
#include <avr/io.h>
#define VOUTPIN PINB1
#define wdt_reset() __asm__ __volatile__ ("wdr")
const uint8_t wt8sec = (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(1<<WDP0);
const uint8_t wt4sec = (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(0<<WDP0);
const uint8_t wt2sec = (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(1<<WDP0);
const uint8_t wt1sec = (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(0<<WDP0);
#ifdef DEBUG
void serOut(const char* str)
{
while (*str) TxByte (*str++);
}
#endif
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
sleep_enable();
ADCSRA &= ~(1<<ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
power_all_disable();
sleep_mode(); // System actually sleeps here
sleep_disable();
power_all_enable();
ADCSRA |= (1<<ADEN); // switch Analog to Digitalconverter ON
}
//Change WDT timeout. Parameter is bit pattern
void wdt_setup(uint8_t wdttime )
{
cli();
wdt_reset();
// Start timed sequence
WDTCR = (0<<WDTIF) | (0<<WDTIE) |(0<<WDP3) | (1<<WDCE) | (1<<WDE) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);
// prescale timer to timeval so we can measure voltage
// Enable watchdog timer interrupts
WDTCR = (1<<WDTIF) | (1<<WDTIE) | wdttime | (0<<WDCE) | (0<<WDE);
sei(); // Enable global interrupts
}
void adc_setup (void)
{
// Set the ADC input to PB2/ADC1, 8 bit only, ref vcc
ADMUX = (1 << MUX0);
ADMUX |= (1 << ADLAR);
// Set the prescaler to clock/32 & enable ADC
// See ATtiny13 datasheet, Table 14.4.
ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}
// returns 0 - 255
int adc_read (void)
{
// Start the conversion
ADCSRA |= (1 << ADSC);
// Wait for it to finish.
while (ADCSRA & (1 << ADSC));
return ADCH;
}
int main (void)
{
uint8_t adc_val;
#ifdef DEBUG
char buf[8];
#endif
DDRB |= (1<<VOUTPIN); // set output pin to output mode
PORTB &= ~(1<<VOUTPIN); // turn on output, low
DDRB &= ~(1 << PB2); //Set PB2 as input
adc_setup();
wdt_setup(wt1sec);
while(1) {
//delay(1); //<-- MicroCode needs this?
adc_val = adc_read();
#ifdef DEBUG
itoa(adc_val,buf,10);
serOut("ADC = ");
serOut(buf);
serOut(" \n");
#endif
system_sleep();
}
return 0;
}