Skip to content

Instantly share code, notes, and snippets.

@bradford-hamilton
Last active April 24, 2023 23:42
Show Gist options
  • Save bradford-hamilton/1a9491894dad2d9abba2b779e7a6b827 to your computer and use it in GitHub Desktop.
Save bradford-hamilton/1a9491894dad2d9abba2b779e7a6b827 to your computer and use it in GitHub Desktop.
ATtiny85 - final code example for Part 1 of blog
// When addressing I/O Registers as data space using LD and ST
// instrucrutions, 0x20 must be added to these addresses.
#define OFFSET 0x20
// Macro helper for registers
#define REG(addr) *((volatile unsigned char*)(addr+OFFSET))
// Port B Data Direction Register
#define DDRB REG(0x17)
// Port B Data Register
#define PORTB REG(0x18)
// Timer/Counter Control Register B
#define TCCR0B REG(0x33)
// Timer/Counter Interrupt Mask Register
#define TIMSK REG(0x39)
// Creates a bitmask for a specific bit position. The input (bit)
// represents the bit position you want to create a bitmask for.
#define BV_MASK(bit) (1 << (bit))
// Inline assembly for SEI instruction
#define ASM_SEI() __asm__ __volatile__ ("sei" ::: "memory")
// Handler function for the TIMER0_OVF (Timer/Counter0 Overflow) interrupt
// (vector at 0x0005 from datasheet). The naming (__vector_+vector#) plus
// the `signal` attribute is ultimately what the compiler needs in order
// to know this is an ISR handler and to patch the vector table, etc.
void __vector_5(void) __attribute__ ((signal));
void __vector_5(void) { PORTB ^= BV_MASK(0); }
int main()
{
// Set data direction for Port B bit 0 (PB0)
DDRB |= BV_MASK(0);
// Set prescale timer to 1/1024th the clock rate
TCCR0B = BV_MASK(2) | BV_MASK(0);
// Enable timer overflow interrupt
TIMSK |= BV_MASK(1);
// Enable global interrupts with assembly
ASM_SEI();
while (1) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment