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

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

Вт окт 05, 2021 16:44:35

slav0n писал(а):
Код:
OCR1A = period * 257UL / 4 + 5600;
Хоть бы проверил, ответ 5600.

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

Вт окт 05, 2021 16:50:36

slav0n, :beer:

Добавлено after 5 minutes 15 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Dimon456, да вроде он правильно все написал. В симуляторе правильное число.
Последний раз редактировалось Kalisnik Вт окт 05, 2021 16:51:40, всего редактировалось 1 раз.

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

Вт окт 05, 2021 16:54:33

Dimon456 писал(а):ответ 5600
докази?

Добавлено after 3 minutes 34 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
доказательства?

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

Вт окт 05, 2021 16:57:18

Уговорил, все равно код asm одинаковый получается, как в моем так и в твоем случае.

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

Вт окт 05, 2021 17:01:37

код прозрачней

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

Ср окт 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);

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

Ср окт 06, 2021 21:26:03

вообще-то, тебе не нужно 32-битное число.
ты умножаешь однобайтное на однобайтное и получаешь двухбайтное число, то есть 16-битное.
поэтому тебе достаточно написать
(uint16_t)period
это нужно, чтобы при умножении тебе не обрезали результат до одного байта.
и после деления на 4 результат останется двухбайтным.
и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);

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

Ср окт 06, 2021 21:40:46

Starichok51, понял. Спасибо. А если совершить арифметическую операцию с числом типа long и float, какой тип будет в результате?

Добавлено after 1 minute 58 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
И соответственно, если мы перемножаем двухбайтные переменные, то в результате получим четырехбайтное число?

Добавлено after 2 minutes 32 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Все... понял )) Вопрос снимается. Опять до глюков в коде ковырялся ))

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

Ср окт 06, 2021 21:43:27

long придется приводить к float, и в результате получишь float.
а если тебе вдруг понадобится этот float запихнуть в регистр, например, в OCR1A, то тебе опять придется приводить это число к целому типу uint16_t.
поэтому тебе тут float ни с какой стороны не нужен. точность он тебе не повысит, так как при приведении к целому числу дробная часть все равно потеряется.

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

Чт окт 07, 2021 11:47:41

и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);


Еще интересный момент. Умножение и деление в СИ имеют один и тот же приоритет, а значит будет выполнена первой та операция, которая находится левее (операции будут выполняться слева на право)? В примере выше сначала будет выполнено умножение, потом деление и в конце сложение - так как оно имеет более низкий приоритет. Все правильно?

Добавлено after 8 minutes 24 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
А еще я был очень удивлен, когда убрал из формулы приведение к типу float и объем занимаемой программой флеш памяти снизился с 13% до 5% :shock:

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

Чт окт 07, 2021 12:09:12

естественно, операции выполняются слева направо.
так библиотека "float" занимает огромное количество места в программной памяти.
но я еще упустил, что число 257 - двухбайтное (16 бит). поэтому, если 257 поставить на первое место, то возможно, что приведение типов вообще не понадобится.
попробуй записать вот так:
OCR1A = 257 * period / 4 + 5600;
я для МК на Си не пишу, но думаю, что такая запись должна работать правильно.

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

Чт окт 07, 2021 12:59:38

гуглите "суффиксы констант"

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

Чт окт 07, 2021 16:06:55

slav0n, спасибо за эту наводку.
поторкался я в проекте на Си.
константу 257 следует записать с суффиксом u
OCR1A = 257u * period / 4 + 5600;
тогда считается абсолютно правильно.
без этого суффикса получается неправильный результат.

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

Пт дек 10, 2021 11:57:26

Поправьте, пожалуйста, правильно ли я понял: в режиме любого ШИМ Т1 регистры OCR1x обновляются либо на вершине счета, либо на нижнем пределе? Причем, это касается не только регистра OCR1А, когда он используется для задания верхнего предела, но и относится к регистру OCR1B?? Т.е. меня интересует, можно ли моментально обновить регистр OCR1В в режиме ШИМ или только через двойную буферизацию?

Добавлено after 21 minute 48 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Вопрос снимается. В даташите написано, что двойная буферизация отключается только для режимов СТС и "нормального".
Ответить