|
【更新後的main.c文件】 #include <avr/io.h> #include <avr/eeprom.h> #include <avr/pgmspace.h> #include <avr/sfr_defs.h> #define F_CPU 1200000U #include <util/delay.h> #include "74HC595.h"
#define K1 (PINB&_BV(3))
const uint8_t* EEPROM_START = 0x00; unsigned char count = 0; unsigned char num = 0x0; unsigned char left = 252; unsigned char right = 0;
unsigned char status = 0x00; #define ROLL 7 #define PAUSE 5
const unsigned char NUM0TO7[] PROGMEM = { 0x0C, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0C, 0x00, 0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x0C, 0x12, 0x10, 0x08, 0x04, 0x02, 0x1E, 0x00, 0x0C, 0x12, 0x10, 0x0C, 0x10, 0x12, 0x0C, 0x00, 0x08, 0x0C, 0x0C, 0x0A, 0x0A, 0x1E, 0x08, 0x00, 0x1E, 0x02, 0x02, 0x0E, 0x10, 0x10, 0x0E, 0x00, 0x0C, 0x12, 0x02, 0x0E, 0x12, 0x12, 0x0C, 0x00, 0x1E, 0x12, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00};
unsigned char read(unsigned char pos) { if (pos < 64) return pgm_read_byte(NUM0TO7 + pos); else { pos -= 64; eeprom_busy_wait(); return eeprom_read_byte(EEPROM_START + pos); } }
void matrixFull(void) { uint8_t i, tmp; uint32_t cnt = 100; while (cnt--) { tmp = 1; for (i = 0; i < 8; i++) { HC595_SerIn(~tmp); // 寫成~_BV(i)太占空間, 改成這種形式會節約一點空間 HC595_SerIn(0x00); HC595_ParOut(); _delay_ms(1); tmp <<= 1; } } }
void matrixScan(unsigned char times) { unsigned char i; while (times--) { if (status & _BV(ROLL)) { /* Roll numbers 0x0 ~ 0xF */ for (i = 0; i < 8; i++) { HC595_SerIn(~_BV(i)); if (i < 7) { if (left > 200) { /* -1 => 255 (<<4), 4 = 3 + (56 - ([255] - 200)) ** -2 => 254 (<<5), 5 = 3 + (56 - ([254] - 200)) ** -3 => 253 (<<6), 6 = 3 + (56 - ([253] - 200)) ** -4 => 252 (<<7), 7 = 3 + (56 - ([252] - 200)) : completely hidden **/ right = (read(num * 8 + i) << (3 + (56 - (left - 200)))); } else right = ((read(num * 8 + i) << 3) >> left); } else { /* The dot at the bottom */ if (num == 0x0 && (left == 0 || left > 200)) { // Do not display ". 0" right = 0x00; } else if (num == 0xf && (left >= 3 && left < 200)) { // Do not display "F ." right = 0x00; } else { if (left < 200 && left >= 5) right = (0x80 >> (left - 5)); else if (left > 200) { /* -4 => 252 (>>3), 3 = [252] - 249 ** -3 => 253 (>>4), 4 = [253] - 249 ** -2 => 254 (>>5), 5 = [254] - 249 ** -1 => 255 (>>6), 6 = [255] - 249 **/ right = (0x80 >> (left - 249)); } else if (left == 0) right = 0x01; else right = 0x00; } } HC595_SerIn(~right); HC595_ParOut(); _delay_us(500); } if (!(status & _BV(PAUSE))) { count++; if (count >= 10) { count = 0; left++; if (left < 200 && left >= 8) { // display the next number left = 252; num++; if (num >= 0x10) { // when all the 16 numbers have appeared num = 0x00; status &= ~_BV(ROLL); // stop rolling numbers } } } } } else { /* Display Numbers 0x00 ~ 0xFF */ for (i = 0; i < 8; i++) { HC595_SerIn(~_BV(i)); left = (read((num / 0x10) * 8 + i) >> 1); right = (read((num % 0x10) * 8 + i) << 3); HC595_SerIn(~(left | right)); HC595_ParOut(); _delay_us(500); } if (!(status & _BV(PAUSE))) { count++; if (count >= 80) { count = 0; num++; // num is from 0x00 to 0x99; it's impossible to be 0x100 if (num == 0x00) { status |= _BV(ROLL); // begin to roll numbers num = 0x0; left = 252; } } } } } }
void keyScan(void) { // PAUSE Key if (!K1) { matrixScan(7); if (!K1) { if (status & _BV(PAUSE)) { PORTB |= _BV(4); status &= ~_BV(PAUSE); } else { PORTB &= ~_BV(4); status |= _BV(PAUSE); } while (K1) matrixScan(5); matrixScan(14); } } }
int main(void) { DDRB = 0x17; // 00010111 PORTB = 0x1f; // 00011111 matrixFull(); status |= _BV(ROLL); while (1) { matrixScan(1); keyScan(); } return 0; }
|