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

Обсуждаем контроллеры компании Atmel.
Ответить
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

slav0n писал(а):

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

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

Сообщение Kalisnik »

slav0n, :beer:

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

Сообщение slav0n »

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

Добавлено after 3 minutes 34 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
доказательства?
ohmycode!
primuss3.com
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

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

Сообщение slav0n »

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

Сообщение Kalisnik »

Мне вот один момент не понятен. Допустим имеем переменную period = 100. При делении ее на 257 получаем число с плавающей запятой (float). Тип данных uint32_t это тот же long - целое длинное число. Почему написав uint32_t мы имеем такой же эффект, как если бы написали float? Переменной типа long можно присвоить дробное число?

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

OCR1A = (uint16_t)((((uint32_t)period * 257)/4) + 5600);
Реклама
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

вообще-то, тебе не нужно 32-битное число.
ты умножаешь однобайтное на однобайтное и получаешь двухбайтное число, то есть 16-битное.
поэтому тебе достаточно написать
(uint16_t)period
это нужно, чтобы при умножении тебе не обрезали результат до одного байта.
и после деления на 4 результат останется двухбайтным.
и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

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

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

Добавлено after 2 minutes 32 seconds:
Re: Atmega8, ШИМ - низкий уровень на выводе после остановки ШИМ.
Все... понял )) Вопрос снимается. Опять до глюков в коде ковырялся ))
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

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

Сообщение Kalisnik »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4101927#p4101927"]и когда ты к двухбайтному результату прибавляешь 5600, уже не надо делать еще одно приведение типов. то есть, достаточно записать
OCR1A = (uint16_t)period * 257 / 4 + 5600);[/uquote]

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

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

Сообщение Starichok51 »

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

Сообщение slav0n »

гуглите "суффиксы констант"
ohmycode!
primuss3.com
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 19097
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

slav0n, спасибо за эту наводку.
поторкался я в проекте на Си.
константу 257 следует записать с суффиксом u
OCR1A = 257u * period / 4 + 5600;
тогда считается абсолютно правильно.
без этого суффикса получается неправильный результат.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Сообщение Kalisnik »

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

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

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