/************************************************************
* Spell text on LEDs - POV (Persistence of Vision) *
* *
* 20050920 *
* sklarm@electric-clothing.com *
* m@unlikely.org *
* *
************************************************************/
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define TEXT_MAXLEN 9 /* MAX length of characters to display */
#define TIMER0_PRESCALER_1 0x01
#define TIMER0_PRESCALER_8 0x02
#define TIMER0_PRESCALER_64 0x03
#define TIMER0_PRESCALER_256 0x04
#define TIMER0_PRESCALER_1024 0x05
void letter_to_pov(char alpha);
SIGNAL(SIG_OVERFLOW0);
/*
* Blink this string
* - user lowercase only
*/
char message[TEXT_MAXLEN] = "code:";
/*
* Letter of message
*/
char *lom;
/*
* Column of Letter
*/
int *col;
/*
* White Space flag (auto inserted between characters)
*/
int ws=0;
int main(void)
{
/*
* Enable PORTA 0-6 as outputs
* Enable PORTB 0-6 as outputs
*/
DDRA=0x7F;
DDRB=0x7F;
/*
* prescaler setup for timer0
*/
TCCR0=TIMER0_PRESCALER_256;
/*
* start timer with nothing
*/
TCNT0=0x00;
/*
* set lowest BIT of TIMSK to enable overflow interrupt
*/
timer_enable_int(1<<TOIE0);
/*
* Set (global) Enable Interrupts
*/
sei();
lom = message;
letter_to_pov(*lom);
while(1);
}
/*
* Timer0 Interrupt Service Routine
* - 8bit
* - rollover occurs at 255
* - TCCR0 - Timer Counter Control Register
* - 256 divide ( CS00 = 0 / CS01 = 0 / CS02 = 1 )
* - 1MHz (clock) / 256 prescalar = 3906.25
* - 1 / 3906.25 (period) = .256ms = 256us
* - requires reload of (256 - 234)
* - reload 22
* - 22us
* - frequency 5405Hz
* - Flash letters at 5405Hz
*/
SIGNAL(SIG_OVERFLOW0) {
/*
* reload timer
* prescalar 256
*/
TCNT0=0xEA;
/*
* Logic for adding a double white space delay
* between each characters hex codes.
*
* Move to next letter when we have reached the end
* hex code.
*/
if ( *col == 0x00 && ws < 2 ) {
ws = ws + 1;
} else if ( ws >= 2 ) {
lom++;
letter_to_pov(*lom);
ws = 0;
}
/*
* restart message
*/
if ( *lom == ':' ) {
lom = message;
letter_to_pov(*lom);
}
/*
* Send Column of letters to PORTB
*/
PORTB = *col;
PORTA = *col;
col++;
}
/*
* Alphabetic representation in 7bit coordinates
* Converts letter to blinking light format
*
* (example 'a' , 'b', 'c', and 'd' below)
*
* ***** ****** ****** *******
* * * * * * * *
* * * * * * * *
* ******* **** * * *
* * * * * * * *
* * * * * * * *
* * * ****** ****** *******
*
*/
void letter_to_pov(char alpha)
{
static int space[] = {0x00};
static int letters[][20] = {
{0x3f,0x48,0x48,0x48,0x3f,0x00}, /* A */
{0x7f,0x49,0x49,0x49,0x36,0x00}, /* B */
{0x3e,0x41,0x41,0x41,0x22,0x00}, /* C */
{0x7f,0x41,0x41,0x41,0x3e,0x00}, /* D */
{0x7f,0x49,0x49,0x41,0x00}, /* E */
{0x7f,0x48,0x48,0x40,0x00}, /* F */
{0x3e,0x41,0x49,0x49,0x2e,0x00}, /* G */
{0x7f,0x08,0x08,0x08,0x7f,0x00}, /* H */
{0x7f,0x00}, /* I */
{0x02,0x01,0x01,0x7e,0x00}, /* J */
{0x7f,0x08,0x18,0x24,0x43,0x00}, /* K */
{0x7f,0x01,0x01,0x01,0x00}, /* L */
{0x3f,0x40,0x40,0x3f,0x40,0x40,0x3f,0x00}, /* M */
{0x7f,0x20,0x1C,0x02,0x7f,0x00}, /* N */
{0x3e,0x41,0x41,0x41,0x3e,0x00}, /* O */
{0x3f,0x48,0x48,0x48,0x30,0x00}, /* P */
{0x3e,0x41,0x45,0x43,0x3f,0x00}, /* Q */
{0x7f,0x48,0x4c,0x4A,0x31,0x00}, /* R */
{0x32,0x49,0x49,0x49,0x26,0x00}, /* S */
{0x40,0x40,0x7F,0x40,0x40,0x00}, /* T */
{0x3e,0x01,0x01,0x01,0x3e,0x00}, /* U */
{0x78,0x06,0x01,0x06,0x78,0x00}, /* V */
{0x7e,0x01,0x01,0x7e,0x01,0x01,0x7e,0x00}, /* W */
{0x41,0x22,0x1c,0x22,0x41,0x00}, /* X */
{0x40,0x20,0x1f,0x20,0x40,0x00}, /* Y */
{0x43,0x45,0x49,0x51,0x61,0x00} /* Z */
};
if (alpha == ' ') {
col = space;
} else {
col = letters[alpha - 'a'];
}
}