Таймеры Arduino. Как они работают
Объясните эту строчку простыми словами.
TCCR0B=TCCR0B&0b11111000|0x01;
Так как разные ардуино имеют разные чипы. У них также есть разные таймеры и разные контакты, которые их используют.
В последнее время я хочу переписать код(Arduino Uno), чтобы он работал на Arduino Micro.
Мне нужно понять, как это работает простыми словами. Обычно я пишу веб-код(javascript,php...). Совсем недавно я начал писать на c++ или "упрощенном" c++ в arduino ide. Это не так уж трудно. Но некоторые конкретные параметры мне трудно понять. Ярлыки, как показано ниже.
TCCR0B=TCCR0B&0b11111000|0x01;
Что это значит?
TCCR0B
TCCR
= Префикс для таймеров. Правильно?
0
= Timer1 или 0 называйте это как хотите.
B
= Для чего нужны A,B,C, а иногда и D? Что это значит?почему в этом коде программист использует B,а не A, C или D
TCR0B=
Таймер 0 B равен:
TCR0B&
if Таймер 0 B возвращает True .. существует "&" ?
0b11111000
Что это такое? я уже спрашивал об этом,и ответ был что-то вроде "очищает младшие 3 бита". Как я уже сказал, я не очень хорошо знаком с c++, битами и другими вещами, касающимися arduino. Теперь я меньше говорю о различных чипах, а также о том, как они реализовали различные параметры arduino ide для работы с этими чипами. Я знаю, что у меня есть 8 значений, которые я могу изменить с 0 на 1. Что эти значения изменяются относительно таймера? Пожалуйста, думайте обо мне как о 6-летнем ребенке.
|0x01;
Я понял это... он устанавливает прескалер... 1,8,32.. некоторые таймеры имеют разные значения... нет проблем. Мне это нужно в 1 час.
@cocco, 👍3
Обсуждение4 ответа
Лучший ответ:
Сначала я займусь тем, что
TCCR0B=TCCR0B&0b11111000|0x01;
означает с точки зрения чистого программирования:
Давайте разберем его на части:
TCCR0B = TCCR0B & 0b11111000 | 0x01;
TCR0B
- это регистр. На самом деле это может быть любая переменная - это просто "значение" в данном контексте. То, что он управляет одним из таймеров, не имеет значения.
0b11111000
- это двоичное представление значения. Это то же самое, что шестнадцатеричное число 0xF8
. F-это 15. 15 в двоичном формате-это 1111. 8-это 8 как в шестнадцатеричном, так и в десятичном. 8 в двоичном коде-это 1000. Сложите их вместе, и у вас будет 11111000. Кстати, в десятичной системе счисления это 248.
0x01
- это шестнадцатеричное число для 1 в десятичной системе счисления, а также 1 в двоичной системе счисления.
Между ними находятся побитовые операторы - &
- это побитовая операция И, а
|
- это побитовая операция ИЛИ.
И
вычисляет, какие биты в паре двоичных чисел включены, и ИЛИ
вычисляет, какие биты в паре двоичных чисел включены в любом из чисел.
Так что сначала возьми первый. Допустим,
регистр TCR0B содержит значение 0x6F
, равное 157 в десятичной системе счисления или 01101111 в двоичной системе счисления. Первая операция заключается в том, чтобы И
что с 11111000:
01101111
11111000 AND
--------
01101000
Вы можете видеть, что последние три бита значения были очищены, потому что они не равны 1 как в левом, так и в правом операнде оператора&
.
Итак, следующая операция-ИЛИ
это с 0x01:
01101000
00000001 OR
--------
01101001
Фактически два операнда были наложены друг на друга, и любые биты, заданные в любом из операндов, будут отражены в результате.
Таким образом, наконец, значение сохраняется в TCR0B
.
Таким образом, эта конкретная операция очищает три нижних бита, а затем устанавливает самый низкий бит TCR0B.
Теперь, что это на самом деле означает в отношении того, что делает регистр TCR0B, можно почерпнуть из таблицы данных для чипа. Например, возьмите чип ATmega328P с платы Arduino UNO. Раздел 14.9.2 "TCR0B – регистр управления таймером/счетчиком B" спецификации подробно описывает этот регистр. Битовый обзор выглядит следующим образом:
Все эти биты соответствуют 1:1 двоичным битам сверху в том же порядке. Таким образом, первый этап, очистив три младших бита, устанавливает CS02, CS01 и CS00 равными 0. Второй этап, ORing 0x01, затем устанавливает CS00 в 1.
Далее в таблице рассказывается, что это значит:
- Биты 2:0 – CS02:0: Выбор часов
Три бита выбора тактовых импульсов выбирают источник тактовых импульсов, который будет использоваться таймером/Счетчиком.
И таблица, показывающая различные значения возможных значений:
Значение, которое было замаскировано и создано для этих трех битов, конечно же, 001, что в этой таблице означает "CLK I/O / (No prescaling)", то есть таймер, работающий на частоте часов ввода-вывода. Если бы вы установили эти биты на 010, то получили бы "CLK I/O / 8 (из прескалера)". Таким образом, ваша маскировка изменится на:
TCCR0B = TCCR0B & 0b11111000 | 0x02;
Или более явно, чтобы вам было легче видеть биты:
TCCR0B = TCCR0B & 0b11111000 | 0b010;
Что касается того, что означают "A" и "B" (TCR0A и TCR0B), то есть два регистра, которые используются для управления таймером. Каждый из них служит своей цели. TCR0A имеет биты, управляющие ШИМ, а TCR0B-биты, управляющие самим таймером.
Не следует путать с OCR0A и OCR0B, которые представляют собой два отдельных числовых значения, которые сравниваются со значением счетчика таймера TCNT0 для обеспечения двух отдельных ШИМ-выходов (OC0A как Uno pin D6 и OC0B как Uno pin D5), синхронизированных из одной и той же временной базы. (См. Разделы 14.9.4 OCR0A – Выходной регистр сравнения A и 14.9.4 OCR0B – Выходной регистр сравнения B в таблице данных)
На самом деле я пытаюсь получить совсем не это в качестве ответа.Мне нужна та часть, которую ты пропустил. Эта часть на самом деле легко понять для меня, так как я много работаю с языком кодирования. также вы можете легко найти онлайн шестнадцатеричные преобразователи в десятичные и так далее. Мой вопрос в том, что эта строка на самом деле делает простыми словами. Если я не знаю, что ищу, я не могу должным образом ознакомиться с таблицей данных на 438 страницах. Все, что я знаю, это то, что мне нужно установить таймер на прескалер 1. Понимание того,в чем разница между TCR1A,TCR1B, TCR1C или тем, что представляют эти 8bit (0b11111000)., @cocco
Подумай об этом ... Я ничего не знаю. я умею кодировать. "TCCR-это просто ценность", - сказали вы. Почему я не могу просто написать: "Timer1 setPrescaler 1". Почему мне нужно написать "Timer1b dosomething или установить значение 1", @cocco
Если бы я знал, где искать данные, меня бы здесь не было. Все, что я знаю, это то, что мне нужно изменить прескалер различных выводов различных таймеров различных чипов различных плат. А теперь они все другие., @cocco
С другой стороны. если бы я хотел получить такой ответ, я бы спросил в stackoverflow, а не здесь. Это конкретный вопрос Arduino., @cocco
В таблице данных выберите "8-битный таймер/счетчик 0 с ШИМ" или как там это называется для вашего чипа. Затем выберите "Описание регистра", затем "TCR0B", и он сообщит вам, что означает каждый бит. В спецификации 328p это раздел 14.9.2 на странице 109. Индексы-это замечательные вещи., @Majenko
@cocco С другой стороны, поскольку это не имеет ничего общего с Arduino и на самом деле касается чипов ATmega, которые находятся на них, вы бы действительно задали этот вопрос Electronics.SE Большинство людей, которые приземляются здесь, не имеют базовых навыков программирования, чтобы понять побитовые операции, поэтому это ответ, данный здесь - это ответ для пользователей Arduino, в то время как вы больше похожи на то, что ищете ответ EE., @Majenko
Извините, я не хотел быть плохим... но: эти сайты созданы для того, чтобы упростить жизнь людей. я зарегистрирован на различных сайтах стека, я ответил на больше вопросов, которые я задал. я пишу код уже много лет. не c++ в простом javascript php и других... понимание этого языка легко для меня, так как он использует почти тот же синтаксис, что и javascript или php... в конце концов, они почти одинаковы. я знаю побитовые oerators, даже если они немного отличаются в js/php. Каждый язык имеет свою собственную ссылку на функцию. Ссылка на arduino ограничена и не описывает должным образом каждую функцию, @cocco
Этот вопрос очень специфичен. Там говорится об ардуино. дело в том, что каждый отдельный arduino имеет свои отличия, зависит от чипа. Я не могу найти "Описание регистра"., @cocco
Сайт Arduino действительно говорит только о конкретных функциях API Arduino, а не о базовом языке, которым является C++. Для всего, что не относится к стандарту Arduino, следует использовать учебные пособия и ссылки на C и C++ (хотя они об этом не упоминают). Такие вещи, как побитовые операторы, являются стандартными C, поэтому не объясняются должным образом на сайте Arduino., @Majenko
но также я не понимаю разницы между TCR0A,TCR0B,TCR0C, как вы сказали... это все один и тот же таймер.. так почему же существует разница между этими значениями?, @cocco
TCR0A = не специфично для arduino? не c++?, @cocco
Итак, в основном вы говорите, что TCR0A не специфичен для arduino, а более специфичен для Atmel? если да, то скажите мне, куда обратиться, чтобы задать этот вопрос., @cocco
Давайте [продолжим это обсуждение в чате](http://chat.stackexchange.com/rooms/27138/discussion-between-majenko-and-cocco)., @Majenko
я в чате, если хочешь, @cocco
Это специфично для чипа, который находится на Arduino. Arduino не делают чипы, они просто покупают их у Atmel. Именно Atmel определяет регистры и то, что они делают. Я расширил ответ информацией о регистрах из таблицы данных и о том, как ее интерпретировать., @Majenko
Ответ на высоком уровне таков: каждый бит (или группа битов) в регистре на практике подобен ручке, которая может настраивать определенные части HW. Для каждого периферийного устройства, которым вы хотите управлять, вы должны понимать структурные схемы, связанные с ними регуляторы и в каких регистрах эти регуляторы расположены. Иногда существует несколько (почти) идентичных экземпляров определенного блока HW, и в случае ATmega эти экземпляры часто адресуются письмами. Таким образом, регистры, имеющие почти идентичные имена, кроме A, B, C, в основном идентичны, но каждый из них будет влиять на отдельный экземпляр определенного периферийного устройства. В зависимости от того, какие контакты или прерывания вы хотите использовать, вы можете выбрать конкретный экземпляр определенного периферийного устройства. Вы должны проверить руководство программиста ATmega328P (это 2k страниц, но легко найти нужный раздел).
Чтобы добавить к очень тщательному и превосходному ответу Майенко (который я пока не могу проголосовать, потому что я очень новичок): Давайте попробуем отточить нужную вам строку кода:
TCCR0B=TCCR0B&0b11111000|0x01;
В этом конкретном Ardiuno TCR0B-это регистр, который управляет скоростью этого конкретного таймера. Более конкретно, самые младшие 3 бита (последние в 8-битном значении) управляют прескалером. Производитель маркирует их как CS02, CS01 и CS00. Комбинация 1s и 0s в этих трех битах определяет, масштабируется ли тактовое время или нет, и на сколько (или даже если есть внешний источник тактовых импульсов). Воспроизведенная таблица 14-9 подскажет вам, насколько часы "замедлились". Это позволяет вам создать таймер 1 Гц (1 секунда), например, вместо таймера 16 Мгц (или любого другого, на котором работает ваша конкретная плата), уменьшив скорость "тиканья"таймера. Если вы погуглите "Arduino hardware timer calculator" или что-то подобное, вы можете найти очень полезные инструменты, которые помогут вам установить нужную тактовую частоту. Сделайте это, так как установка неправильных значений сопряжена с опасностью, и ваш компилятор может не уловить то, что может быть серьезной ошибкой.
Я узнал об аппаратных таймерах только после того, как изучил Arduino в течение нескольких лет. Оказывается, они очень и очень полезны!
Я понимаю, что ваш вопрос не о c++ и битовых манипуляциях.
Речь идет не о "Arduino", потому что ваша строка кода имеет смысл только для определенного микроконтроллера avr с регистром TCR0B
.
Конечно, некоторые ардуино основаны на таких микроконтроллерах, и компилятор c++, используемый в цепочке инструментов arduino, позволяет получить доступ к этим аппаратным регистрам через их имена, используемые в таблицах данных.
Однако детали выходят за рамки "Arduino" и должны быть найдены в соответствующей таблице данных контроллера.
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Как считать время в секундах?
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
Связанный с этим вопрос: http://arduinoprosto.ru/q/14298/arduino-uno-vs-arduino-micro-timers-pins/, @Nick Gammon
-я уже спрашивал об этом, и ответ был что-то вроде "очищает младшие 3 бита". Как я уже сказал, я не очень хорошо знаком с c++, битами и другими вещами, касающимися arduino.- О'кей, ты не понимаешь, что значит "очистить младшие 3 бита". Затем в другом комментарии вы говорите: "Эта часть на самом деле легко понять для меня, так как я много работаю с языком программирования. также вы можете легко найти онлайн шестнадцатеричные преобразователи в десятичные и так далее.- Непонятно, о чем вы спрашиваете. Сначала вы говорите, что не знакомы с битами C++, а затем говорите, что это не то, о чем вы спрашиваете., @Nick Gammon
мне нужно было простое объяснение того, что меняют эти 3 бита и другие 7 бит. Я также не знал, для чего нужны ABCD, которые добавляются к TCR0. Это разные регистры по 8 бит каждый. На, вероятно, всех arduino, чтобы изменить прескалер, вам нужен только регистр B. последние 3 бита. они меняют мультипликатор. "TCR0B=TCR0B&0b11111000|0x01;" эта строка: таймер 0 регистр B сбрасывается и вновь устанавливается на 1.Соответствующие таймеры для arduino micro и uno-это pin 9,10,12 ... все используют регистр timer4 b...и мне нужно изменить последние биты, @cocco
в вашем действительно хорошем, но сложном для меня ответе я не могу этого прочитать. Вы не объясняете, что эти последние 3 бита 0b11111000 предназначены для сброса таймера. вы также не объясняете, что означает abcd. затем, когда я задал вам еще один вопрос, вы велели мне написать новый.. я так и сделал. вы получили +1 и правильный ответ., @cocco
И Майенко, и я опубликовали выдержку из таблицы данных, показывающую, что означает каждый из 8 битов в TCR0B. - Если я не знаю, что ищу, то не смогу должным образом ознакомиться с таблицей данных на 438 страницах.- вы смотрите на ту часть Таймера 1 (или Таймера 2 и т. Д.), Которая занимает всего несколько страниц. Затем вы смотрите на страницу, описывающую TCR0B. Это описывает каждый из этих 8 битов. Каждый бит имеет имя (напр. WGMC13, CS10). Под текстом в таблицах данных объясняется, что делают эти биты. Библиотеки на Arduino предназначены для того, чтобы помочь людям писать код, не читая таблиц данных. Если вы хотите пойти дальше, вы должны прочитать их., @Nick Gammon
я просмотрел таблицу данных несколько раз , это все равно что смотреть на гироглифы. так что, показав мне часть гироглифов, вы не решите проблему. мне уже трудно писать и читать все по-английски. Мне нужны простые объяснения. @Majenko , как увидел, что я ничего не понимаю, открыл чат и объяснил мне, что эти 3 бита-это те же самые биты, которые меняют прескалер... эти 3 бита, вероятно, всегда находятся в регистре B таймера N. эти 3 бита необходимо сбросить, чтобы вы могли снова изменить их на то, что хотите., @cocco
Давайте [продолжим это обсуждение в чате](http://chat.stackexchange.com/rooms/27171/discussion-between-cocco-and-nick-gammon)., @cocco
чат!чат!чат!, @cocco
я проверил их... 3 бита где-то меняют что-то другое, и что A B C & D-это своего рода подмножество таймера... теперь все ясно... ABCD-это "память" каждого таймера, содержащая все различные настройки... только 3 бита в памяти B изменяют прескалер. теперь, когда я знаю, что ваш ответ также намного яснее, намного яснее, чем фактическая таблица данных... они должны переписать таблицу данных..., @cocco
TCR0B=TCR0B&0b11111000|0x01;
непостижимо без данных. Поиск данных ATmega328P UNO по адресу https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf для "TCR0B" есть 8 совпадений, по одному для раздела "14.9.2 TCR0B – регистр управления таймером/счетчиком B", который объясняет каждый из битов, аналогичных TCR0B на ATmega32U Micro https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf . Я бы написал clear/setTCR0B=(TCR0B & 0b11111000) | 0b001;
Есть TCR0A и TCR0B, контролирующие таймер 0., @Dave X