13.6.1. Обращение к 16разрядным регистрам Каждый 16разрядный регистр таймеров/счетчиков физически разме щается в двух 8разрядных регистрах. Соответственно для обращения к ним требуется выполнить по две операции чтения или записи. Для того чтобы запись или чтение обоих байт содержимого 16разрядного регистра проис ходила одновременно, в составе каждого таймера/счетчика имеется специ альный 8разрядный регистр TEMP, предназначенный для хранения стар шего байта значения (этот регистр используется только процессором и программно недоступен). Для выполнения цикла записи 16разрядного регистра первым должен быть загружен старший байт, который помещается в регистр TEMP. При последующей записи младшего байта он объединяется с содержимым реги стра TEMP, и оба байта одновременно (в одном и том же машинном цикле) записываются в 16разрядный регистр. Если требуется изменить несколько 16разрядных регистров таймера/счетчика, а старшие байты всех записы ваемых значений одинаковы, загрузку старшего байта достаточно выпол нить только один раз. Для выполнения цикла чтения 16разрядного регистра первым должен быть прочитан младший байт. При его чтении содержимое старшего байта помещается в регистр TEMP. При последующем чтении старшего байта воз вращается значение, сохраненное в регистре TEMP. Исключение составля ют только регистры сравнения OCR1A/B/C (OCR3A/B/C), при чтении ко торых регистр TEMP не задействуется. При выполнении цикла обращения к 16разрядному регистру тайме ра/счетчика прерывания должны быть запрещены. В противном случае, ес ли прерывание произойдет между двумя командами обращения к 16раз рядному регистру, а в подпрограмме обработки этого прерывания тоже будет произведено обращение к какомулибо из 16разрядных регистров того же таймера/счетчика, содержимое регистра TEMP будет изменено. Как следст вие, результат обращения к 16разрядному регистру в основной программе будет неверным. (Евстифеев. Вообще, все нюансы здесь)
В даташите все то же самое, только по английски. Текст приводить не буду.
Т.е. когда вы пишите значение в старший байт - вы фактически пишете его в Temp. А запись в сам старший байт происходит при записи значения в младший регистр. Т.е. Вы смотрели текущее значение страшего регистра до его модификации записью во младший.
Я так понимаю, Вы на железе проверяли?
Последний раз редактировалось ИС-пытатель Пт апр 11, 2014 13:06:08, всего редактировалось 4 раз(а).
Ошибка в коде найдена! Был вкючен режим ШИМ. Таймер был сконфигурирован как Phase correct PWM 9 бит, а не как CTC. При включенном режиме ШИМ запись в регистр High идет напрямую, а не через TEMP! Поэтому одновременной записи в два 8-ми битных регистра и не получается.
Ответ на вопрос "Где хваленые русские спецы?". Мне грустно. За Вас и за Россию. За Вас потому что читать не умеете. А за Россию потому, что таких миллионы..
Ответ на вопрос "Где хваленые русские спецы?". Мне грустно. За Вас и за Россию. За Вас потому что читать не умеете. А за Россию потому, что таких миллионы..
Если Вы спец (не спорю), объясните почему происходил сброс значения регистра OCR1AH
При включенном режиме ШИМ запись в регистр High идет напрямую, а не через TEMP!
Это кто Вас такому научил? Плюньте ему в лицо!
Согласен, инфа была не достоверной, но это не повод выражать свое мнение относительно умений или не умений совершенно незнакомого человека!!! P.S. Не ошибается только тот, кто ничего не делает.
Я уже ответил на Ваш вопрос. Вырезкой текста из Евстифеева. Там все описано. Никакого сброса не было. Вы писали и читали разные регистры. Я не считаю себя мега-крутым специалистом, ибо всегда есть куда расти. Я всего лишь опытнее Вас в этом вопросе. А еще в отличие от Вас я умею разжевывать и анализировать прочитанное, а не глотать целиком и выдавать свои догадки за действительное. Но это тоже всего лишь опыт.
P.S. Воспринимайте критику как критику (указатель на ошибки и недочеты), а не как плевок в Вашу сторону. Ибо только критика позволит Вам не расслабляться и двигаться вперед. Но и это вопрос опыта.. ))
Я уже ответил на Ваш вопрос. Вырезкой текста из Евстифеева. Там все описано. Никакого сброса не было. Вы писали и читали разные регистры. Я не считаю себя мега-крутым специалистом, ибо всегда есть куда расти. Я всего лишь опытнее Вас в этом вопросе. А еще в отличие от Вас я умею разжевывать и анализировать прочитанное, а не глотать целиком и выдавать свои догадки за действительное. Но это тоже всего лишь опыт.
P.S. Воспринимайте критику как критику (указатель на ошибки и недочеты), а не как плевок в Вашу сторону. Ибо только критика позволит Вам не расслабляться и двигаться вперед. Но и это вопрос опыта.. ))
Написано и прочитано было то, что надо. Видимо вы плохо разжевали этот вопрос и проглотили один комочек)) не учев ошибки, с которой столкнулся я!
Mr.Noiro писал(а):
ldi r16,0x05 out TCCR1B,r16 ldi r16,0x02 out TCCR1A,r16 ldi r16,high(pause) ldi r17,low(pause) out OCR1AH,r16 out OCR1AL,r17
записав командой out OCR1AH,r16 - значение в регистре появляется. Но после следующей команды - пропадает. В регистре OCR1AL - сохраняется и не исчезает, МК tiny2313, avrstudio 4. В чем может быть причина?
Плохо разобравшись в вопросе (решив свою задачу и не вдаваясь в подробности) я допустил ошибку в следующем посте:
Mr.Noiro писал(а):
Ошибка в коде найдена! Был вкючен режим ШИМ. Таймер был сконфигурирован как Phase correct PWM 9 бит, а не как CTC. При включенном режиме ШИМ запись в регистр High идет напрямую, а не через TEMP! Поэтому одновременной записи в два 8-ми битных регистра и не получается.
По совету "ИС-пытатель" я разобрался. Таков результат: Запись в High-регистр 16-ти разрядного регистра сравнения OCR1 происходит через недоступный для программиста регистр TEMP, как в режиме CTC, так и в режиме ШИМ. В режиме ШИМ необходимо быть внимательнее со значением, записываемым в регистр OCR, т.к. его разрядность может быть ограничена 8-ю (0xFF), 9-ю(0x1FF) или 10-ю(0x3FF) разрядами (зависит от режима). Соответственно, например, при записи в OCR1A в режиме "Phase correct PWM9-разрядный" числа 0x2FF произойдет следующее:
.equ zzz=0x02FF
ldi r16,high(zzz) ldi r17,low(zzz) out OCR1AH,r16 //число 0x02, запишется в TEMP - 0b00000010 out OCR1AL,r17 //число 0xFF, запишется в OCR1AL - 0b11111111, а в регистре OCR1AH произойдет переполнение (он объявлен как 9-й разряд OCR1A, соответственно - один бит не может содержать число, большее чем 0b01, а в коде в него было записано 0b10) и он обнулится.
По совету "ИС-пытатель" я разобрался. ... .equ zzz=0x02FF
ldi r16,high(zzz) ldi r17,low(zzz) out OCR1AH,r16 //число 0x02, запишется в TEMP - 0b00000010 out OCR1AL,r17 //число 0xFF, запишется в OCR1AL - 0b11111111, а в регистре OCR1AH произойдет переполнение (он объявлен как 9-й разряд OCR1A, соответственно - один бит не может содержать число, большее чем 0b01, а в коде в него было записано 0b10) и он обнулится.
Вы опять какие-то свои домыслы вставили.... С чего Вы взяли, что контроллер что-то обнуляет в зависимости от режима? Это где-то описано? Или Вы это проверили сделав хотя бы 3-4 эксперимента? Вот Вам вопрос, а если в Temp записать число 0b11? Обнулится первый бит и останется там просто 0b01?
Более того, в этом топике Вы очень уверенно отвечаете, что это именно так (могу это расценивать не более чем браваду), а вот в соседнем спрашиваете, верно ли Ваше ПРЕДПОЛОЖЕНИЕ?
Я Вам дам ответ на Ваше ПРЕДПОЛОЖЕНИЕ.
НИЧЕГО контроллер НЕ ОБНУЛЯЕТ. Он просто не использует старшие биты, которые Вы записали в верхний регистр. И... как бы все.. )
И давайте, все же начнем с того, что КАК именно Вы определили, что там что-то обнуляется? Вообще, давайте ВЕСЬ свой код сюда! Вместе разберем!
Я высказал предположение, проверенное в симуляторе. А в с соседнем топике "Ассемблер (ASM) для AVR в вопросах и ответах" решил узнать мнения, может кто делал опыты на реальном девайсе. Код сейчас будет - с (как Вы это называете) очередными моими домыслами и догадками))
Последний раз редактировалось Gudd-Head Пт апр 11, 2014 15:17:08, всего редактировалось 1 раз.
В DS все описано: When changing the TOP value the program must ensure that the new TOP value is higher or equal to the value of all of the Compare Registers. If the TOP value is lower than any of the Compare Registers, a compare match will never occur between the TCNT1 and the OCR1x. Note that when using fixed TOP values, the unused bits are masked to zero when any of the OCR1x Registers are written. У Вас фиксированный TOP=0x1FF в phase correct PWM, так что, когда запишете, например, 0x3FF в OCR1A, туда попадет 0x1FF.
]Note that when using fixed TOP values, the unused bits are masked to zero when any of the OCR1x Registers are written[/b]. У Вас фиксированный TOP=0x1FF в phase correct PWM, так что, когда запишете, например, 0x3FF в OCR1A, туда попадет 0x1FF.
Коротко и понятно, без вяких там
ИС-пытатель писал(а):
"Где хваленые русские спецы?". Мне грустно. За Вас и за Россию. За Вас потому что читать не умеете. А за Россию потому, что таких миллионы..
вода-вода-вода...и только под конец Вы немного начали наставлять на путь. Ну и за это спасибо. Заставили разобраться в этом вопросе: сначала один раз "разобраться", а потом второй))
Прошу прощение за долгое отсутствие. Уезжал на выходные. В общем дело обстоит несколько иначе. Если вы сначала инициализируете режим таймера, а потом записываете в регистр сравнения, то у Вас старшие, не используемые биты, обнуляются. Т.е. все происходит так, как описал a_skr. А ежели Вы сначала инициализируете регистр сравнения, а потом режим самого таймера, то у Вас в регистре остается ПОЛНОЕ значение, но контроллер ИСПОЛЬЗУЕТ УСЕЧЕННОЕ (ничего не обнуляя). Т.е. так, как сказал Вам я. Проверено на железе. Время срабатывания таймера отслеживалось осциллографом по изменяющейся ноге. Так что я сделал то, чего Вы и добивались - проделал за Вас всю работу.
Вопрос по таймеру с частотой, допустим, 1/8 тактовой частоты МК. Если я устанавливаю текущее значение таймера, то оно будет инкрементировано через восемь тактов после: а) изменения значения таймера; б) предыдущего инкремента таймера?
Вариант Б. Предделитель работает независимо. Его можно сбросить.
Цитата:
The prescaler is free running (i.e., operates independently of the clock select logic of the Timer/Counter) and it is shared by Timer/Counter1 and Timer/Counter0. ... It is possible to use the prescaler reset for synchronizing the Timer/Counter to program execution.
2 a_skr. Благодарю! А если я еще раз передам в регистр TCCR1B биты, указывающие на предделитель 1/8, это будет считаться сбросом? Или для сброса надо передавать другое значение?
Не будет. Этими битами просто выбирается вход мультиплексора источника тактирования. Для сброса есть специальный бит Bit 0 – PSR10: Prescaler Reset Timer/Counter1 and Timer/Counter0 в регистре SFIOR (на примере меги8). В ДШ все описано, там целая глава про это - Timer/Counter0 and Timer/Counter1 Prescalers.
А почему не хотите прочитать полностью главу о таймерах у Естифеева? Там описано ВСЕ (и не особо много). Или Вы привыкли, чтобы Вас мордочкой возили вперед-назад?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 214
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения