Разбираюсь с работой таймера ATTiny13. Написал код, но работает не так, как задумывалось. Не могу понять - почему. Режим работы таймера CTC, но продолжительность импульсов на PB3 не изменяется при изменении начального значения OCR0A. Получается, что прерывание срабатывает не при достижении равенства значения счётчика и значения OCR0A, а при переполнении счётчика (т.е. счёт идёт постоянно до 255). Заход, в функцию обработки прерываний, происходит. Что-то не так написал в коде, или что-то не дописал? Помогите, пожалуйста, разобраться.
Код:
#include <avr/io.h> #include <avr/interrupt.h>
void setup() { TCCR0A = 0x10; // режим CTC TCCR0B = 0x01; //предделитель тактовой частоты CLK/1 TCNT0 = 0; // начальное значение счётчика OCR0A = 100; // начальное значение регистра совпадения A
DDRB |= (1 << PB3); // output на PB3 PORTB &= ~(1 << PB3); // низкий уровень на PB3
//устанавливаем бит разрешения прерывания 0-ого счетчика по совпадению с OCR0A TIMSK0 |= (1 << OCIE0A);
sei();// Разрешаем прерывания глобально }
byte a = 0;
ISR(TIM0_COMPA_vect) // обработка прерывания при совпадении счётчика с OCR0A {
if (a == 0) { PORTB |= (1 << PB3); // высокий на PB3 ++a; } else { PORTB &= ~(1 << PB3); // низкий на PB3 a = 0; } }
_________________ Платы для HLDI - установки лазерной засветки фоторезиста. ФоторезистыOrdyl Alpha 350 и AM 140. Жидкое олово для лужения плат (видео) - самое лучшее и только у меня. Паяльная маска XV501T-4 и KSM-S6189 (5 цветов). Заказ печатных плат - pcbsmac@gmail.com
Вопрос снимается. Нашёл ошибку в коде: значение режима задал не в тех единицах. Нужно было или 2 (в десятичной), или 0b10 (в двоичной), или 0x02 (в шестнадцатиричной), или так: TCCR0A |= (2 << WGM00); То есть, в коде я выставил режим просто счётчика. Непонятно только: почему этот обработчик прерывания срабатывал?
Последний раз редактировалось alsav22 Чт дек 04, 2025 17:25:34, всего редактировалось 1 раз.
На выводе РВ3 светодиод. При старте значение регистра OCR0A = 200. При замыкании вывода РВ4 на GND, в данный регистр запишется значение 100. По миганию светодиода это хорошо будет видно.
alsav22 Гибрид ардуино - стиля (возможно и самой ардуиноIDE) и Си??? Так в варианте ардуинки второй генератор таймерной сетки на Т0 совсем иначе делается.
Я не понимаю Си, но в каком месте вы изменяете значение регистра OCR0A?
А зачем мне его изменять (при работе кода я его не меняю, менял в тексте,перед сборкой)?.Цели такой не было. Просто разбирался с регистрами таймера: куда, что, и как нужно прописывать. Результат работы смотрел логическим анализатором на пине вывода.
alsav22 Гибрид ардуино - стиля (возможно и самой ардуиноIDE) и Си??? Так в варианте ардуинки второй генератор таймерной сетки на Т0 совсем иначе делается.
Ардуинка, насколько понял, свои настройки таймера автоматом может прописывать (например, при вызове analogWrite()). Долго не мог понять: делаю настройки таймера, потом использую analogWrite(), мои настройки не работают. А с таким синтаксисом всё видно. В общем, разбираюсь (как могу).
TCCR0A = 0x10; // режим CTC TCCR0B = 0x01; //предделитель тактовой частоты CLK/1 TCNT0 = 0; // начальное значение счётчика OCR0A = 100; // начальное значение регистра совпадения A
Сделал бы (в мнемокодах) TCCR0B <- 0 //стоп таймера TCNT0 <- 0 // начальное значение счётчика TCCR0A <- 1<<WGM01 // режим CTC OCR0A <- 100 // начальное значение регистра совпадения A
TIMSK0 <- 1 << OCIE0A TIFR0 <- 1 << OCF0A TCCR0B <- 1<<CS00 //старт с тактовой частотой CLK/1 SEI
... Ардуинка, насколько понял, свои настройки таймера автоматом может прописывать (например, при вызове analogWrite()). Долго не мог понять: делаю настройки таймера, потом использую analogWrite(), мои настройки не работают. А с таким синтаксисом всё видно. В общем, разбираюсь (как могу).
Ежли работаете с ардуино - извольте соблюдать правила "референса". Надо хоть немножко понимания иметь о том, что автоматически добавляется к каждому "СКОТчу" в качестве "системных функций" самой средой по умолчанию. Иначе будет достаточно много всякого рода "непонятных ошибок". Таймер Т0 используется в адуринках на АВРках в качестве "генератора системных часов" - по факту 1 миллисекундного интервала. Можно и свой добавочный генератор добавить (для "параллельного процесса" на основе прерывания по OCR0A, но то прерывание также будет с интервалом 1 миллисекунда, единственно смещено относительно основного (обычно ставится 0х127). А уже на его основе строятся свои программные счетчики. Насчет работ с адуриньями рекомендую посмотреть раскиданные по viewtopic.php?f=62&t=156720 заметки и раздел "уроков" у Гайвера: https://alexgyver.ru/
Для того, чтобы совсем "влияния не оказывалось" надо программу писать "за пределами ардуиноIDE" - в любой другой IDE. Максимум что можно "нейтрализовать" изменяя основную страничку исходника - это убрать работу уарт (и то там проще делается). Да и зачем? Неуж то "в рамках референса" средств недостаточно? Собственно вариант окна симулятора к примеру: Спойлер зачем еще раз то же самое дублировать?
Прерывание не будет правильно подключено и будет казаться, что таймер срабатывает только при переполнении
---
не TCCR0A = 0x10; // режим CTC - ето бит COM0B0, а не бит WGM01 а TCCR0A = (1 << WGM01); // режим CTC
Поскольку режим CTC включен неправильно, таймер работает в Normal Mode. В Normal Mode прерывание OCR0A не возникает, но прерывание по переполнению может быть вызвано.
Последний раз редактировалось veso74 Пт дек 05, 2025 11:14:42, всего редактировалось 2 раз(а).
Пока что не совсем понятно с какой средой разработки топикстартер дело имеет. Он же не объявлял, что под ардуино IDE работает. Да и в самой IDE платформ с Тинькой 13ой минимум 2 - их ещё и устанавливать дополнительно надо (в списке "по умолчанию" их нет- надо вручную добавлять). Может топикстартер пытается копировать "стиль ардуино" в АВРстудио (микрочип студио)... Так что подождем уточнений... OKF, ну не "матрешки" же делать - вкладывать повторно то же самое в то же самое. Обычно достаточно от loop избавиться. И то лишь для гурманов (изврата). Да и авр студии никто не отменял...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 32
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения