Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков

Сообщение slav0n »

правильное деление на 256 делается через union

Код: Выделить всё

union {u16 i; u8 c[2];} pw;
pw.i = pid->fout * MAXPULSEDURATION;
pid->pwrOutput = pw.c[1];
ohmycode!
primuss3.com
Контактная информация:
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Вы так долго будете делить, пока ТС не скажет какой ему диапазон частот нужен.
СпойлерК примеру: нужен диапазон частот от 2кГц и до 5кГц

Имеем вводные данные:

Код: Выделить всё

При тактовой частоте 1МГц, ICR1H=0 ICR1L=250                       2000Гц
При тактовой частоте 1МГц, ICR1H=0 ICR1L=100                       5000Гц
Самый простой вариант, использовать уравнение прямой проходящей через две точки:

Код: Выделить всё

АЦП=0 соответствует ICR1L=250                       2000Гц
АЦП=255 соответствует  ICR1L=100                       5000Гц
воспользуемся онлайн калькулятором, допустим этим получаем формулу

Код: Выделить всё

y=−0.5882352941176471x+250
Встраиваем ее в наш код

Код: Выделить всё

	period_temp2 = (uint16_t) ((int32_t) ((int32_t)period_temp * (-0.5882352941176471)) + 250);

	pulsewidth_temp2 = (uint16_t) ((uint32_t) ((uint32_t)pulsewidth_temp * (uint32_t)period_temp2)/256);
в протеусе моделируется ровно от 2000Гц до 5000Гц

А вот теперь делите, как хотите, хоть через союз union.
Реклама
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Starichok51 писал(а):режим №8 работает "туда и обратно".
когда ICR1 равно 256, количество тиков равно 512.
Точно! Максимальный период в режиме 8 равен 131 070. Упустил этот момент.
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Dimon456, спасибо за код. :) Хотел спросить...

Зачем делать так?:

Код: Выделить всё

period_temp2 = (uint16_t) ((uint32_t) ((uint32_t)period_temp * 0x10000)/256);
Если можно сделать так:

Код: Выделить всё

period_temp2 = (uint16_t)period_temp * (0x10000/256);
Дополнительные преобразования типов наверняка отнимают время?
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

умножение на 0х10000 (65536) и последующее деление на 256 эквивалентно одному умножению на 256.
так что, можно упростить выражение для периода.

Добавлено after 2 minutes 49 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
и первые переменные лучше объявить
uint8_t period_temp, pulsewidth_temp;
так как в них сохраняется один байт из ADCH.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Kalisnik писал(а):Дополнительные преобразования типов наверняка отнимают время?
0x10000 и 256 красивые числа, компилятор наверняка их сократит.
При 0x10000 вы не сможете перекрыть полностью диапазон. По этому у меня было три диапазона: 0x10000 0x1000 и 0x100.
Реклама
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

ну, ТС нам так и не сообщил, какой диапазон ему нужен.
видимо, нужен как раз тот, какой у него в исходнике.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков

Сообщение slav0n »

Dimon456 писал(а):0x10000 и 256 красивые числа
так и писал бы тогда их красиво: 0x10000 и 0x100
сразу была бы понятна твоя бессмыслица:
Dimon456 писал(а):у меня было три диапазона: 0x10000 0x1000 и 0x100
ohmycode!
primuss3.com
Контактная информация:
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Попробовал режим №9 Т1. Работает без всяких костылей. Кода на порядок меньше. OCR1A задает период, а OCR1B скважность.
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

на порядок - это в 10 раз.
не вижу, где у тебя могло сократиться в 10 раз.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Starichok51, хороший подкол :)
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

я вообще не вижу, чтобы было сокращение кода. нет никакой разницы, в какие регистры записывать период и длительность.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Не нужно прописывать буферизацию для ICR1 руками. В этом весь прикол.

Добавлено after 5 minutes 22 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
В дадашите рекомендуют при часто меняющейся частоте использовать регистр OCR1A для задания верхнего предела таймера.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков

Сообщение slav0n »

Kalisnik писал(а):В дадашите рекомендуют при часто меняющейся частоте
опять ТС решает задачу через ж
ohmycode!
primuss3.com
Контактная информация:
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Почему в этом примере вместо ожидаемого результата 19 349, получается 150?

Код: Выделить всё

volatile uint8_t period = 214;

OCR1A = (uint16_t)(((period * 257)/4) + 5600);
Добавлено after 20 minutes 52 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
slav0n писал(а):решает задачу через ж

Голос за кадром... :tea:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков

Сообщение slav0n »

Kalisnik писал(а):Почему в этом примере вместо ожидаемого результата 19 349, получается 150?
патамушо написано через ж
ohmycode!
primuss3.com
Контактная информация:
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Кроме комментариев мы ни чего не увидим.. :tea:
Последний раз редактировалось Kalisnik Вт окт 05, 2021 16:35:45, всего редактировалось 1 раз.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Kalisnik писал(а):Почему в этом примере вместо ожидаемого результата 19 349, получается 150?
А за чем нам еще нужно приведение типов?
Даже и не охота и объяснять

Код: Выделить всё

OCR1A = (uint16_t)((((uint32_t)period * 257)/4) + 5600);
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков

Сообщение slav0n »

Код: Выделить всё

OCR1A = period * 257UL / 4 + 5600;
ohmycode!
primuss3.com
Контактная информация:
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

Dimon456, точно! Ну или float нужно было написать. Рано или поздно, после долгого ковыряния с кодом начинает клинить... ))) Спасибо! :beer:
Ответить

Вернуться в «AVR»