Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.16.147.124] |
|
Сообщ.
#1
,
|
|
|
Всем здравствуйте!
Возник такой вопрос : как реализовать 2 независимых друг от друга таймера(которые бы выводились на экран в первые 2 строки на дисплее 16х4). а при поступлении команды время засекалось, и выводилось с 1 таймера-3 строка, со 2 таймера- 4 строка. Вот то что я смог наваять со вчерашнего вечера. // 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 одинаковых синхронных таймера, но обнуляются оба сразу.А этого не надо |
Сообщ.
#2
,
|
|
|
shut
В чём конкретно трудности? Вам понадобиться 2 переменные. В которых запоминаете время от которого отсчитывает счётчик. start1, start2 И две константы или переменные для сравнения. period1,period2 И один счётчик тиков. tickcount if (tickcount-start1>period1) { ... start1=tickcount; } if (tickcount-start2>period2) { ... start1=tickcount; } Микроконтроллёры работают последовательно. Поэтому для независимости не получиться. Надо псевдо параллельно делать. Поищи в гугле по словам "РТОС для микроконтроолеров" или "плонировщик процессов на микроконтроллёре" |
Сообщ.
#3
,
|
|
|
Цитата Pavia @ Не умничай. Всё проще - у ТС два таймера с разными векторами прерывания. Микроконтроллёры работают последовательно. Поэтому для независимости не получиться. Надо псевдо параллельно делать. Поищи в гугле по словам "РТОС для микроконтроолеров" или "плонировщик процессов на микроконтроллёре" shut, копипаста тебя погубит. Смотри в функции read_microseconds2 - из какого счетчика считываешь значение. Остальное не смотрел, но осуждаю. |
Сообщ.
#4
,
|
|
|
Копипаста - согласен. Но я не программист вообще(только начал). А сделать надо для клуба единомышленников, товарищи ждут.
|
Сообщ.
#5
,
|
|
|
А может кто поможет за денежку? надо очень!
|
Сообщ.
#6
,
|
|
|
Та тут и даром начать да кончить. Неинтересно.
Но раз уж такая пьянка... |
Сообщ.
#7
,
|
|
|
Цитата Qraizer @ Та тут и даром начать да кончить. Неинтересно. Но раз уж такая пьянка... Согласен. Но иногда приходится заниматься тем, в чем не понимаешь. а времени разобраться нет. надо через 2-3 дня. |