Секундомер на ATtiny2313 (Arduino IDE)

На базе 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 байт.

Добавить комментарий

Войти с помощью: