Обсуждаем контроллеры компании Atmel.
Ответить

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 12:08:39

Да, я аппаратный и имел в виду... видимо непонятно написал (в пункте 1)...

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 12:28:10

2й таймер настроен неправильно...
да и не нужен 2й таймер для этой задачи...
______
1) настрой любой (пусть будет Т1) на 1кГц с режимом PWM и с генерацией прерывания
выход PWM (ШИМ) будет управлять зарядкой, а самим этим режимом будет управлять соответствующий ему регистр OCR. Т.е. режимом зарядки теперь можно управлять, изменяя OCR.
2) т.к. прерывание вызывается с частотой 1кГц, то этим можно воспользоваться - в прерывании инкрементировать переменную i (счетчик) и сравнивать её с 2мя константами С1=заполнение, С2=1000.
если i<C1 OCR=x иначе OCR=0; //(включение-отключение импульсов, х-ширина "иголок" заряда)
если i>C2 i=0; //(перезапуск программного счетчика.)

Да я понял вас, аппаратный шим, реализовывал дрыганог/ программный шим думал там меньше нагружу мк.
А почему не правильно таймер2 настроил, просто для себя так сказать докапаться по полной?

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 12:43:11

у тебя написано тактирование 250кГц из такой частоты 8 битным таймером 35 Гц не получить... хотя, ты получаешь более высокую частоту и дожимаешь её программным счетчиком... но тогда что мешает взять в качестве опоры прерывания таймера Т1?

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 13:14:13

При указанном делителе на 32 можно получить ~35Гц
OCR2=250000/32/35/2-1=110

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 13:23:18

250 кГц - это уже счётчик Т2 (делителей там дальше уже нет...)250000/35=7142, 8 битный таймер до стольки считать не умеет...
а частота всего МК = 8 МГц, вот таймер и тикает на 8М/32=250к

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 14:01:57

у тебя написано тактирование 250кГц из такой частоты 8 битным таймером 35 Гц не получить... хотя, ты получаешь более высокую частоту и дожимаешь её программным счетчиком... но тогда что мешает взять в качестве опоры прерывания таймера Т1?

не понимаю вообще 16 битный таймер, и как "дожимать" тем более... как вычислить OCR1A хотя бы 1kHz.
1 kHz опытным путем добился на выходе мк...
мои рассуждения такие:
8000000Hz/(2^16=65536)/9)=1098Hz, где 9 это TCCR1B=0x09; или из теории сухой о 16 битных таймера "даный регист TCCR отвечает за установку делителя, чтобы таймер не так быстро считал, также он отвечает (вернее его определённые биты) за установку определённого режима", TCCR1A и TCCR1B правильно ли я указал?

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 14:08:20

Ivanoff-ivПонятно. Делителей ещё до...
OCR2=8000000/1024/35/2-1~110
neid
OCR1A=8000000/1000/2-1
TCCR1B=0x09 ;режим CTC F/1
Последний раз редактировалось akl Чт янв 14, 2021 14:12:32, всего редактировалось 1 раз.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 14:36:14

neid, для расчетов не шибко важно, какой разрядности таймер. Просто у него расширяется диапазон. Есть частота тика таймера, которая в общем случае для старых мег = частоте меги / предделитель. Это 1 тик таймера. А максимум тиков до переполнения равно 2 в степени разрядности. Но максимум (TOP) может ограничиваться и меньшим значением, главное что не большим. И иметь промежуточные значения (OCR), по достижению которых что-то происходит (прерывание или изменения состояния пина).

Добавлено after 26 minutes 10 seconds:
Lilia, см главу 10.3.2 - 10.3.3 ДШ. По умолчанию CLK_PER делится на 6 от MAIN_CLK. Т.е. при основной частоте 20 МГц, периферия будет работать на 3.3 МГц, поэтому и неподходит. Кстати с CMP = 0x14, частота должна выходить в этом случае 4 кГц, а не 5. А так-то расчет верен. Просто выставьте предделитель CLK_PER в 1 в регистрах CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLB.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 15:03:45

я вот понял, попробую "перевести"...
есть исходная частота (8 МГц), есть делители на входе таймера, они как редуктор тормозят входную тактовую частоту в сколько-то (настраивается) раз, т.е таймер может тикать как на частоте 8 МГц, так и в какоето целое число раз (набор доступных делителей смотри в ДШ). каждый тик таймера увеличивает его счетчик на 1, но таймер не может считать вечно, когдато он переполнится (так-же как переворачиваются 999999 в 000000 на спидометре автомобиля...) то, как долго таймер может не переполняться как-раз и определяется его разрядностью (так-же как и в спидометре количеством счетных колёс)...
_____________
теперь о применении на практике:
тебе надо добиться, используя доступные значения делителя, чтобы счетчик тикал с частотой в целое число раз больше требуемой, но чтобы это число вместилось в разрядность таймера (для 8 битных это 256, для 16 битных - 65536 (2^16) )
тебе надо 1кГц это в 8000 раз меньше 8 МГц (число целое, и не больше 65536 - значит его можно использовать для Т1) (делитель при этом =1)
также для Т1 пойдут делители на 8 и на 64, а вот для 8 битных таймеров пойдет только делитель на 64 т.к. только (8000/64)<256 и ещё целое (при следующем доступном делителе 256 уже получается 31,25 кГц)
допустим мы оставили делитель 1, значит чтобы прошла 1мс таймер должен сосчитать от 0 до 7999, 7999 = 1F3F (HEX)
осталось сделать так, чтобы счетчик считал до этого числа и перезапускался
для этого есть режим СТС, но он нам не подходит, т.к. нам ещё нужен ШИМ сигнал на выходе, ещё есть режимы PWM - выберем "fastPWM top OCR1A" и запишем наше число в OCR1A, теперь таймер работает с частотой 1 кГц и дает выход....
нет, выход он пока не даёт, его ещё подключить надо... компаратор "А" уже занят, подключим к "В": OutB - Inverted PWM
можно выбрать и неинвертируемый, но он не умеет полностью закрываться - маленькие иголочки при сбросе таймера будут просачиваться... поэтому берём инвертируемый, но в коде это учтём.
также надо включить прерывание по совпадению А, чтобы при каждом обороте таймера ЦП контроллера об этом узнавал.
Вот, собственно и вся настройка таймера...

Добавлено after 7 minutes 29 seconds:
neid, ещё я очень рекомендую скачать программу Algorithm Builder (v5.44)в ней зоздать и настроить проект: Файл->новый..... проект->проект оптионс (тут выбрать свой МК и задать его тактовую)
потом кликнуть на красную "S" выбрать таймер/счетчик1 и поковыряться с его параметрами, и, думаю сразу станет понятней его работа...

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 15:15:53

Добавлено after 26 minutes 10 seconds:
Lilia, см главу 10.3.2 - 10.3.3 ДШ. По умолчанию CLK_PER делится на 6 от MAIN_CLK. Т.е. при основной частоте 20 МГц, периферия будет работать на 3.3 МГц, поэтому и неподходит. Кстати с CMP = 0x14, частота должна выходить в этом случае 4 кГц, а не 5. А так-то расчет верен. Просто выставьте предделитель CLK_PER в 1 в регистрах CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLB.


Спасибо огромное! Да, именно в этом было дело :))

Может насчет прерываний тоже сможете помочь?

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 15:39:35

Но в действительности ISR (TCA0_CMP0_vect) не срабатывает. .


В этом режиме он, видимо, и не будет срабатывать, т.к. в FRQ режиме значение TOP определяется регистром CMP0 (таблица 20-7 даташита).

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 15:55:40

Но в действительности ISR (TCA0_CMP0_vect) не срабатывает. .


В этом режиме он, видимо, и не будет срабатывать, т.к. в FRQ режиме значение TOP определяется регистром CMP0 (таблица 20-7 даташита).


Не поняла. Я и хочу, чтобы СМР0 было TOP. И хочу чтобы по достижению TOP было прерывание, чтобы подсчитывать время для выходного сигнала. Или это можно только через события организовать?

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 16:25:57

Lilia, т.к. достижение TOP и есть переполнение таймера, срабатывает соб-но оно. Если бы срабатывали оба, в этом случае CMP0_vect срабатывало бы в то же время абсолютно.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 16:38:53

Lilia, т.к. достижение TOP и есть переполнение таймера, срабатывает соб-но оно. Если бы срабатывали оба, в этом случае CMP0_vect срабатывало бы в то же время абсолютно.

Я всегда думала, что переполение - это достижение максимального значения по разрядности. Для таймера 16бит - это 65 635.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 16:48:01

Lilia, переполнение - это достижение TOP значения. В некоторых режимах оно равно максимальной разрядности таймера, но во многих других может снижаться. В общем-то тоже самое я писал чуть выше другому человеку для старых вариантов AVR: https://radiokot.ru/forum/viewtopic.php ... 4#p3959644
Смысл не изменился. В данном режиме согласно ДШ TOP = CMP0. Таймер считает от 0 до TOP (CMP0) и начинает с нуля. Это и есть момент переполнения. Иначе оно бы никогда у вас не достигалось. Если вам нужно шагать до 65535 (максимальное значение разрядности таймера называется MAX, эти определения есть в разделе 20.3.1 ДШ), то вам нужен другой режим таймера.

Добавлено after 5 minutes 25 seconds:
Описание прерываний:

0x00 OVF Overflow and compare match interrupt
The counter has reached its top value and wrapped to zero.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 17:01:06

Lilia, переполнение - это достижение TOP значения. В некоторых режимах оно равно максимальной разрядности таймера, но во многих других может снижаться. В общем-то тоже самое я писал чуть выше другому человеку для старых вариантов AVR: https://radiokot.ru/forum/viewtopic.php ... 4#p3959644
Смысл не изменился. В данном режиме согласно ДШ TOP = CMP0. Таймер считает от 0 до TOP (CMP0) и начинает с нуля. Это и есть момент переполнения. Иначе оно бы никогда у вас не достигалось. Если вам нужно шагать до 65535 (максимальное значение разрядности таймера называется MAX, эти определения есть в разделе 20.3.1 ДШ), то вам нужен другой режим таймера.

Добавлено after 5 minutes 25 seconds:
Описание прерываний:

0x00 OVF Overflow and compare match interrupt
The counter has reached its top value and wrapped to zero.


Да, вижу.
Если б это было так, все было бы прекрасно и все работало уже как надо. Но частота прерываний OVF выше (период ~0,05мс) и не зависит от значения CMP0 к сожалению.

Re: Таймеры/счётчики в AVR

Чт янв 14, 2021 17:56:33

Но в действительности ISR (TCA0_CMP0_vect) не срабатывает. .


В этом режиме он, видимо, и не будет срабатывать, т.к. в FRQ режиме значение TOP определяется регистром CMP0 (таблица 20-7 даташита).


Не поняла. Я и хочу, чтобы СМР0 было TOP. И хочу чтобы по достижению TOP было прерывание, чтобы подсчитывать время для выходного сигнала. Или это можно только через события организовать?

Здесь надо понимать, как таймер взводит флаги на значения счётчика таймера. А флаги взводятся не в момент совпадения / переполнения / обнуления, а только в следующем такте таймера.

Добавлено after 4 minutes 4 seconds:
Да, вижу.
Если б это было так, все было бы прекрасно и все работало уже как надо. Но частота прерываний OVF выше (период ~0,05мс) и не зависит от значения CMP0 к сожалению.

Потому, что флаги в прерывании автоматически не сбрасываются. Их надо сбрасывать программно. Поэтому как только МК покидает обработчик прерывания, он выполняет одну инструкцию основного кода и опять уходит в прерывание.

Добавлено after 9 minutes 52 seconds:
Я всегда думала

Надо не думать и даже не предполагать, а внимательно читать даташит.
И это простой синхронный таймер А. А асинхронный таймер D вообще способен вынести мозг.

0-ая и 1-ая серия AVR очень заковыристая.

Re: Таймеры/счётчики в AVR

Пт янв 15, 2021 11:07:32

Все работает, действительно OVF, квитирование помогло. Даташит хитрый, не сразу поймешь, что они имеют ввиду.

Спасибо огромное!

Re: Таймеры/счётчики в AVR

Вс янв 17, 2021 14:39:31

я вот понял, попробую "перевести"...
есть исходная частота (8 МГц), есть делители на входе таймера, они как редуктор тормозят входную тактовую частоту в сколько-то (настраивается) раз, т.е таймер может тикать как на частоте 8 МГц, так и в какоето целое число раз (набор доступных делителей смотри в ДШ). каждый тик таймера увеличивает его счетчик на 1, но таймер не может считать вечно, когдато он переполнится (так-же как переворачиваются 999999 в 000000 на спидометре автомобиля...) то, как долго таймер может не переполняться как-раз и определяется его разрядностью (так-же как и в спидометре количеством счетных колёс)...
_____________
теперь о применении на практике:
тебе надо добиться, используя доступные значения делителя, чтобы счетчик тикал с частотой в целое число раз больше требуемой, но чтобы это число вместилось в разрядность таймера (для 8 битных это 256, для 16 битных - 65536 (2^16) )
тебе надо 1кГц это в 8000 раз меньше 8 МГц (число целое, и не больше 65536 - значит его можно использовать для Т1) (делитель при этом =1)
также для Т1 пойдут делители на 8 и на 64, а вот для 8 битных таймеров пойдет только делитель на 64 т.к. только (8000/64)<256 и ещё целое (при следующем доступном делителе 256 уже получается 31,25 кГц)
допустим мы оставили делитель 1, значит чтобы прошла 1мс таймер должен сосчитать от 0 до 7999, 7999 = 1F3F (HEX)
осталось сделать так, чтобы счетчик считал до этого числа и перезапускался
для этого есть режим СТС, но он нам не подходит, т.к. нам ещё нужен ШИМ сигнал на выходе, ещё есть режимы PWM - выберем "fastPWM top OCR1A" и запишем наше число в OCR1A, теперь таймер работает с частотой 1 кГц и дает выход....
нет, выход он пока не даёт, его ещё подключить надо... компаратор "А" уже занят, подключим к "В": OutB - Inverted PWM
можно выбрать и неинвертируемый, но он не умеет полностью закрываться - маленькие иголочки при сбросе таймера будут просачиваться... поэтому берём инвертируемый, но в коде это учтём.
также надо включить прерывание по совпадению А, чтобы при каждом обороте таймера ЦП контроллера об этом узнавал.
Вот, собственно и вся настройка таймера...

Добавлено after 7 minutes 29 seconds:
neid, ещё я очень рекомендую скачать программу Algorithm Builder (v5.44)в ней зоздать и настроить проект: Файл->новый..... проект->проект оптионс (тут выбрать свой МК и задать его тактовую)
потом кликнуть на красную "S" выбрать таймер/счетчик1 и поковыряться с его параметрами, и, думаю сразу станет понятней его работа...

codevision тоже симулирует. но в протеусе получаются совсем другие периоды. неделю копаюсь.

Re: Таймеры/счётчики в AVR

Вс янв 17, 2021 14:41:17

sergs777, вангую, что в протеусе, в свойствах компонента МК просто не поменяли частоту на нужную.
Ответить