#define F_CPU 12000000UL #include #include #include #define WORD uint16_t #define BYTE unsigned char /************************************************** Konstanty **************************************************/ #define TopTime 1800 //maximální čas pro countdown 1800s (30min) #define SecFreq 750 //sekundy - každý 750tý průchod je 1s int bezi = 0; //hodiny běží nebo neběží 1/0 /************************************************** Znaková sada **************************************************/ BYTE chartable[10] = { /*0*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5), /*1*/ 0x00 | _BV(PB1) | _BV(PB2), /*2*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB4) | _BV(PB6), /*3*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB6), /*4*/ 0x00 | _BV(PB1) | _BV(PB2) | _BV(PB5) | _BV(PB6), /*5*/ 0x00 | _BV(PB0) | _BV(PB2) | _BV(PB3) | _BV(PB5) | _BV(PB6), /*6*/ 0x00 | _BV(PB0) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6), /*7*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB2), /*8*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6), /*9*/ 0x00 | _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB5) | _BV(PB6) }; /************************************************** Prototypy **************************************************/ void T0setup (); //nastavení timeru 0 void zapiscislo (WORD); //zápis čísla na sedmisegmentovku int tlacitko (); //stisk tlačítka void zobrazpozici (BYTE, BYTE); //zobrazí číslici (0-9) na určité pozici (1-4) /************************************************** Timer0 přerušení 750Hz Počítá sekundy a občerstvuje display **************************************************/ ISR(TIMER0_COMP_vect) { /*Countdown 1 sekunda je právě když počet průchodů je 750*/ static WORD pruchody = SecFreq; //čítač průchodů (750..0) static WORD cntsec = 0; //čítač sekund pruchody --; if (cntsec == 0) cntsec = TopTime; if (!pruchody) { //počítadlo na konci? pruchody = SecFreq; //nastav maximum if (bezi) cntsec --; //pokud hodiny běží, sniž počet sekund } /*Občerstvení displaye*/ if ((pruchody % 1) == 0) { //display se občersvuje 750x za sekundu zapiscislo (cntsec); //v každém průchodu vždy 1 pozice ze čtyř } //frekvence každé pozice je 750/4 } /************************************************** main **************************************************/ int main (void) { T0setup (); //nastavení T0 sei(); //povolení přerušení DDRC &= ~_BV(DDC7); //PC7 - tlačítko PORTC |= _BV(PC7); while(1) { //smyčka if (tlacitko () && bezi) { //zastaví hodiny bezi = 0; while (tlacitko ()) {} //zůstane zacyklený, aby se reagovalo puze na jeden stisk } if (tlacitko () && !bezi) { //spustí hodiny bezi = 1; while (tlacitko ()) {} //zůstane zacyklený, aby se reagovalo puze na jeden stisk } } return 0; } /************************************************** Funkce **************************************************/ void T0setup () { TCCR0 &= 0x00; TCCR0 |= (1< 999) { cislice = (cas - zbytek) / 1000; zbytek = cislice * 1000; } break; case 3: if (cas > 99) { cislice = (cas - zbytek) / 100; zbytek += cislice * 100; } break; case 2: if (cas > 99) { cislice = (cas - zbytek) / 10; zbytek += cislice * 10; } break; case 1: cislice = (cas - zbytek); zbytek = 0; break; } zobrazpozici (cislovka, cislice); if (cislovka == 1) cislovka = 5; } /**************************************************/ int tlacitko () { int ret; ret = 0; if (!(PINC & _BV(PC7))) { int i; for (i = 0; i < 255; i++) { ret += (!(PINC & _BV(PC7)) ? 1 : 0); } } return ret==255 ? 1 :0; } /**************************************************/ void zobrazpozici (BYTE pozice, BYTE cislo) { DDRA |= _BV(DDA4) | _BV(DDA5) | _BV(DDA6) | _BV(DDA7); DDRB |= _BV(DDB7) | _BV(DDB6) | _BV(DDB5) | _BV(DDB4) | _BV(DDB3) | _BV(DDB2) | _BV(DDB1) | _BV(DDB0); PORTB &= 0x00; //zhasnutí segmentů PORTA &= 0; PORTB |= chartable [cislo]; //nastavení číslice switch (pozice) { //rozsvícení příslušné pozice case 1: PORTA |= _BV(PA7); break; case 2: PORTA |= _BV(PA6); break; case 3: PORTA |= _BV(PA5); break; case 4: PORTA |= _BV(PA4); break; } }