Правильная инициализация таймера
Правильная инициализация таймера
Как правильно инициализировать с | или без?
В некоторых примерах можно встретить такое:
TCCR0 = 0;
TCCR0 = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00);
TCNT0 = 0;
OCR0 = 0;
TIMSK = 0;
TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00);
В некоторых примерах можно встретить такое:
TCCR0 = 0;
TCCR0 = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00);
TCNT0 = 0;
OCR0 = 0;
TIMSK = 0;
TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00);
- Реклама
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Правильная инициализация таймера
при начальной настройке - однозначно без |
т.к. во первых через команду с палкой может просочиться мусор, а во вторых команда с палкой занимает во флеше больше места и дольше выполняется...
дальше в коде, когда регистр уже настроен, можно и так, и так в зависимости от ситуации
если точно знаешь какими должны быть все байты регистра - выгодней написать без |
если не знаешь (например, скорость таймера настроилась в процессе работы, или модикация регистра происходит в подпрограмме и может быть вызвана при разных состояниях таймера) то без "|" и/или "&" не обойтись.
Добавлено after 19 minutes 28 seconds:
или. в твоем примере палка была применена только для того, чтобы заново не набивать названия регистров таймера... (возможно, оптимизатор это поймёт и, дописав недостающие биты, напишет эту команду без палки)
1 команда - обнуление регистра (имхо лишняя, т.к. 2 команда его всёравно установит в точно определенное состояние, что бы в нём ни находилось)
2- настройка режима таймера
3-5 - очистка регистров таймера
6- запуск таймера (изменяются только биты, отвечающие за прескалер)
т.к. во первых через команду с палкой может просочиться мусор, а во вторых команда с палкой занимает во флеше больше места и дольше выполняется...
дальше в коде, когда регистр уже настроен, можно и так, и так в зависимости от ситуации
если точно знаешь какими должны быть все байты регистра - выгодней написать без |
если не знаешь (например, скорость таймера настроилась в процессе работы, или модикация регистра происходит в подпрограмме и может быть вызвана при разных состояниях таймера) то без "|" и/или "&" не обойтись.
Добавлено after 19 minutes 28 seconds:
или. в твоем примере палка была применена только для того, чтобы заново не набивать названия регистров таймера... (возможно, оптимизатор это поймёт и, дописав недостающие биты, напишет эту команду без палки)
1 команда - обнуление регистра (имхо лишняя, т.к. 2 команда его всёравно установит в точно определенное состояние, что бы в нём ни находилось)
2- настройка режима таймера
3-5 - очистка регистров таймера
6- запуск таймера (изменяются только биты, отвечающие за прескалер)
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Правильная инициализация таймера
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3778063#p3778063"](возможно, оптимизатор это поймёт и, дописав недостающие биты, напишет эту команду без палки)[/uquote]Всё верно пишешь, кроме вот этой фразы. Регистры это volatile сущности, компилятор не имеет права ничего менять в доступе к ним.
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Правильная инициализация таймера
Первоначальная инициализация таймера (при включении питания, после сброса) непосредственное задание значения. То есть, TCCR0A = (1<<CS0); Регистры, общие для таймеров (TIMSK) - первые команды задание значений, последующие - |.
Совет, сначала задать режим работы таймера, затем разрешать флаги прерываний. Этот совет касается всего, где есть прерывания. В противном случае, если сначала разрешить прерывание, может выполниться условие и установится флаг прерывания и сработает соответствующее прерывание.
Совет, сначала задать режим работы таймера, затем разрешать флаги прерываний. Этот совет касается всего, где есть прерывания. В противном случае, если сначала разрешить прерывание, может выполниться условие и установится флаг прерывания и сработает соответствующее прерывание.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Правильная инициализация таймера
[uquote="VladislavS",url="/forum/viewtopic.php?p=3778071#p3778071"]Регистры это volatile сущности, компилятор не имеет права ничего менять в доступе к ним.[/uquote]наверно... но при перенастройке собаки или делителя тактовой оптимизацию отключать всёравно приходится, а иначе он таки забывает о том что это сущности...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Реклама
Re: Правильная инициализация таймера
В случае с ассемблером предварительное преобразование делает препроцессор, а в команду подставляется только готовая величина.
Для Си...
Возможно удобнее выполнить предварительно определение командного байта как константы, а затем уже ту константу подставлять в текст программы.
Допустим
const unsigned char com_word = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00);
(хотя... сдвиг нуля лишен смысла, поскольку достаточно 1<<COM00, чтобы остальные биты результата были сброшены в 0...)
а затем уже
TCCR0 = com_word;

Для Си...
Возможно удобнее выполнить предварительно определение командного байта как константы, а затем уже ту константу подставлять в текст программы.
Допустим
const unsigned char com_word = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00);
(хотя... сдвиг нуля лишен смысла, поскольку достаточно 1<<COM00, чтобы остальные биты результата были сброшены в 0...)
а затем уже
TCCR0 = com_word;
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Правильная инициализация таймера
С тоже пересчитывает сам... (даже не представляю насколько надо укуриться, чтоб это на камень возложить...)
тут как удобней программисту... если эта одинаковая настройка мелькает несколько раз или есть вероятность менять её перед компиляцией, то удобней её вынести из кода в начало (объявить константой или задефайнить), а если нет, то ... просто оставить где была...
тут как удобней программисту... если эта одинаковая настройка мелькает несколько раз или есть вероятность менять её перед компиляцией, то удобней её вынести из кода в начало (объявить константой или задефайнить), а если нет, то ... просто оставить где была...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Re: Правильная инициализация таймера
Правильно ли я понимаю:
TCCR0 = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00); - это непосредственная запись в регистр (значения)?
TCCR0 = 0b00010000 (16)
----------------------------------------------------------------------------------------------------------------------------------------------------
TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00); - это наложение битовой маски(через битовое "или")?
TCCR0 = 0b00010000 - значение регистра установленное выше
|
0b00000101 - накладываем маску ((1<<CS02)|(0<<CS01)|(1<<CS00))
=
0b00010101 - результат
Во второй настройке таймера если не будем использовать маску то COM00 сбросится в 0?
Справедливо ли это для других регистров, например для АЦП?
В настройках АЦП такого вроде не встречал, всегда используется |.
TCCR0 = (0<<COM01)|(1<<COM00)|(0<<WGM01)|(0<<WGM00); - это непосредственная запись в регистр (значения)?
TCCR0 = 0b00010000 (16)
----------------------------------------------------------------------------------------------------------------------------------------------------
TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00); - это наложение битовой маски(через битовое "или")?
TCCR0 = 0b00010000 - значение регистра установленное выше
|
0b00000101 - накладываем маску ((1<<CS02)|(0<<CS01)|(1<<CS00))
=
0b00010101 - результат
Во второй настройке таймера если не будем использовать маску то COM00 сбросится в 0?
Справедливо ли это для других регистров, например для АЦП?
В настройках АЦП такого вроде не встречал, всегда используется |.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Правильная инициализация таймера
| — прбитовое или, где бы ни применялось.
|= (а также -=, +=, %=, /=, *=, &=... и т.д.) это просто сокращенная запись..
твоё TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00);
означает TCCR0 = (TCCR0)|(1<<CS02)|(0<<CS01)|(1<<CS00);
и выполняется в МК за 3 команды:
R16 <— TCCR0;
R16 <— R16|(0b00000101); значение в скобках вычисляется ещё при компиляции и в мк закладывается уже в таком виде,
TCCR0 <— R16;
в регистр общего назначения содержимое TCCR0 выгружается потому, что мк не умеет с ним работать напрямую... простая (без |) запись в него фиксированного значения также будет происходить через РОН, но уже без выгрузки в РОН исходного состояния регистра (т.е. займёт 2 команды).
|= (а также -=, +=, %=, /=, *=, &=... и т.д.) это просто сокращенная запись..
твоё TCCR0 |= (1<<CS02)|(0<<CS01)|(1<<CS00);
означает TCCR0 = (TCCR0)|(1<<CS02)|(0<<CS01)|(1<<CS00);
и выполняется в МК за 3 команды:
R16 <— TCCR0;
R16 <— R16|(0b00000101); значение в скобках вычисляется ещё при компиляции и в мк закладывается уже в таком виде,
TCCR0 <— R16;
в регистр общего назначения содержимое TCCR0 выгружается потому, что мк не умеет с ним работать напрямую... простая (без |) запись в него фиксированного значения также будет происходить через РОН, но уже без выгрузки в РОН исходного состояния регистра (т.е. займёт 2 команды).
Последний раз редактировалось Ivanoff-iv Чт янв 23, 2020 05:55:25, всего редактировалось 1 раз.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Правильная инициализация таймера
mastech, Вы что, прикалываетесь? Откройте любой учебнике по Си и почитайте про оператор "|=".
Re: Правильная инициализация таймера
[uquote="VladislavS",url="/forum/viewtopic.php?p=3778600#p3778600"]mastech, Вы что, прикалываетесь? Откройте любой учебнике по Си и почитайте про оператор "|=".[/uquote]
Вот с этого надо было начинать. А то остальные понаписали тут для ТС "сначала таймер через =, а потом через |=". Да ну нахер. Нет никакого "правильного" в данном случае. ТС просто надо прочитать чем оператор = отличается от |=. Тогда и понимание будет, а не тупо копирование без понимания. Битовые операции используются, когда надо "не трогать" другие биты. Присваивание - когда другие биты нужно установить однозначно в 0.
ТС, читай: http://www.c-cpp.ru/books/bitovye-operatory
Может лучше ссылка есть, первая что нашел. Просто учти что a |= b, это тоже самое, что a = a | b. Аналогично как a &= b == a = a & b и т.д.
Вот с этого надо было начинать. А то остальные понаписали тут для ТС "сначала таймер через =, а потом через |=". Да ну нахер. Нет никакого "правильного" в данном случае. ТС просто надо прочитать чем оператор = отличается от |=. Тогда и понимание будет, а не тупо копирование без понимания. Битовые операции используются, когда надо "не трогать" другие биты. Присваивание - когда другие биты нужно установить однозначно в 0.
ТС, читай: http://www.c-cpp.ru/books/bitovye-operatory
Может лучше ссылка есть, первая что нашел. Просто учти что a |= b, это тоже самое, что a = a | b. Аналогично как a &= b == a = a & b и т.д.


