На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > система хронометража , Поделка на Ардуино
      Всем здравствуйте!
      Возник такой вопрос : как реализовать 2 независимых друг от друга таймера(которые бы выводились на экран в первые 2 строки на дисплее 16х4). а при поступлении команды время засекалось, и выводилось с 1 таймера-3 строка, со 2 таймера- 4 строка.
      Вот то что я смог наваять со вчерашнего вечера.
      ExpandedWrap disabled
        // Variables definition
        uint16_t microseconds = 0, milliseconds = 0;
        uint8_t seconds = 0, minutes = 0, hours = 0;
        uint16_t microseconds2 = 0, milliseconds2 = 0;
        uint8_t seconds2 = 0, minutes2 = 0, hours2 = 0;
        #include <LiquidCrystal.h>
         
        // Interrupt service routines
        ISR(TIMER1_COMPA_vect)  // Timer-1 OC1A Match interrupt handler
        {
          milliseconds += 100;
          if (milliseconds == 1000)
          {
            milliseconds = 0;
            seconds++;
          }
          if (seconds == 60)
          {
            seconds = 0;
            minutes++;
          }
          if (minutes == 60)
          {
            minutes = 0;
            hours++;
          }
        }
        ISR(TIMER2_COMPA_vect)  // Timer-2 OC1A Match interrupt handler
        {
          milliseconds2 += 100;
          if (milliseconds2 == 1000)
          {
            milliseconds2 = 0;
            seconds2++;
          }
          if (seconds2 == 60)
          {
            seconds2 = 0;
            minutes2++;
          }
          if (minutes2 == 60)
          {
            minutes2 = 0;
            hours2++;
          }
        }
         
         
        LiquidCrystal lcd(4, 5, 10, 11, 12, 13);
        // Reset chronometer
        void reset_chrono(void)
        {
          unsigned char sreg;
          sreg = SREG;  // Save global interrupts flag
          cli();  // Disable interrupts
          TCNT1 = 0;  // Reset timer-1 counter
          SREG = sreg;  // Restore global interrupts flag
          milliseconds = 0;
          seconds = 0;
          minutes = 0;
          hours = 0;
        }
        void reset_chrono2(void)
        {
          unsigned char sreg2;
          sreg2 = SREG;  // Save global interrupts flag
          cli();  // Disable interrupts
          TCNT2 = 0;  // Reset timer-1 counter
          SREG = sreg2;  // Restore global interrupts flag
          milliseconds2 = 0;
          seconds2 = 0;
          minutes2 = 0;
          hours2 = 0;
        }
         
        // Read microseconds counter
        uint32_t read_microseconds(void)
        {
          uint32_t microseconds;
          unsigned char sreg;
          sreg = SREG;  // Save global interrupts flag
          cli();  // Disable interrupts
          microseconds = TCNT1*4;  // one timer-1 count for 4us
          SREG = sreg;  // Restore global interrupts flag
          return microseconds;
        }
        uint32_t read_microseconds2(void)
        {
          uint32_t microseconds2;
          unsigned char sreg2;
          sreg2 = SREG;  // Save global interrupts flag
          cli();  // Disable interrupts
          microseconds2 = TCNT1*4;  // one timer-2 count for 4us
          SREG = sreg2;  // Restore global interrupts flag
          return microseconds2;
        }
         
        // Setup
        void setup(void)
         
        {
          Serial.begin(9600);  // Open serial port with 9600bps
          lcd.begin(16, 2);
          pinMode(8, OUTPUT);
          pinMode(9, OUTPUT);
          pinMode(7, OUTPUT);
          
          
          // Set timer-1 parameters
          TCCR1A = 1<<WGM10 | 1<<WGM11; // Fast PWM mode enabled with 16bits registers
          TCCR1B = 1<<CS10 | 1<<CS11 | 1<<WGM12 | 1<<WGM13;  // Fixe clock for timer1 F_CPU=16MHz/64 (prescaler)
          OCR1A = 24999;  // Set the top limit counter to 24999
          TIMSK1 = 1<<OCIE1A;  // Enable interrupt on 0C1A match
          sei();  // Enable interrupt
          // Set timer-1 parameters
          TCCR2A = 1<<WGM10 | 1<<WGM11; // Fast PWM mode enabled with 16bits registers
          TCCR2B = 1<<CS10 | 1<<CS11 | 1<<WGM12 | 1<<WGM13;  // Fixe clock for timer1 F_CPU=16MHz/64 (prescaler)
          OCR2A = 24999;  // Set the top limit counter to 24999
          TIMSK2 = 1<<OCIE1A;  // Enable interrupt on 0C1A match
          sei();  // Enable interrupt
            
        }
         
        // Main loop
        void loop(void)
         
        {
            char char_readed = 0;
          char_readed = Serial.read();  // Read serial port character
         
          if (char_readed == 0x31)  // Type "1" to reset chronometer
          {
            reset_chrono();
            lcd.setCursor(0,2);
            lcd.print("Reset1timer       ");
            digitalWrite(8, HIGH);   // set the LED on
            delay(1000);              // wait for a second
            digitalWrite(8, LOW);
            delay(1000);
            lcd.clear();
         
          }
          if (char_readed == 0x35)  // Type "5" to reset chronometer2
          {
            reset_chrono2();
            lcd.setCursor(0,4);
            lcd.print("Reset2timer       ");
            digitalWrite(8, HIGH);   // set the LED on
            delay(1000);              // wait for a second
            digitalWrite(8, LOW);
            delay(1000);
            lcd.clear();
         
          }
         
          uint32_t microseconds_count = 0;
          uint16_t milliseconds_display = 0, microseconds_display = 0, milliseconds_rest = 0;
          microseconds_count = read_microseconds();
          milliseconds_rest = (uint16_t)(microseconds_count/1000);  // Take the two most important digits (decimal value) of microseconds counter
          milliseconds_display = milliseconds + milliseconds_rest;  // Add rest to milliseconds hundred
          microseconds_display = (uint16_t)(microseconds_count-(uint32_t)(milliseconds_rest*1000));  // Conserve microseconds
          lcd.setCursor(0,0);
          lcd.print("Time: ");
          lcd.print(minutes, DEC);
          lcd.print("m ");
          lcd.print(seconds, DEC);
          lcd.print("s ");
          lcd.print(milliseconds_display, DEC);
          lcd.print("ms ");
         
          uint32_t microseconds_count2 = 0;
          uint16_t milliseconds_display2 = 0, microseconds_display2 = 0, milliseconds_rest2 = 0;
          microseconds_count2 = read_microseconds2();
          milliseconds_rest2 = (uint16_t)(microseconds_count2/1000);  // Take the two most important digits (decimal value) of microseconds counter
          milliseconds_display2 = milliseconds2 + milliseconds_rest2;  // Add rest to milliseconds hundred
          microseconds_display2 = (uint16_t)(microseconds_count2-(uint32_t)(milliseconds_rest2*1000));  // Conserve microseconds
          lcd.setCursor(0,3);
          lcd.print("Time: ");
          lcd.print(minutes, DEC);
          lcd.print("m ");
          lcd.print(seconds, DEC);
          lcd.print("s ");
          lcd.print(milliseconds_display, DEC);
          lcd.print("ms ");
         
          if (char_readed == 0x32)  // Type "2" to print chronometer time
          {
            uint32_t microseconds_count = 0;
            uint16_t milliseconds_display = 0, microseconds_display = 0, milliseconds_rest = 0;
            microseconds_count = read_microseconds();
            milliseconds_rest = (uint16_t)(microseconds_count/1000);  // Take the two most important digits (decimal value) of microseconds counter
            milliseconds_display = milliseconds + milliseconds_rest;  // Add rest to milliseconds hundred
            microseconds_display = (uint16_t)(microseconds_count-(uint32_t)(milliseconds_rest*1000));  // Conserve microseconds
            lcd.setCursor(0,1);
            lcd.print("TimeF1:");
            lcd.print(minutes, DEC);
            lcd.print("m ");
            lcd.print(seconds, DEC);
            lcd.print("s ");
            lcd.print(milliseconds_display, DEC);
            lcd.print("ms ");
            digitalWrite(9, HIGH);   // set the LED on
            delay(1000);              // wait for a second
            digitalWrite(9, LOW);
          }
           if (char_readed == 0x33)  // Type "3" to print chronometer time
          {
           uint32_t microseconds_count2 = 0;
           uint16_t milliseconds_display2 = 0, microseconds_display2 = 0, milliseconds_rest2 = 0;
           microseconds_count2 = read_microseconds2();
           milliseconds_rest2 = (uint16_t)(microseconds_count2/1000);  // Take the two most important digits (decimal value) of microseconds counter
           milliseconds_display2 = milliseconds2 + milliseconds_rest2;  // Add rest to milliseconds hundred
           microseconds_display2 = (uint16_t)(microseconds_count2-(uint32_t)(milliseconds_rest2*1000));  // Conserve microseconds
            lcd.setCursor(0,2);
            lcd.print("TimeF2:");
            lcd.print(minutes, DEC);
            lcd.print("m ");
            lcd.print(seconds, DEC);
            lcd.print("s ");
            lcd.print(milliseconds_display, DEC);
            lcd.print("ms ");
            digitalWrite(9, HIGH);   // set the LED on
            delay(1000);              // wait for a second
            digitalWrite(9, LOW);
          }
          
        }


      Непонятно, как сделать чтоб 2 таймера работали независимо друг от друга.
      P.S. Программист из меня никакой, вы уж простите.

      В итоге получаются 2 одинаковых синхронных таймера, но обнуляются оба сразу.А этого не надо
      Сообщение отредактировано: shut -
        shut
        В чём конкретно трудности?

        Вам понадобиться 2 переменные.
        В которых запоминаете время от которого отсчитывает счётчик.
        start1, start2
        И две константы или переменные для сравнения.
        period1,period2
        И один счётчик тиков.
        tickcount

        ExpandedWrap disabled
          if (tickcount-start1>period1)
            {
            ...
            start1=tickcount;
            }
          if (tickcount-start2>period2)
            {
            ...
            start1=tickcount;
            }


        Микроконтроллёры работают последовательно. Поэтому для независимости не получиться. Надо псевдо параллельно делать.
        Поищи в гугле по словам "РТОС для микроконтроолеров" или "плонировщик процессов на микроконтроллёре"
          Цитата Pavia @
          Микроконтроллёры работают последовательно. Поэтому для независимости не получиться. Надо псевдо параллельно делать.
          Поищи в гугле по словам "РТОС для микроконтроолеров" или "плонировщик процессов на микроконтроллёре"
          Не умничай. :) Всё проще - у ТС два таймера с разными векторами прерывания.
          shut, копипаста тебя погубит. Смотри в функции read_microseconds2 - из какого счетчика считываешь значение. Остальное не смотрел, но осуждаю.
            Копипаста - согласен. Но я не программист вообще(только начал). А сделать надо для клуба единомышленников, товарищи ждут.
              А может кто поможет за денежку? надо очень!
                Та тут и даром начать да кончить. Неинтересно.
                Но раз уж такая пьянка...
                  Цитата Qraizer @
                  Та тут и даром начать да кончить. Неинтересно.
                  Но раз уж такая пьянка...


                  Согласен. Но иногда приходится заниматься тем, в чем не понимаешь. а времени разобраться нет. надо через 2-3 дня.
                  Сообщение отредактировано: shut -
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0330 ]   [ 17 queries used ]   [ Generated: 3.05.24, 00:29 GMT ]