Skip to content

Instantly share code, notes, and snippets.

@Marzogh
Created August 20, 2015 12:46
Show Gist options
  • Save Marzogh/d1a2f67de6ef38450610 to your computer and use it in GitHub Desktop.
Save Marzogh/d1a2f67de6ef38450610 to your computer and use it in GitHub Desktop.
Charlieplexing 6 LEDs on ATTiny85
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
void setLED(uint8_t LED);
uint8_t currentLED;
uint8_t times = 0;
/*
LEDs connected to PB0, PB1 and PB2
Truth table for LED matrix
Led | Pin High | Pin Low | Pin Disc. | PORTB | DDRB |
0 | 0 | 1 | 2 | 0x01 | xFB |
1 | 1 | 0 | 2 | 0x02 | xFB |
2 | 1 | 2 | 0 | 0x02 | xFE |
3 | 2 | 1 | 0 | 0x04 | xFE |
4 | 0 | 2 | 1 | 0x02 | xFD |
5 | 2 | 0 | 1 | 0x04 | xFD |
*/
void main()
{
LED_PORT &= 0xF8; // Set lower 3 bits to 0, i.e. off
LED_DDR |= 0x07; // Set lower 3 bits to 1, i.e. output
// Set up timer prescalar to FCpu/64 @ 1MHz
TCCR0B |= (_BV(CS00) | _BV(CS02));
// Set timer to CTC mode
TCCR0A |= _BV(WGM01);
// Enable CTC interrupt
TIMSK |= _BV(OCIE0A);
// Enable global interrupts
sei();
// Set timer to compare 1/4 second
OCR0A = 243;
while(1)
{
//Turn on an LED
setLED(currentLED);
}
}
// Handle timer interrupt
// This triggers the interrupt every 1/2th of a second
// ATTiny85's Timer0 is 8 bit and therefore cannot store OCR0A values higher than 255
// This is a quick and dirty way to get the 2Hz refresh rate
ISR(TIMER0_COMPA_vect)
{
int i;
times++;
if (times >= 2)
{
// Get random number for i
i = rand() % 14;
if (i != currentLED)
{
currentLED = i;
}
else
{
i = rand() % 14;
}
// Reset clock repeats
times = 0;
}
}
// Switch the state of the LED from on to off or from off to on
void setLED(uint8_t LED)
{
//Clear existing status, we can only drive one LED at a time
PORTB &= 0xF8; // Set the lower 3 bits to 0, i.e. off
DDRB |= 0x07; // Set the lower 3 bits to 1, i.e. output
switch (LED)
{
case 0:
DDRB &= 0xFB; // Disconnect the nr. 2 pin
PORTB |= 0x01; // Set pin 0 to high and pin 1 to low
break;
case 1:
DDRB &= 0xFB; // Disconnect the nr. 2 pin
PORTB |= 0x02; // Set pin 1 to high and pin 0 to low
break;
case 2:
DDRB &= 0xFE; // Disconnect the nr. 0 pin
PORTB |= 0x02; // Set pin 1 to high and pin 2 to low
break;
case 3:
DDRB &= 0xFE; // Disconnect the nr. 0 pin
PORTB |= 0x04; // Set pin 2 to high and pin 1 to low
break;
case 4:
DDRB &= 0xFD; // Disconnect the nr. 1 pin
PORTB |= 0x01; // Set pin 0 to high and pin 2 to low
break;
case 5:
DDRB &= 0xFD; // Disconnect the nr. 1 pin
PORTB |= 0x04; // Set pin 2 to high and pin 0 to low
break;
default:
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment