На базе ATtiny2313 можно собрать простой секундомер. Информация выводится на дисплей LCD1602. Для управления секундомером используются три кнопки — СТАРТ, СТОП, СБРОС. Минимальный шаг секундомера 0,1 секунда, максимальное время измерения 24 часа.
Кнопки СТОП и СТАРТ работают через прерывания IN0 и INT1 (пример — http://rcl-radio.ru/?p=94273), время тактируется при помощи таймера 1, частота прерывания таймера 0,1 с.
Перед загрузкой скетча рекомендую ознакомится со статьей — ATtiny2313 + Arduino IDE
// ATTINY2313 V1.25 // D4 = PB0 // D5 = PB1 // D6 = PB2 // D7 = PB3 // E = PB4 // RS = PD6 byte i1,hh,mm,ss,stop; void setup() { cli(); DDRD &= ~(1 << 2); DDRD &= ~(1 << 3); DDRD &= ~(1 << 4); PORTD |= (1 << 2) | (1 << 3) | (1 << 4); MCUCR |= (1 << ISC11) | (1 << ISC01); GIMSK |= (1 << INT0) | (1 << INT1); ////////////////////// TCCR1A = 0; TCCR1B = 0; OCR1A = 18750; // 0.1 s TCCR1B |= (1 << WGM12); TCCR1B &= ~(1 << CS12); TCCR1B &= ~ (1 << CS11); TCCR1B &= ~ (1 << CS10); TIMSK |= (1 << OCIE1A); sei(); lcdInit(); } void loop() { if(((PIND >> 4) & 1) == 0 && stop==1){hh=0,mm=0,ss=0;i1=0;} lcdCurs(0,6); lcdString("TIME"); lcdCurs(1,3); lcdInt(hh/10);lcdInt(hh%10);lcdString(":"); lcdInt(mm/10);lcdInt(mm%10);lcdString(":"); lcdInt(ss/10);lcdInt(ss%10);lcdString(".");lcdInt(i1); lcdCurs(1,3); } /////////////////////////////////////////////////////////////////////////////////////////// void lcdSend(bool rs, byte data) { if(rs==0){PORTD |= (1 << 6);} else{PORTD &= ~(1 << 6);}//RS del(); if(((data >> 7) & 1) ==1) PORTB |= (1 << 3); else PORTB &= ~(1 << 3); if(((data >> 6) & 1) ==1) PORTB |= (1 << 2); else PORTB &= ~(1 << 2); if(((data >> 5) & 1) ==1) PORTB |= (1 << 1); else PORTB &= ~(1 << 1); if(((data >> 4) & 1) ==1) PORTB |= (1 << 0); else PORTB &= ~(1 << 0); e_pin(); if(((data >> 3) & 1) ==1) PORTB |= (1 << 3); else PORTB &= ~(1 << 3); if(((data >> 2) & 1) ==1) PORTB |= (1 << 2); else PORTB &= ~(1 << 2); if(((data >> 1) & 1) ==1) PORTB |= (1 << 1); else PORTB &= ~(1 << 1); if(((data >> 0) & 1) ==1) PORTB |= (1 << 0); else PORTB &= ~(1 << 0); e_pin(); } void lcd(uint8_t cmd) {lcdSend(true, cmd);} void lcdChar(const char chr) {lcdSend(false, (uint8_t)chr);} void lcdString(const char* str) {while(*str != '\0') {del();lcdChar(*str);str++;}} void del(){delay(1);} void e_pin(){PORTB |= (1 << 4);del();PORTB &= ~(1 << 4);} void lcdCurs(byte str, byte mesto){ if(str==0){lcd(0b10000000+mesto);} if(str==1){lcd(0b11000000+mesto);} } void lcdInit(){ DDRB |= (1 << 0) | (1 << 1)| (1 << 2) | (1 << 3) | (1 << 4); DDRD |= (1 << 6); delay(100); lcd(0x03);delayMicroseconds(4500); lcd(0x03);delayMicroseconds(4500); lcd(0x03);delayMicroseconds(200); lcd(0b00000010);del(); lcd(0b00001100);del(); lcdClear(); } void lcdInt(long int_x){ byte h[8]; long int_y=int_x; int i,i_kol; if(int_x<0){int_x=abs(int_x);lcdChar('-');} // если минус for(i_kol=0;int_x>0;i_kol++){int_x=int_x/10;} // определяем кол-во цифр в long for(i=0;i<i_kol;i++){h[i]=int_y%10; int_y=int_y/10;}// разбиваем число на отдельные цифры for(i=i_kol-1;i>=0;i--){lcdChar(h[i] +'0');} // преобразуем числа в char if(i_kol==0){lcdChar('0');} // если long = 0, то выводить ноль } void lcdClear(){lcd(0b00000001);} void lcdFloat(float fr){ long int_f = fr*100, int_y=int_f; // умножаем float на 100, чтобы получить long и выделить два знака после запятой byte h[8]; int i,i_kol; if(int_f<0){int_f=abs(int_f);lcdChar('-');} // если минус for(i_kol=0;int_f>0;i_kol++){int_f=int_f/10;} // определяем кол-во цифр в long for(i=0;i<i_kol;i++){h[i]=int_y%10; int_y=int_y/10;}// разбиваем число на отдельные цифры for(i=i_kol-1;i>=0;i--){ // преобразуем числа в char if(i_kol==2&&i==1){lcdChar('0');lcdChar('.');} // если float = 0.XX if(i_kol==1){lcdChar('0');lcdChar('.');lcdChar('0');}// если float = 0.0X if(i==1&&i_kol>2){lcdChar('.');} lcdChar(h[i] +'0');}// если float > 0 if(i_kol==0){lcdChar('0');lcdChar('.');lcdChar('0');lcdChar('0');}// если float = 0, то выводить 0.00 } ISR(TIMER1_COMPA_vect){ i1++; if(i1 > 9){i1 = 0;ss++;} if(ss > 59){mm++;ss=0;} if(mm > 59){hh++;mm = 0;} if(hh > 23){hh = 0;} } ISR(INT0_vect){ TCCR1B &= ~(1 << CS12); TCCR1B &= ~ (1 << CS11); TCCR1B &= ~ (1 << CS10);stop=1; } ISR(INT1_vect){ TCCR1B |= (1 << CS11) | (1 << CS10);stop=0; }
Скетч использует 1690 байт (82%) памяти устройства. Всего доступно 2048 байт.
Глобальные переменные используют 24 байт (18%) динамической памяти, оставляя 104 байт для локальных переменных. Максимум: 128 байт.