Загадка про таймеры
- Войдите на сайт для отправки комментариев
Ср, 07/09/2022 - 13:03
Доброго всем!
Решал простую задачу - мигать светодиодом. Временем свечения управляет первый таймер, временем потухлости - второй.
Так вот, при старте пару раз (два раза, если быть точнее) мигает правильно - меньше секунды смена состояния, а потом время свечения продлевается до четырёх секунд примерно. Как будто первый таймер отринул настройки и стал игнорировать OCR1A = 3000;
Что такое происходит через два такта мигания - у меня фантазия всё. Может, просветит кто?
Вот код:
uint8_t pin = 13; volatile uint16_t state = 50, count = 1; void setup() { //Timer2. Constant period cli(); TCCR2A = 0; TCCR2B = 0; TCNT2 = 0; TCCR2A |= (1 << WGM21); TCCR2B |= (1 << CS20); TCCR2B |= (1 << CS21); TCCR2B |= (1 << CS22); TIMSK2 |= (1 << OCIE2A); OCR2A = 220; //Timer1. For shift TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B |= (1 << WGM12); TIMSK1 |= (1 << OCIE1A); OCR1A = 3000; //for change sei(); pinMode(pin, OUTPUT); } void loop(){ } ISR(TIMER2_COMPA_vect){ if(count < state){ count++; }else{ //cli(); digitalWrite(pin, HIGH); TCCR2B &= (0 << CS20)&(0 << CS21)&(0 << CS22); TCCR1B |= (1 << CS10)|(1 << CS12); //OCR1A = 3000; count = 1; //sei(); } } ISR(TIMER1_COMPA_vect){ //cli(); digitalWrite(pin, LOW); TCCR1B &= (0 << CS10)&(0 << CS11)&(0 << CS12); TCCR2B |= (1 << CS20)|(1 << CS21)|(1 << CS22); //sei(); }
ОТГАДКА - А где сброс самих счетчиков ??? После 3000 он идёт до 65536 и потом снова до 3000
Вот эта строчка:
Разве не подразумевается, что счётчик сбрасывается в ноль, достигая этого числа:
?
TCCR1B &= (0 << CS10)&(0 << CS11)&(0 << CS12);
равносильно
TCCR1B = 0;
Да, но не наглядно. Обычно:
TCCR1B = 0<<CS10 | 0<<CS11 | 0<<CS12;
а не фиг знамо что.
В TCCR1B есть и другие полезные биты, которые не надо трогать на этом действии
Да что вы говорите! Так сделайте по другому. Сбросьте одни, добавьте другие.
В TCCR1B есть и другие полезные биты, которые не надо трогать на этом действии
Так нахрена же Вы их все до единого в ноль сбросили?
Вам же уже сказали:
TCCR1B &= (0 << CS10)&(0 << CS11)&(0 << CS12);
равносильно
TCCR1B = 0;
Вы этого не прочитали?
Вы тупо прописываете весь регистр нулями, а потом чего-то хоите.
В TCCR1B есть и другие полезные биты, которые не надо трогать на этом действии
Так нахрена же Вы их все до единого в ноль сбросили?
Вам же уже сказали:
TCCR1B &= (0 << CS10)&(0 << CS11)&(0 << CS12);
равносильно
TCCR1B = 0;
Вы этого не прочитали?
Вы тупо прописываете весь регистр нулями, а потом чего-то хоите.
Не равносильно. Обращу Ваше внимание, что регистр TCCR1B, как минимум, восемь бит. А я только три обнуляю, остальные не трогаю.
Да что вы говорите! Так сделайте по другому. Сбросьте одни, добавьте другие.
Я так и делаю. Разве нет?
Не равносильно. Обращу Ваше внимание, что регистр TCCR1B, как минимум, восемь бит. А я только три обнуляю, остальные не трогаю.
да, ну выведи в ком порт чему равно
Не равносильно. Обращу Ваше внимание, что регистр TCCR1B, как минимум, восемь бит. А я только три обнуляю, остальные не трогаю.
че седня такое.... вспышка на Солнце? одни дебилы...
Ваша строка
равнозначная вот этой
еще будут возражения на тему "в регистре 8 бит" ?
че седня такое.... вспышка на Солнце? одни дебилы...
причем с датой регистрации - не вчера.
а то что вы хотите, делается так:
видите разницу?
Не равносильно. Обращу Ваше внимание, что регистр TCCR1B, как минимум, восемь бит. А я только три обнуляю, остальные не трогаю.
да, ну выведи в ком порт чему равно
Понял, проникся! Всем спасибо! Обещаю исправиться
а то что вы хотите, делается так:
видите разницу?
Да, спасибо. Что-то разогнался быстрее головы.
Ну вот когда понимает, тогда и приятно с человеком разговаривать. А не как с дебилом каким то!
Если понимаешь свои ошибки, анализируешь, то всё у тебя получится.