Created
August 20, 2015 12:46
-
-
Save Marzogh/d1a2f67de6ef38450610 to your computer and use it in GitHub Desktop.
Charlieplexing 6 LEDs on ATTiny85
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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