сообщение 11
Попробовал вывод в Serial засунуть в loop с секундной задержкой, если таймер 1 запущен валятся квадратики в одну строку, если закомментировать, то 123 как и должно
А если строчку 64 убрать?
Посмотрел выше - вы ж ее убирали уже и написали, что “помогло”.
Зачем обратно добавили?
У меня 64 это TIMSK |= (1 << OCIE1A); ее я не убирал она везде присутствует, я комментировал векторы прерываний, помогло в том смысле что импульсы были при любой частоте на трех лапках 3х таймеров, но я сразу не проверил, потом заметил, Serial порт при этом не читает, видимо портятся данные, не могу понять, может это помехи, не пойму куда копать
Я вам написал все прерывания на таймерах выключить. Закомментировать обработчик недостаточно.
Что-то мы по кругу ходим. Я же вроде все обьяснил уже?
Не тянет ваша Атмега 60 тыс прерываний в секунду. Точнее тянет, но на все остальное очень мало времени остается. А если какие процессы требуют точных таймингов, как например передача по Уарт - то они вообще перестают работать.
Смотрите - Процесс Сериал должен передавать биты с точными интервалами. А ваш таймер с частотой 60 КГц запускает свое прерывание и, НАТУРАЛЬНО, прерывает работу Сериал. А если часть битов в строчке “123\n” переданы с ошибкой - то и выйдут те самые квадратики, что вы наблюдаете в мониторе.
Я вас понял сейчас уберу, проверю
Странно убираю эту строку, по идее так как регистр TIMSK =0; соответственно ocie1a должен быть 0 и не должно быть прерывания, но если в векторе первого таймера прописываю мигание светодиодом то он мигает с большой частотой
Ну, это слишком категоричное высказывание.
По моему опыту “генерить сигнал” можно на AVR 16 МГц с частотой прерываний где-то до 110 кГц. Разумеется, никаких digitalWrite - только работой с портами.
Подтверждение:
сделал так TIMSK &= ~(1 << OCIE1A); //Отключение прерывания
Все заработало, спасибо большое за помощь, ошибку понял.
Возможно слегка перегнул, но направление то верное. И согласитесь, что 60кгц у ТС и 110кгц у вас - цифры по порядку довольно близкие.
Плюс выпадение бит в передаче UART очень характерный симптом, говорящий о проблемах с прерыванием.
Меня в этом обсуждении другой вопрос интересует.
Правильно ли я понимаю, что если бит прерывания включен, то даже если обработчик не определён или пустой - прерывание все равно происходит и на него тратятся ресурсы? Я там выше оговорился, что это только предположение…
Насколько помню, в ХАЛ стм32 это решается просто. Там обработчик прерывания есть всегда, даже если пользователь его не установил. При наличии пользовательской функции вызывается она, а если пользовательской нет - системная заглушка.
А в АВР как?
Хотя скорее всего так же. Если бит прерывания включен - должен быть обработчик, иначе будет ошибка исполнения.
Сейчас порт выдает и 700кГц и при этом Serial работает
Получается что в АВР расходуются ресурсы если прерывание включено
Это нормально. Если прерывание не нужно - не включайте его.
Флаг события устанавливается всегда, даже если прерывание запрещено. Ежели прерывание разрешено, но обработчик не задан кодом, то по-умолчанию происходит переход на вектор сброса.
в любом случае (что в avr ,что stm) бит случившигося прерывания должен быть очищен. и это должно происходить в пользовательском коде, а никак не само собой в железе
Нет. В авр флаг прерывания сбрасывается аппаратно при переходе на соотв.вектор.
Не знал.
А если функция обработки не проинициализирована?
Бит сбрасывается до перехода в пользовательский код и ничего не мешает случиться еще одному прерыванию до окончания отработки пользовательского кода?
@mixail844 при входе в прерывание все прерывания аппаратно запрещаются записью бита I регистра SREG. Внутри прерывания ничто не мешает этот бит включить обратно. Тогда можно из одного прерывания попасть в другой. У меня так проектик один и сделан: некоторые вещи крайне критичны, потому они происходят в нужный момент, даже если сейчас выполняется какое-либо другое прерывание.