Обсуждаем контроллеры компании Atmel.
Вт окт 05, 2021 16:44:35
slav0n писал(а):- Код:
OCR1A = period * 257UL / 4 + 5600;
Хоть бы проверил, ответ 5600.
Вт окт 05, 2021 16:50:36
slav0n,
Добавлено after 5 minutes 15 seconds:Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.Dimon456, да вроде он правильно все написал. В симуляторе правильное число.
Последний раз редактировалось
Kalisnik Вт окт 05, 2021 16:51:40, всего редактировалось 1 раз.
Вт окт 05, 2021 16:54:33
Dimon456 писал(а):ответ 5600
докази?
Добавлено after 3 minutes 34 seconds:Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.доказательства?
Вт окт 05, 2021 16:57:18
Уговорил, все равно код asm одинаковый получается, как в моем так и в твоем случае.
Вт окт 05, 2021 17:01:37
код прозрачней
Ср окт 06, 2021 21:00:40
Мне вот один момент не понятен. Допустим имеем переменную period = 100. При делении ее на 257 получаем число с плавающей запятой (float). Тип данных uint32_t это тот же long - целое длинное число. Почему написав uint32_t мы имеем такой же эффект, как если бы написали float? Переменной типа long можно присвоить дробное число?
- Код:
OCR1A = (uint16_t)((((uint32_t)period * 257)/4) + 5600);
Ср окт 06, 2021 21:26:03
вообще-то, тебе не нужно 32-битное число.
ты умножаешь однобайтное на однобайтное и получаешь двухбайтное число, то есть 16-битное.
поэтому тебе достаточно написать
(uint16_t)period
это нужно, чтобы при умножении тебе не обрезали результат до одного байта.
и после деления на 4 результат останется двухбайтным.
и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);
Ср окт 06, 2021 21:40:46
Starichok51, понял. Спасибо. А если совершить арифметическую операцию с числом типа long и float, какой тип будет в результате?
Добавлено after 1 minute 58 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
И соответственно, если мы перемножаем двухбайтные переменные, то в результате получим четырехбайтное число?
Добавлено after 2 minutes 32 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Все... понял )) Вопрос снимается. Опять до глюков в коде ковырялся ))
Ср окт 06, 2021 21:43:27
long придется приводить к float, и в результате получишь float.
а если тебе вдруг понадобится этот float запихнуть в регистр, например, в OCR1A, то тебе опять придется приводить это число к целому типу uint16_t.
поэтому тебе тут float ни с какой стороны не нужен. точность он тебе не повысит, так как при приведении к целому числу дробная часть все равно потеряется.
Чт окт 07, 2021 11:47:41
и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);
Еще интересный момент. Умножение и деление в СИ имеют один и тот же приоритет, а значит будет выполнена первой та операция, которая находится левее (операции будут выполняться слева на право)? В примере выше сначала будет выполнено умножение, потом деление и в конце сложение - так как оно имеет более низкий приоритет. Все правильно?
Добавлено after 8 minutes 24 seconds:Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.А еще я был очень удивлен, когда убрал из формулы приведение к типу float и объем занимаемой программой флеш памяти снизился с 13% до 5%
Чт окт 07, 2021 12:09:12
естественно, операции выполняются слева направо.
так библиотека "float" занимает огромное количество места в программной памяти.
но я еще упустил, что число 257 - двухбайтное (16 бит). поэтому, если 257 поставить на первое место, то возможно, что приведение типов вообще не понадобится.
попробуй записать вот так:
OCR1A = 257 * period / 4 + 5600;
я для МК на Си не пишу, но думаю, что такая запись должна работать правильно.
Чт окт 07, 2021 12:59:38
гуглите "суффиксы констант"
Чт окт 07, 2021 16:06:55
slav0n, спасибо за эту наводку.
поторкался я в проекте на Си.
константу 257 следует записать с суффиксом u
OCR1A = 257u * period / 4 + 5600;
тогда считается абсолютно правильно.
без этого суффикса получается неправильный результат.
Пт дек 10, 2021 11:57:26
Поправьте, пожалуйста, правильно ли я понял: в режиме любого ШИМ Т1 регистры OCR1x обновляются либо на вершине счета, либо на нижнем пределе? Причем, это касается не только регистра OCR1А, когда он используется для задания верхнего предела, но и относится к регистру OCR1B?? Т.е. меня интересует, можно ли моментально обновить регистр OCR1В в режиме ШИМ или только через двойную буферизацию?
Добавлено after 21 minute 48 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Вопрос снимается. В даташите написано, что двойная буферизация отключается только для режимов СТС и "нормального".
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.