Прерывания по таймеру
- Войдите на сайт для отправки комментариев
Ср, 24/10/2012 - 20:38
Прошу помощи в пояснении по принципу работы с таймерами. Искал долго и много но так ответы на вопросы и не были найдены.
Пример кода из интернета
volatile unsigned int tcnt2; void setup() { TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора tcnt2 = 1; // 16000000/64/f=tcnt2 TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2. } void loop() { } void MyInterupt() { //обработчик вашего прерывания } //****************обработчик прерывания******************** ISR(TIMER2_OVF_vect) { TCNT2 = tcnt2; MyInterupt(); }
Я его немного переделал чтобы визуально всё было понятно.
int led = 13; volatile unsigned int tcnt2; volatile int count = 0; void setup() { //Serial.begin(9600); TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора tcnt2 = 25000; // 16000000/64/f=tcnt2 TIMSK2 |= (1<<TOIE2); pinMode(led, OUTPUT); } boolean t=0; void loop() { } void MyInterupt() { digitalWrite(led, t); t=!t; //Serial.println("000"); } ISR(TIMER2_OVF_vect) { TCNT2 = tcnt2; MyInterupt(); }
В интернете я нашёл таблицу в которой написаны все прерывания для arduino. Но приведённый пример я так и не смог разобрать. Мне в нём непонятно ВСЁ. Весь setup включая знаки & | ~ (в конкретном случае), TIMSK2, TCCR2A, WGM22, ASSR и прочее. Откуда всё это берётся?
Основной смысл: сделать блинк на прерываниях по таймеру.
Библиотеки не предлагать!
Также мне интересно как сделать прерывания по зависанию мк? Название прерывания из таблицы WDT_vect
про символы & | ~ читать про битовые операции переведите или поищите "битовые операции на с" - должно мнего найтись. Вообще, поизучать с будет полезно (хотя бы основы, к коим и относятся битовые операции)
TIMSK2, TCCR2A, WGM22 - это регистры управления процессора, связанные с таймерами. Они объявлены в общем хедере для процессора, так что ненужно их искать. Прежде чем работать с таймерами, почитайте про них в статьях или даташите
Про прерывание по зависанию, ищите про ватчдог.
Про символы я разобрался.
НО всё остальное просто жесть какая-то. Прочитал статью. Понял на 50% хотя и то не уверен.
Нашёл сборник статей на эту тему. Но они не очень хорошо написаны.(((
Читайте как можно больше, чтобы работать с таймерами, нужно понимать, как они работают. Легче всего понять, если Вы разбираетесь в схемах и немножко читаете по аглицки, потому что о принципе работы, на самом деле, даташит дает исчерпывающую информацию, но трудноусваимую.
Не знаю, что входит в 50%, которые Вы не поняли, но поясню по программе:
&= ~(1<<TOIE2) - сброс бита номер TOIE2. Берется "1", сдвигается влево на 6-ю позицию (TOIE2=6), получается 0b01000000, инвертируется операцией "~", получается 0b10111111, производится логическое умножение (операция И), результат кладется обратно. Таким образом "0" попадает в нужный бит регистра. Если не инвертировать и применить операцию битового сложения (ИЛИ), то в нужное место попадет единичка.
В общем случае, то, что в скобках, зовется маской, ее накладывают на регистр через "&", если нужно сбросить биты там, где у маски "0", или через "|", чтобы установить биты там, где у маски "1".
Все это можно делать и через функции bitSet() и bitClear(), но будет медленнее и "неуниверсально"
Я …. Что то вообще ничего не понял(((
По статьям:
Чтобы установить бит в регистре в значение 1, не изменяя значения других битов, используется команда вида:
регистр |= (1 << номер_бита);
А чтобы установить бит в регистре в значение 0, так же не изменяя значения других битов, ис-пользуется команда вида:
регистр &= ~ (1 << номер_бита);
Следовательно давайте разберём первую строчку. TIMSK2 &= ~(1<<TOIE2);
По статьям:
TIMSK - регистр маски прерываний таймеров/счетчиков
Бит 7 - OCIE2: прерывание по совпадению ТС2
Бит 6 - TOIE2: прерывание по переполнению ТС2
Бит 5 - TICIE1: прерывание по захвату ТС1
Бит 4 - OCIE1A: прерывание по совпадению A ТС1
Бит 3 - OCIE1B: прерывание по совпадению В ТС1
Бит 2 - TOIE1: прерывание по переполнению ТС1
Бит 1 - не используется
Бит 0 - TOIE0: прерывание по переполнению ТС0
Если соответствующий бит установлен в "1" и бит I (7-й бит) регистра состояний SREG установлен в "1", тогда соответствующее прерывание будет срабатывать.
В этом месте уже непонятно. Как я это вижу:
При старте мк в регистрах TIMSK записано 0b00000000 (так ли я это понимаю?)(то есть нули и всё прерывания выключены) или всё наоборот ?
Ок ступил. Всё логично получается с единицами. Только я не понял раз стоит 0 то значит прерывание включено а если 1 то выключено?
По статьям:
TIMSK - регистр маски прерываний таймеров/счетчиков
Бит 7 - OCIE2: прерывание по совпадению ТС2
Бит 6 - TOIE2: прерывание по переполнению ТС2
Бит 5 - TICIE1: прерывание по захвату ТС1
Бит 4 - OCIE1A: прерывание по совпадению A ТС1
Бит 3 - OCIE1B: прерывание по совпадению В ТС1
Бит 2 - TOIE1: прерывание по переполнению ТС1
Бит 1 - не используется
Бит 0 - TOIE0: прерывание по переполнению ТС0
Не можете ли указать источник столь полезной информации.
По моим сведениям (да и Atmel так считает - см. даташит) в микроконтроллерах ATMega48/88/168/328 существует аж 3 регистра, занимающихся маскированием - соответственно TIMSK0, TIMSK1, TIMSK2 (страницы 111, 139 и 163 "большого" даташита). И у этих регистров только младшие биты имеют значение (3, 4 и 3 бита соответственно). А у вас - целый байт...
Только я не понял раз стоит 0 то значит прерывание включено а если 1 то выключено?
Еще раз - даташит на соответствующий контроллер является истиной в последней инстанции. Там все предельно ясно сказано. Например, бит 2 регистра TIMSK0:
"Bit 2 – OCIE0B: Timer/Counter Output Compare Match B Interrupt Enable
When the OCIE0B bit is written to one, and the I-bit in the Status Register is set, the
Timer/Counter Compare Match B interrupt is enabled. The corresponding interrupt is executed if
a Compare Match in Timer/Counter occurs, i.e., when the OCF0B bit is set in the Timer/Counter
Interrupt Flag Register – TIFR0."
Ок ступил. Всё логично получается с единицами. Только я не понял раз стоит 0 то значит прерывание включено а если 1 то выключено?
Если "1" - то включено, если "0" - то выключено.
У Вас в первом скетче просто ошибка в комментарии, первая строчка ЗАПРЕЩАЕТ прерывание, там все сделано правильно:
Делается так для того, чтобы во время настройки таймера у нас прерывание не сработало случайно.
Дело всё в том что скетч из примера вообще не работает! один раз только срабатывает прерывание!
Хотел написать сам как в статьях всё равно не работает!
В строке 11 скетча вы присваиваете регистру TIMSK2 значение 64. Другими словами, устанавливаете бит 6.
Если открыть даташит на микроконтроллер и посмотреть, что же там пишется об этом регистре, то можно уяснить, что смысл имеет лишь установка трех младших битов:
Это так - в качестве примера достоверности тех данных, которыми вы пытаетесь пользоваться. Неудивительно, что ваше прерывание сыплется.
UPD1: Далее, в процедуре обработки прерывания вы вызываете функцию, которая слишком тяжела для обработки в прерываниях: в ней вызывается не слишком быстрая функция digitalWrite(), а также Serial.print, которой для вывода 3 символов (да плюс еще CR+LF) потребуется около 5 миллисекунд. Сколько раз за это время произойдет очередное переполнение вашего таймера? 40? или 50? (таймер "щелкает" с частотой 500 кГц в диапазоне 150-255, т.е. переполняется где-то 5 раз в миллисекунду).
UPD2: Упс, у вас выбран режим 0 - нормальный режим счета. В этом режиме счетчик считает от 0 до 255. Величина в TCNT2 значения не имеет. Стало быть счет в диапазоне 0-255 и переполнение "всего" 2 раза в миллисекунду.
Скачал даташит. На 12 главе описываются прерывания по таймеру. Подобного рисунка с надписью TIMSK2 замечено не было. Я не знаю английского языка поэтому в даташит и не лазаю. Пробовал перевести переводчиком. Полная чушь!
(да плюс еще CR+LF)-что это такое?
Мне кажется надо как то систематизировать данные по даташиту. Ибо возможно мы говорим об одном и том же, а я ничего понять не могу. Также мне не понятно как высчитывать секунды или полсекунды.
Используя пример из интернета вот что получилось.
Мне не понятно как настроить и вычислить такты. То есть как рассчитать так чтобы прерывание срабатывало скажем каждую секунду.
И мне не всё понятно с регистром маски прерываний так как в строчке TIMSK2 |= (1 << TOIE2); мы чётко ставим 1 в бит 6! А если записать как 64 то ничего не работает.
Также не ясно. Какие режимы может принимать регистр управления В. (выбор тактирования таймера)
PS пример который я привёл получился методом тыка!!! Мне стыдно что так и не смог разобраться((((
(да плюс еще CR+LF)-что это такое?
CR (Carriage Return - возврат каретки) и LF (Line Feed - перевод строки) - те символы, которые добавляются к пересылаемой строке в случае использования функции Serial.println().
И мне не всё понятно с регистром маски прерываний так как в строчке TIMSK2 |= (1 << TOIE2); мы чётко ставим 1 в бит 6! А если записать как 64 то ничего не работает.
А с чего вы взяли, что TOIE2 равен 6? А не, скажем, 0?
Попробуйте в скетче вывести его значение на экран:
Serial.println(TOIE2,DEC);
Скачал даташит. На 12 главе описываются прерывания по таймеру.
"Preliminary"? Но и там в 12 главе описывается таймер/счетчик0, а второй - соответственно - в 15-й.
[quote]
Я не знаю английского языка поэтому в даташит и не лазаю
[/quite]
Ну, тогда вам остается мигать диодом с помощью delay().
Если уж совсем никак, найдите книжку Евстифеева. Практически даташит, только переведенный на русский язык, ну и урезанный мало-мало.
Всё разобрался (вроде как). Смотрел какой-то левый даташит + не дошёл до раздела который нужно было использовать. Спасибо!
Замечу, что Serial.print использовать в прерываниях нерекомендуется. Если все же очень надо, советую почитать статью о неблокирующем Serial
Ок спасибо. Статья интересная. Но я не буду применять печать в прерываниях.
Я так понял что мало кто разбирается на тему прерываний и настройки таймеров.
Сейчас ищу про WATCHDOG. К сожалению описания на русском нет. Также удалось выяснить, что для нормальной работы необходимо перепрошить бутлогер. Конечно всё бы решил даташит! Но я пока не нашёл переводчика))) а гугл сами знаете что выдаёт.
По сторожевому таймеру уже было на форуме. Что гугль выдает - не знаю, потому что в свое время зарекся переводить технические тексты компьютерными переводчиками (это было после фразы "ОСТРЫЙ не несет ответственности при ношении устройства в запасных карманах Вашего времени")
Найдите "Англо-русский словарь по программированию" (как-то видел в продаже в книжном магазине и обратил на него внимание) и переводите потихоньку по-старинке - заодно и язык выучите, пригодится. Я в свое время выучил читая хелп для с++.
LEVV2006
Если у вас остались какие-нибудь конкретные вопросы по таймерам, то я с радостью попытаюсь на них ответить (не так давно пришлось разбиратся в этой теме :) )
А у меня мечта... с таймерами в STM32 разобраться... :)
:)
А у меня мечта... с таймерами в STM32 разобраться... :)
Скоро и у меня такая же мечта появится))))
Хотел рассказать, чем же закончилась моя эпопея с таймерами))))
Я вроде разобрался, как всё это работает и даже написал «блик» основываясь на таймере. (Кстати данный совет: чем больше вы будите перечитывать информации о таймере, тем лучше поймёте его работу!!!!! Действительно работает!!!! Я начел понимать после 20 прочтений текстов!!!).
Но дело далеко не в блинке. Я делаю свой проект и в нём я решил использовать прерывание по таймеру, чтобы он в свою очередь управлял переменными отвечающие за задержки. К сожалению, я не смог придумать лучить код (г..о-код) для реализации псевдо-многозадачности.
Код который был написан для блинка не стал работать в моём проекте. Я поленился разбираться в чём дело и самая главная отговорка была в том что блинк был написан под МК 328 а проект на 168. Так и задвинул это дело. Выходом из ситуации стала библиотека, которая вроде как стабильно работает.
Почему «вроде». Сейчас я просто не понимаю что происходит с контроллером. У меня для проекта есть две версии кода. Одна вообще убогая, но рабочая (без прерываний и на одних delay). Вторая более менее структурированная и с прерываниями по таймеру.
Дело всё в том, что первая работает как часы: МК не зависает. Одним словом всё чётко!
А вот со второй проблемы и не понятно, какого характера. МК может работать день нормально на второй зависнуть 2 раза подряд. В чём кроется причина так и не ясно. Ковыряюсь с этой проблемой уже месяц. Перелопатил весь код (улучшил его, исправил ошибки, в том числе и ошибки по использованию библиотеке для таймера).
В результате ничего не изменилось. МК по-прежнему зависает правда не часто. А однажды слетела толи прошивка толи eeprom. МК работал, отвечал на нажатия клавиш, но не выполнял никаких действий. Лечился только пере заливкой скетча.
И да оставшейся оперативной памяти после компиляции остаётся много (200). Так что вряд ли зависания от того что заканчивается оперативная память.
Могу порекомендовать использовать другой таймер или разобраться с вачдогом...
С вачдогом я тоже разобрался. Я использую другой загрузчик и стандартную библиотеку. В принципе он может решить проблему зависания. Но он не устраняет саму причину.
Ну вот и я "докатился" до прерываний. Как уже было выше написанно: "чем больше об этом читаешь, тем понятнее". Пока я только читал и моргал диодиком, вроде всё понятно. Окончательно разобраться помогла вот эта статья. Понятия не имею почему именно она стала ключём к разгадки, но я кое-что понял.
Но хотелось бы уточнить парачку нюансов:
1) что такое Prescaler и зачем он нужен? (Вроди как для точности счётчика !?)
2) вот по этой формуле высчитывается количество тиков для определённого времени:
т.е. если у меня Prescaler = 1024 и тактер 16MHz то для одной секунды я решаю так:
количество тиков = (1 с) / (1024 / 16000000) = 15625-1 = 15624
но если я прескалер не устанавливал вовсе, как я должен решать? С 0 или с 1 ?
Во я блин даю, пока писал вопрос сам с ним разобрался
но один фиг оставлю это на форуме, может кому поможет разобраться с этой темой.
А ответ на мой вопрос "1", ведь МК работает с частотой 16MHz что значит 16000000 "тиков/операций/инструкций или как это ещё называется
" в секунду. => чтобы прерыване сработало через 1 сек. нужно подождать 16000000 - 1 = 15999999 "тиков".
К стати вопрос номер (1. что такое Prescaler и зачем он нужен?) так и не отпал. Один фиг не понятно, если без Prescalerа счётчик считает точней всего, зачем оно тогда надо?
1) что такое Prescaler и зачем он нужен? (Вроди как для точности счётчика !?)
Ну, можно и так сказать (тогда уж - для снижения точности счета). Скорее, аналогом прескалера в окружающей нас действительность будет селектоор диапазонов радиоприемника: с одним положением ручки "слушаем" УКВ1, с другим - УКВ2, с надцатым и до ДВ добираемся. При этом на шкале самая левая частота больше самой правой (или в другую сторону? давно на приемник не смотрел) в одно и то же число раз - раза в два-четыре (в зависимости от модели приемника):
2) вот по этой формуле высчитывается количество тиков для определённого времени:
(# timer counts + 1) = (target time) / (timer resolution)
т.е. если у меня Prescaler = 1024 и тактер 16MHz то для одной секунды я решаю так:
количество тиков = (1 с) / (1024 / 16000000) = 15625-1 = 15624
но если я прескалер не устанавливал вовсе, как я должен решать? С 0 или с 1 ?
Если переводить дословно, то прескалер суть делитель. Частота без обработки прескалером - суть число без делителя или поделенное на что? Правильно, на единичку.
Я тоже напишу - как это я понимаю.
Допустим, мы таймером измеряем длину импульса (запуск по переднему фронту, захват значения таймера - по заднему). Тогда:
Точность измерения (относительная) зависит от разрядности счетчика, а абсолютная - от прескалера. И от этих же двух параметров зависит диапазон измерения. Это понятно, что чем точнее, тем лучше, то есть берем 16 - разядный счетчик. Масимальное значение (максимальная длина импулься) будет 65535/16000000=0,0041(с) - тоесть 4,1 мс. Точность измерения ±1 тик, то есть 0,0625 мкс. А если у нас, скажем, импульс 1с ? Вводим прескалер. Для 1024 максимальная длина импульса 4,2 с. Но и точность падает в 1024 раза (получается 64 мкс)
Здравствуйте..
Подскажите по такому вопросу..Какой таймер/счетчик в Мега 2560 может синхронизироваться с внешней частотой(Т0,Т2)..? Только 2-ой..? Мне необходимо посчитать входящие импульсы и ни одного не пропустить, а так же, если возможно, высчитать их другие параметры(скважность, длительность и т.д.).
И еще..Можно ли в устанавливать биты в регистрах таким образом EIMSK=0x58, TIFR=0x55..?
Спасибо..
Судя по картинке со схемой единственного 8-битового таймера в этих мегах, считать можно как импульсы от предделителя, так и внешние:
Судя по картинке для таймеров 1,3-5, у них те же возможности по тактированию.
А диапазон интересующих вас частот какой?
Один счетчик запускается в нормальном режиме с тактированием от внешнего источника - вот вам точное количество импульсов за определенный период времени.
Другой счетчик запускается по переднему фронту внешнего сигнала и ведет подсчет системных тактов до момента поступления заднего фронта - вот вам длительность (положительного) импульса.
Третий счетчик запускается по заднему фронту внешнего сигнала и ведет подсчет системных тактов до момента поступления переднего фронта - вот вам длительность паузы.
"Длительность"+"пауза" = "период" вашего сигнала. Скважность определяется простым делением одной величины на другую...
А почему бы и нет? Если в описании регистра для всех его битов указано ".../w", то запишете - хоть по-отдельности, хоть скопом. Ну а если не указано - то никак (ну или это не будет иметь никакого влияния на поведение микроконтроллера).
..Другой счетчик запускается по переднему фронту внешнего сигнала и ведет подсчет системных тактов до момента поступления заднего фронта - вот вам длительность (положительного) импульса.
Третий счетчик запускается по заднему фронту внешнего сигнала и ведет подсчет системных тактов до момента поступления переднего фронта - вот вам длительность паузы.
"Длительность"+"пауза" = "период" вашего сигнала. Скважность определяется простым делением одной величины на другую...
А на одном счетчике это сделать разве нельзя..?
У меня мысль реализовать это так: Захват по переднему и вкл.подсчета импульсов, переключение на захват по заднему..По приходу заднего -- записать количество в ячейку, переключение на захват по переднему с продолжением счета..По приходу второго переднего -- остановить счет и вывести оба результата на ЛСД..
Для запуска счетчика 1 мне нужно установить регистр TCCR1B=0x07(внешн.1->0) или TCCR1B=0x06(внешн.0->1) + сбросить флаг переполнения TIFR=0x01(если было), разрешить глобальные прерывания SREG=0x80, TCCR1A=0 и вроде все..Или еще что упустил..?
И еще..Судя по этому синтаксису attachInterrupt(interrupt, function, mode) можно сколько угодно использовать обработчиков прерваний..Я правильно понял..?
А на одном счетчике это сделать разве нельзя..?
Можно. После того, как освоитесь с использованием таймеров.
Опять же - все весьма существенно зависит от диапазона частот, который вы пытаетесь оседлать.
Судить лучше не по синтаксису, а по даташиту. А в даташите (ATmega1280-2560) говорится о восьми векторах запросов внешних прерываний - INT0...INT7. Кстати, судя по описанию функции attachInterrupt(), в Мегах поддерживаются только шесть из них.
Можно. После того, как освоитесь с использованием таймеров.
Уже потихоньку дело идет..Счетчик запускается по прерыванию TNT0, но пока не считает то, что нужно :(
Опять же - все весьма существенно зависит от диапазона частот, который вы пытаетесь оседлать.
Диапазон частот..Вообщем есть оптический энкодер и мне необходимо измерить кол-во импульсов, которое он выдает..Для начала-окончания отсчета исп.НОЛЬ-метка на нем(подкл. к TNT0)..Скорость вращения энкодера может быть разной(в зависимости от ск-ти вращения двигателя) и период импульсов тоже разный..И нужно подсчитать кол-во импульсов.
На ПИКе было полегче(меньше регистров и таймеров)
Вот это и хочу перенести на Ардуину и использовать ее дополнительные возможности, которых нет на ПИКе
И с Ардуино осилим.. :)
Подскажите, плизз, с флагами прерываний..Если флаг установлен, то он в 0, а если сброшен, то в 1..Так..?
Подскажите, плизз, с флагами прерываний..Если флаг установлен, то он в 0, а если сброшен, то в 1..Так..?
Так.
С точностью до наоборот.
Так.
С точностью до наоборот.
А как же даташит
Читать следует весь абзац (в конкретном случае даже два, но маленьких):
"When an edge or logic change on the INT1 pin triggers an interrupt request, INTF1 becomes set (one). If the I-bit in SREG and the INT1 bit in EIMSK are set (one), the MCU will jump to the corresponding Interrupt Vector.
The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared when INT1 is configured as a level interrupt."
В (любое) прерывание вы входите с соответствующим флагом прерывания в соответствующем управляющем регистре установленным в единицу. Эта единица сбрасывается аппаратно при выполнении операции IRET. Либо - альтернативно - программным способом, а именно посылкой единицы в соответствующий бит. При этом происходит чудо чудное - была в флаге единица, мы туда посылаем единицу. А в результате получается нулик.
Странно? да не совсем - это особенность флаговых регистров: при засылке битов в них происходит не загрузка бита, а операция двоичного сложения с потерей переноса. Грубо: 1+1 должно получиться 10, но единичка в старший разряд не переносится (это же не арифметический регистр, а флаговый) а просто теряется. То есть получаем 1+1=0...
В результате, кстати, экономится как минимум два программных такта. Ведь для манипуляции битами в тех же портах необходимо:
1) считать значение порта в РОН
2) модифицировать содержимое РОН
3) сохранить значение из РОН в порт
(РОН - регистр общего назначения)
А тут - имеем, скажем, такое состояние флагового регистра: b11110000. Посылаем в флаговый регистр байт b00100000. В итоге получаем в регистре b11010000. И все это за один такт.
step962, cпасибо..уже успел и сам разобраться, наложив на TIFR1 маску 0xFF..
Подскажите еще, что не правильно делаю..В прерывании не хочет запускаться Timer1 на тактирование по внешнему сигналу на Т1..
Вот сама функция прерывания..По второму обращению к ней необходимо запустить Counter1, а по третьему -- остановить и сбросить таймер в 0
что здесь не так..?
И вопрос по внешним прерываниям INT0-INT7..При поступлении события на эти прерывания я могу вывести обработку их в отдельные функции(как в attachInterrupt), или мне только через goto можно на них выйти..
что здесь не так..?
"не так" здесь прежде всего так называемое "применение магических чисел" (например, TCCR1B=0x06;). Таким образом вы запутываете и себя и тех, к кому вы обращаетесь за советом.
Куда как понятнее было бы написать:
TCCR1B = (1<<CS12) | (1<<CS11);
Сразу видно, что вы пытаетесь установить режим работы предделителя "110" для первого канала таймера 1. Осталось открыть соответствующую табличку и узнать, что это работа от внешнего источника тактовых сигналов по переднему фронту.
Во-вторых - отсутствие комментариев в приводимых участках кода и описания назначения переменных в сопроводительном тексте. Как мне догадаться, для чего служит переменная nul и чем она отличается от переменной nul_s?
В-третьих, приведенный участок кода - это далеко не все, относящееся к теме управления таймером. Что записано в регистр TCCR1A, остается только догадываться, а ведь от этого очень сильно зависит поведение таймера/счетчика.
В-четвертых, как уже предлагалось ранее, ходить надо шагами. А не прыжками. Отладьте части своей задачи (их три, если я правильно помню?) по-отдельности. В процессе отладки более-менее изучите, как настраивается и работает таймер/счетчик. А отладив отдельные подзадачи и повысив уровень своих знаний вы сможете более уверенно браться за решение этих трех подзадач в рамках одной функции.
Не совсем понятен вопрос. attachInterrupt именно с внешними прерываниями и работает.
step962, не ругайтесь, мне легче с HEXсом работать, поэтому и пишу так..
Вот пример скетча
А какие таймеры можно подключить на внешнее тактирование в МегаР3..Только Т0 и Т5..?
step962, не ругайтесь,
Ну это вы еще не слышали, как я ругаюсь...
И упускаете смысл работаемого. Вот, например, строка 21 ("
TCCR5A=0x00;
// обнуляем
"). Обнулением регистра это было бы только в том случае, если дальше шла бы установка нужных битов. А так как ее нет (и вообще это единственная инструкция в скетче, где производится манипуляция с регистром TCCR5A), то здесь не обнуление, а установка режима работы таймера, а именно:WGM51..WGM50=00, да еще WGM53..WGM52=00 (в "обнуляемом" регистре TCCR1B). Итого 0000 - нормальный режим работы счетчика.
А тут необходимо внимательно прочитать разделы 16.3, 17.4, 18.1 и 18.3 в даташите, а также посмотреть на распиновку камня. Можно увидеть, что
T0 - это 50-й вывод (PD7)
T1 - это 49-й вывод (PD6)
T3 - это 8-й вывод (PE6)
T4 - это 27-й вывод (PH7)
T5 - это 37-й вывод (PL2)
Кстати, внешнее прерывание INT0 сидит на 19-м выводе (PB0). Но это так - к слову...
А тут необходимо внимательно прочитать разделы 16.3, 17.4, 18.1 и 18.3 в даташите, а также посмотреть на распиновку камня. Можно увидеть, что
T0 - это 50-й вывод (PD7)
T1 - это 49-й вывод (PD6)
T3 - это 8-й вывод (PE6)
T4 - это 27-й вывод (PH7)
T5 - это 37-й вывод (PL2)
Кстати, внешнее прерывание INT0 сидит на 19-м выводе (PB0). Но это так - к слову...
Про распиновку и Даташит камня я в курсе...Я про распиновку ArduinoMega 2560R3.
В Ардуине не все прерывания и счетчики можно задействовать..Большинство(Т1,Т3 и Т4) висят в воздухе..Подпоять контакты к ним для меня не проблема..
WGM51..WGM50=00, да еще WGM53..WGM52=00 (в "обнуляемом" регистре TCCR1B). Итого 0000 - нормальный режим работы счетчика.
Но у меня при подключенном внешнем такитровании Т5 на вывод 28 Ардуино счетчик не работает, т.е. он в нуле. Или мне еще надо переключить вывод 37 камня на вход(pinMode(37, INPUT))..?
приводя номера выводов, я имел в виду выводы камня, а не Arduino-платки. Так что тут еще надо перевести 37-й вывод камня в Dxx.
Про распиновку и Даташит камня я в курсе...
При этом в скетче никак не упоминается вывод No37 (Dxx?), с которого таймер/счетчик5 будет подсчитывать импульсы в режиме тактирования от внешнего источника.
При этом в скетче никак не упоминается вывод No37 (Dxx?), с которого таймер/счетчик5 будет подсчитывать импульсы в режиме тактирования от внешнего источника.
Я чуть выше написал pinMode(37, INPUT) -- вот этого еще в скетче не хватает..? Или еще какие манипуляции с 37 выводом делать надо..?
Да. Необходимо проверить, соответствует ли 37-й вывод камня 37-му выводу Arduino Mega.
PS: Судя по этой картинке - нет такого вывода, доступного через плату Arduino Mega.
PS: Судя по этой картинке - нет такого вывода, доступного через плату Arduino Mega.
Эта картинка для Ардуино Мега 2560, а у меня 2560R3..Я выше выкладывал скрин, и там этот вывод задействован на 28 выводе Ардуино..
Так какой вывод платы соответствует 37-му выводу камня (т.е. PL2)?