Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 (изменено) · Жалоба Доброго времени суток! Прошу помощи. Занялся изучением мк. Попытался написать таймер обратного отсчета. Суть следующая написал исходник где переменные должны меняться по достижению определенного значения. Важный момент, таймер МК настроен на децесекунды, и итерации кнопкой проходят по 10 децесекунд, то есть +1 секунда Но когда таймер получает первую минуту, то при дальнейшей итерации - увеличение минут не происходит, а продолжается наращивание секунд, уверен что ошибся в написании функции. ПРошу помощи как лучше реализовать данную функцию. Видео поведения таймера прикладываю https://youtu.be/8j1sTrgwCcw Spoiler //------------------------------------------------------------------------------------------------------------------------- unsigned int d_min = 0, min = 0, d_sec = 0, sec = 0, dsec = 0, z = 0, desec = 0; // Создаю переменные для разрядов на дисплее (тысячи, сотни, десятки, еденицы) //------------------------------------------------------------------------------------------------------------------------- void chislo (unsigned int tiki) // Создаю функцию для дробления 5х значного числа на разряды { d_min = tiki/10000; // десятки минут min = tiki/1000; // минуты d_sec = tiki%1000/100; // сотни sec = tiki%100/10; // десятки dsec = tiki%10; // единицы if (dsec==10){sec++; dsec=0;} if (sec==10){d_sec++; sec=0;} if (d_sec==6){min++; d_sec=0;} if (min==10){d_min++; min=0;} } //------------------------------------------------------------------------------------------------------------------------- void timer1_ini(void) //настройка таймера счетчика первого { TCNT1 = 0; // обнуляем счетный регистр OCR1A = 3125; // Указываем число для сравнения в регистр сравнения TIMSK |= (1<<OCIE1A); // Включаем бит разрешения сравнения с OCR1A } //------------------------------------------------------------------------------------------------------------------------- void timer1_start(void) //Запуск первого таймера счетчика с предделителем на 256 и разрешением сравнения { TCCR1B |= (1<<WGM12)|(1<<CS12); } //------------------------------------------------------------------------------------------------------------------------- void timer1_stop(void) //Остановка первого таймера { TCCR1B &= ~((1<<WGM12)|(1<<CS12)); } //------------------------------------------------------------------------------------------------------------------------- ISR(TIMER1_COMPA_vect) // Создаю макрос тиканья таймера { if (--desec<=0) { desec = 0; PORTF |= (1<<4); TCCR1B &=~(1<<CS12); } } //------------------------------------------------------------------------------------------------------------------------- void button_on(void) // Активирую порты D и Е на выход, что бы использовать кнопки { DDRD = 0x00; PORTD |= (1<<6) | (1<<7); DDRE |= (0<<6) | (0<<7); PORTE |= (1<<6) | (1<<7); } //------------------------------------------------------------------------------------------------------------------------- void rele(void) // Активирую Порт F на выход, для того что бы активировать реле { DDRF |= (1<<4); PORTF = 0x00; } //------------------------------------------------------------------------------------------------------------------------- void displey_port(void) // Активирую Порт B на выход, для того что бы активировать реле { DDRB = 0xff; PORTB = 0x00; } //------------------------------------------------------------------------------------------------------------------------- int main(void) { timer1_ini(); timer1_start(); timer1_stop(); button_on(); rele(); displey_port(); sei(); // глобальные прерывания включены Lcd_init(); Lcd_clear(); Lcd_update(); LcdContrast(62); while (1) { chislo(desec); if (~PIND&(1<<6)) { desec+=10; if(desec>=66526) desec = 66526; _delay_ms(150); } if (~PIND&(1<<7)) { desec-=10; if(desec<=0) desec = 0; _delay_ms(150); } if (~PINE&(1<<6)) { timer1_start(); PORTB &= ~(1<<4); _delay_ms(150); } if (~PINE&(1<<7)) { timer1_stop(); PORTB |= (1<<4); _delay_ms(150); } Lcd_clear(); char buff[20]; itoa(d_min, buff, 10); Lcd_print(0, 1, FONT_2X,(unsigned char *)buff); itoa(min, buff, 10); Lcd_print(2, 1, FONT_2X,(unsigned char *)buff); Lcd_prints(4, 1, FONT_2X,(unsigned char *)PSTR(":")); itoa(d_sec, buff, 10); Lcd_print(6, 1, FONT_2X,(unsigned char *)buff); itoa(sec, buff, 10); Lcd_print(8, 1, FONT_2X,(unsigned char *)buff); Lcd_prints(10, 1, FONT_2X,(unsigned char *)PSTR(":")); itoa(dsec, buff, 10); Lcd_print(12, 1, FONT_2X,(unsigned char *)buff); Lcd_update(); } } Изменено 24 октября, 2023 пользователем haker_fox Отформатировал текст, спрятал длинный код в спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба Разрядность посмотрите для unsigned int if(desec>=66526) desec = 66526; if(desec<=0) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 3 минуты назад, codenamehawk сказал: Разрядность посмотрите для unsigned int if(desec>=66526) desec = 66526; if(desec<=0) Так он имеет от -32768 до 32767. но если сделать без знаковым, то должен вмещать 65534. Да и разрядность тут не причем. я не переполняю переменную. Я пишу о том что таймер не так отрабатывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 (изменено) · Жалоба 4 minutes ago, Devil Byte said: то должен вмещать 65534 Никогда не видел в конце 4. В вы сколько туда пытаетесь засунуть? 1 hour ago, Devil Byte said: d_min = tiki/10000; // десятки минут min = tiki/1000; // минуты d_sec = tiki%1000/100; // сотни sec = tiki%100/10; // десятки dsec = tiki%10; // единицы Этот ряд сбивается. Изменено 24 октября, 2023 пользователем codenamehawk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 1 минуту назад, codenamehawk сказал: В вы сколько туда пытаетесь засунуть? Этот ряд сбивается. Это ни как на софт не влияет, до исполнения этого if не дайдет. Не понял вашей фразы- ряд сбивается Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба Идиде снизу вврех, min выделяются как-то не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 5 минут назад, codenamehawk сказал: Идиде снизу вврех, min выделяются как-то не так. одна минута это 600 децесекунд... так? подскажите.. я уже голову третий день ломаю) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 (изменено) · Жалоба 28 minutes ago, codenamehawk said: min = tiki/1000; Вы не видите разницы, между тем как получаются sec, d_sec и min ? 17 minutes ago, Devil Byte said: одна минута это 600 децесекунд... так? Так, а теперь вы её делите на 1000, и что получите? Изменено 24 октября, 2023 пользователем codenamehawk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 11 минут назад, codenamehawk сказал: Вы не видите разницы, между тем как получаются sec, d_sec и min ? Так, а теперь вы её делите на 1000, и что получите? ну получу 0.6. Я же говорю яч использовал эту функкцию что бы дробить число для сигментного индикатора, но может стоить ее убрать и например мне конвертировать время исходя из того что в секунде 10 децесекунд, в минуте 60 секунд и так далее. просто я не понимаю как мне это написать и обрабатывать это сразу в переменных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба И еще я не увидел высчитывания минут, когда после 60 секунды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба Только что, codenamehawk сказал: И еще я не увидел высчитывания минут, когда после 60 секунды. я попытался решить эту проблему через иф if (dsec==10){sec++; dsec=0;} if (sec==10){d_sec++; sec=0;} if (d_sec==6){min++; d_sec=0;} if (min==10){d_min++; min=0;} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 1 minute ago, Devil Byte said: ну получу 0.6 Вы может и получите, считая калькулятором, а в проц не получит, вернее не сможет поместить её в uint Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 1 минуту назад, codenamehawk сказал: Вы может и получите, считая калькулятором, а в проц не получит, вернее не сможет поместить её в uint ну ок а как тогда ? создать переменную long int total? наращивать ее кнопкой по 10 А потом писать так \ int sec=total==10; int min=sec/60; а потом ээти переменные выводить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 24 октября, 2023 Опубликовано 24 октября, 2023 (изменено) · Жалоба Надо составить алгоритм перевода целого числа во время. 2 hours ago, Devil Byte said: dsec = tiki%10; // единицы if (dsec==10){sec++; dsec=0;} проверьте какое значение может быть в dsec и может ли сработать условие if Поставьте себе протеус с можете пошагово отлаживать программу. 17 minutes ago, Devil Byte said: А потом писать так \ int sec=total==10; int min=sec/60; а потом ээти переменные выводить? Похоже, если исправить ошибку и пересчитывать секунду больше 60 в минуты. В принципе все уже готово, поищите как считают и переводят в сек мин часы, время в линуксе. Изменено 24 октября, 2023 пользователем codenamehawk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Devil Byte 0 24 октября, 2023 Опубликовано 24 октября, 2023 · Жалоба 11 минут назад, codenamehawk сказал: Надо составить алгоритм перевода целого числа во время. проверьте какое значение может быть в dsec и может ли сработать условие if Поставьте себе протеус с можете пошагово отлаживать программу. Похоже, если исправить ошибку и пересчитывать секунду больше 60 в минуты. В принципе все уже готово, поищите как считают и переводят в сек мин часы, время в линуксе. почему линукс то? время считается от внутреннего счетчика таймера МК Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться