Created
February 9, 2011 19:08
-
-
Save jaytaph/819034 to your computer and use it in GitHub Desktop.
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/interrupt.h> | |
#include <avr/io.h> | |
#define INIT_TIMER_COUNT 100 | |
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT | |
// These are the digits from 0 to 9, with 7 segments | |
byte ssd[10][7] = { | |
{ 1,1,1,1,1,1,0 }, | |
{ 0,1,1,0,0,0,0 }, | |
{ 1,1,0,1,1,0,1 }, | |
{ 1,1,1,1,0,0,1 }, | |
{ 0,1,1,0,0,1,1 }, | |
{ 1,0,1,1,0,1,1 }, | |
{ 1,0,1,1,1,1,1 }, | |
{ 1,1,1,0,0,0,0 }, | |
{ 1,1,1,1,1,1,1 }, | |
{ 1,1,1,1,0,1,1 } | |
}; | |
// LCD pins, LSB (least significant digit) is 2, MSB is 5 | |
// So the number "1234" gets stored to: | |
// 4 => pin 2 | |
// 3 => pin 3 | |
// 2 => pin 4 | |
// 1 => pin 5 | |
byte lcd_offset[] = { | |
5,4,3,2, | |
25,24,23,22, | |
29,28,27,26, | |
0 | |
}; | |
#define SEG_OFFSET 6 | |
#define SEG_DOT 13 | |
// Counters. 1 counter per 'block' of 4 digits | |
int rc[4]; | |
// Called lots of times per second (can't remember the freq) | |
ISR(TIMER2_OVF_vect) { | |
// Reset timer again | |
RESET_TIMER2; | |
// Increase our mini counter | |
// Increase counter | |
rc[0]++; | |
// Overflow? increase next block | |
if (rc[0] > 9999) { | |
rc[0] = 0; | |
rc[1]++; | |
} | |
// Overflow? increase next block | |
if (rc[1] > 9999) { | |
rc[1]= 0; | |
rc[2]++; | |
} | |
// Overflow? increase next block | |
if (rc[2] > 9999) { | |
rc[2]= 0; | |
rc[3]++; | |
} | |
// Don't care about rc3 overflow | |
}; | |
/** | |
* Will be run on startup/reset | |
*/ | |
void setup() { | |
// Set all pins to output (lazy, we should only set pins we actually use) | |
for (int i=2; i!=32; i++) pinMode(i, OUTPUT); | |
// Reset counter | |
rc[0] = rc[1] = rc[2] = rc[3] = 0; | |
// set irq to 244 Hz: CS22-bit = 1, CS21-bit = 1, CS20-bit = 0 | |
TCCR2B |= ( (0<<CS22) | (0<<CS21)); | |
TCCR2B &= ~( (0<<CS20) ); | |
TCCR2A &= ~((0<<WGM21) | (1<<WGM20)); | |
TIMSK2 |= (1<<TOIE2); | |
TIMSK2 &= ~( (1<<OCIE2A) | (1<<OCIE2B) ); | |
RESET_TIMER2; | |
sei(); | |
} | |
/** | |
* Selects the current LCD we want to set, all others will be set to HIGH. | |
* Sounds strange, but we actually set something by making it LOW instead of | |
* high. Maybe I just switched something around. That is still a possibility | |
*/ | |
void lcd_select(int lcd) { | |
int i = 0; | |
while (lcd_offset[i]) { | |
digitalWrite(lcd_offset[i], (i == lcd) ? LOW : HIGH); | |
i++; | |
} | |
} | |
/** | |
* Write a number to an LCD block. A number is a max 4 digit number (between 0 and | |
* 9999) so it writes to 4 sequential LCD's. BLockNr which block (in our case, | |
* block 0, 1 or 2) | |
*/ | |
void lcd_write(int block_nr, int r) { | |
int i; | |
// Write to 4 digits (LSB first) | |
for (int l=3; l>=0; l--) { | |
// First, all segments should be turned off. Otherwise we get "ghosts" on the | |
// block we want to write | |
for (int j=0; j!=7; j++) digitalWrite(SEG_OFFSET+j, HIGH); | |
// All segments are off, we can safely select our new block. | |
lcd_select((block_nr*4) + l); | |
// Get LSB digit xxx4 | |
i = r % 10; | |
r /= 10; // shift so next LSB will be the next number | |
// Set all correct segments (according to our lookup table). | |
for (int j=0; j!=7; j++) { | |
digitalWrite(SEG_OFFSET+j, ssd[i][j] ? LOW : HIGH); | |
} | |
// Don't write a dot.. Still need to figure out how to deal with this | |
// (maybe do fixedpoint stuff?) | |
digitalWrite(SEG_DOT, HIGH); | |
// Delay a bit. 5 is like watching a CRT on a home-video, 1 gives the best result. | |
delay(1); | |
} | |
} | |
void loop() { | |
// Just write the data. Timer will take care of increasing the counters | |
lcd_write(0, rc[0]); | |
lcd_write(1, rc[1]); | |
lcd_write(2, rc[2]); | |
// lcdwrite(3, r[3]); // still room for 1 more block :) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment