ручной ШИМ

Привет, All !

Есть мега32, соответствующий гцц, 50 раз в секунду надо делать примерно следующее:

PORTA = 0xFF; PORTB = 0x3F; for ( uint8_t i = 0; i < MAX_LIMIT; i++ ) { if ( lim [0] > 0) { lim [0]--; }else{ PORTA &= 0xFF - 1; } if ( lim [1] > 0) { lim [1]--; }else{ PORTA &= 0xFF - 4; } if ( lim [2] > 0) { lim [0]--; }else{ PORTB &= 0xFF - 1; } ... // всего 14 каналов }

то есть, считаем время, выдаем 14 ШИМов на 14 ног. ГЦЦ пытается этот код соптимизировать и времена выполнения разных веток становятся неодинаковыми, что приводит к паразитному изменению одних ШИМов в момент окончания работы других ШИМов. Соответственно, хочется (переписать такой фрагмент на ассемблере) "чтоб времена выполнения всех веток было одинаково".

Так вот, что лучше, ассемблерная вставка, или отдельный ассемблерный файл с отдельной функцией? Что читать про ассемблерные вставки у гцц в таком экзотическом случае?

. С уважением, Hикита. icq:240059686, lj-user:nicka_startcev ... "чч часов мм минут. Торпедный катер выполз на берег и скрылся в лесу"

Reply to
Nickita A Startcev
Loading thread data ...

примени буферизацию - вычисляй в переменной и потом выдавай весь байт в порт.

ассемблерная вставка

info gcc ассемблер то практически стандартный - тебе надо изучить constrains.

Reply to
Arcady Schekochikhin

а ты уверен что тут именно оптимизатор gcc все портит?

у тебя получается по каждому каналу две ветки if и else. глянул я в листинг того что генерится, так вот PORTB &= 0xFF - 1; у него ложится в одну инструкцию cbi 56-0x20,0 а вот декремент с индексацией (в случае если lim байт) в 4 инструкции. то есть когда добежит до 14 канала накопится случайная ошибка в диапазоне 0 - 3*13 == 0 - 39 инструкций. ветки по определению разные, оптимизатор тут не при чем :)

может дело в алгиритме? вон Орлову тут недавно аналогичную ошибку с фронтами поправили (он еще слюнями исходил по этому поводу).

суть в следующем: если у нас не получается пройти по всем веткам за одинаковое время, то мы вводим буффер на выдачу сигналов и запись производим в него а не прямо в порт. а вот буффер в порт выпихиваем в начале (идеально) или конце алгоритма. тогда фронты "встанут" привязанно к итерациям цикла.

хотя я не очень понял твое описание.

50 раз в секунду выдаешь по 1 импульсу ШИМ? lim[i] вначале содержит значение, определяющее скважность i-го канала? так?

NAS> Есть мега32, соответствующий гцц, 50 раз в секунду надо делать примерно NAS> следующее: NAS>

NAS> PORTA = 0xFF; NAS> PORTB = 0x3F; NAS> for ( uint8_t i = 0; i < MAX_LIMIT; i++ ) я не понял, MAX_LIMIT тут что означает? период ШИМ?

NAS> { NAS> if ( lim [0] > 0) NAS> { NAS> lim [0]--; NAS> }else{ NAS> PORTA &= 0xFF - 1; NAS> } NAS> if ( lim [1] > 0) { NAS> lim [1]--; }else{ NAS> PORTA &= 0xFF - 4; NAS> } NAS> if ( lim [2] > 0) { NAS> lim [0]--; }else{ NAS> PORTB &= 0xFF - 1; NAS> } NAS> ... NAS> // всего 14 каналов а что бы эти 14 каналов в один цикл не свернуть? ;)

NAS> } NAS>

NAS> то есть, считаем время, выдаем 14 ШИМов на 14 ног. NAS> ГЦЦ пытается этот код соптимизировать и времена выполнения разных веток NAS> становятся неодинаковыми, что приводит к паразитному изменению одних ШИМов NAS> в момент окончания работы других ШИМов. Соответственно, хочется NAS> (переписать такой фрагмент на ассемблере) "чтоб времена выполнения всех NAS> веток было одинаково". NAS>

NAS> Так вот, что лучше, ассемблерная вставка, или отдельный ассемблерный файл NAS> с отдельной функцией? лучше подумать и написать на С :)

NAS> Что читать про ассемблерные вставки у гцц в таком экзотическом случае?

Reply to
Dmitry E. Oboukhov

Привет Nickita!

29 Oct 06 13:34, Nickita A Startcev писал All:

NS> Так вот, что лучше, ассемблерная вставка, или отдельный ассемблерный NS> файл с отдельной функцией?

По-моему лучше вынести в ассемблерный модуль.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Закрой свой Ворд!

Reply to
Alex Mogilnikov
*** Ответ на письмо из carbonArea (carbonArea).

Привет, Dmitry !

01 Nov 06 , 11:00 Dmitry E. Oboukhov писал к Nickita A Startcev:

DO> а ты уверен что тут именно оптимизатор gcc все портит?

ну, по крайней мере именно он переставляет инструкции и генерирует код, который в разных ветках выполняется разное время.

DO> у тебя получается по каждому каналу две ветки DO> if и else.

Да. либо "счет времени" либо обнуление/пропуск.

DO> глянул я в листинг того что генерится, так вот DO> PORTB &= 0xFF - 1; у него ложится в одну инструкцию DO> cbi 56-0x20,0 а вот декремент с индексацией (в случае если lim байт) в DO> 4 инструкции. то есть когда добежит до 14 канала накопится случайная DO> ошибка в диапазоне 0 - 3*13 == 0 - 39 инструкций. ветки по определению DO> разные, оптимизатор тут не при чем :)

Примерно так, но хочется делать их одинаковыми.

DO> может дело в алгиритме?

А в чем же еще? Раскладка такая: 16 МГц кварц. Хочется примерно 200 градаций на 14 каналов на 1 мс

1 мс = 16 000 операций, примерно 5 операций на градацию*канал.

DO> вон Орлову тут недавно аналогичную ошибку DO> с фронтами поправили (он еще слюнями исходил по этому поводу).

Hе видел. Фидошка как-то странно ходит в последнее время.

DO> суть в следующем: если у нас не получается пройти по всем веткам за DO> одинаковое время, то мы вводим буффер на выдачу сигналов и запись DO> производим в него а не прямо в порт. DO> а вот буффер в порт выпихиваем в начале (идеально) или конце DO> алгоритма. тогда фронты "встанут" привязанно к итерациям цикла.

Лишние операции, лишние плавающие задержки.

DO> хотя я не очень понял твое описание. DO> 50 раз в секунду выдаешь по 1 импульсу ШИМ? lim[i] вначале содержит DO> значение, определяющее скважность i-го канала? так?

50 раз в секунду выдаю 14 каналов шим. Высокий уровень ШИМ должен держаться от 1 мс (крайнелевое положение исполняющего усройства) до 2мс (крайнеправое). Весь диапазон хочется побить на примерно сотню-две градаций.

NAS>> PORTA = 0xFF; NAS>> PORTB = 0x3F; NAS>> for ( uint8_t i = 0; i < MAX_LIMIT; i++ ) DO> я не понял, MAX_LIMIT тут что означает? период ШИМ?

Максимальная длительность единицы; максимальное значение елемента массива lim.

DO> а что бы эти 14 каналов в один цикл не свернуть? ;)

Порты разные, придется в цикле смотреть номер канала и выбирать PORTB иль PORTC

NAS>> Так вот, что лучше, ассемблерная вставка, или отдельный NAS>> ассемблерный файл с отдельной функцией? DO> лучше подумать и написать на С :)

;)

. С уважением, Hикита. ... И физиономия, прошу заметить, глумливая.

Reply to
Nickita A Startcev

 X-RFC2646: Format=Flowed; Original X-Virus-Scanned: amavisd-new at bezeqint.net

Hello, Dmitry E. Oboukhov! You wrote in conference fido7.ru.embedded to Nickita A Startcev on Wed, 01 Nov 2006 11:00:28 +0300:

DEO> может дело в алгиритме? вон Орлову тут недавно аналогичную ошибку с DEO> фронтами поправили (он еще слюнями исходил по этому поводу).

Ошибка там только в твоем воображении, недоумок.

dima

formatting link

Reply to
Dmitry Orlov

DO>> суть в следующем: если у нас не получается пройти по всем веткам за DO>> одинаковое время, то мы вводим буффер на выдачу сигналов и запись DO>> производим в него а не прямо в порт. DO>> а вот буффер в порт выпихиваем в начале (идеально) или конце DO>> алгоритма. тогда фронты "встанут" привязанно к итерациям цикла. NAS>

NAS> Лишние операции, лишние плавающие задержки. нет, лишних операций всего на две асмовских инструкции

там где PORTA/PORTB инициализируется проинициализируй две переменные bufa и bufb

PORTA = bufa = 0xFF; PORTB = bufb = 0x3F; for ( uint8_t i = 0; i < MAX_LIMIT; i++ ) { PORTA=bufa; PORTB=bufb; ... if ( lim [0] > 0) { lim [0]--; }else{ bufa &= 0xFF - 1; } ...

фронты всех каналов будут уже гулять _одинаковым_ образом, но продолжат гулять, так как у тебя получается что точность установки ШИМ от того что у тебя в цикле написано зависит (и по каким веткам пройдет)

DO>> хотя я не очень понял твое описание. DO>> 50 раз в секунду выдаешь по 1 импульсу ШИМ? lim[i] вначале содержит DO>> значение, определяющее скважность i-го канала? так? NAS>

NAS> 50 раз в секунду выдаю 14 каналов шим. NAS> Высокий уровень ШИМ должен держаться от 1 мс (крайнелевое положение NAS> исполняющего усройства) до 2мс (крайнеправое). NAS> Весь диапазон хочется побить на примерно сотню-две градаций.

1мс - это на 8Мгц - 8000 инструкций

канал у тебя по моему листингу получается в 5+4+1=10 инструкций укладывается

14 каналов соответственно 140 8000/140=57 сотня градаций только на 16МГц выйдет, в упор тут уже пора совсем на АСМ уходить :(

NAS>>> PORTA = 0xFF; NAS>>> PORTB = 0x3F; NAS>>> for ( uint8_t i = 0; i < MAX_LIMIT; i++ ) DO>> я не понял, MAX_LIMIT тут что означает? период ШИМ? NAS>

NAS> Максимальная длительность единицы; NAS> максимальное значение елемента массива lim. там абсолютные числа какие? в районе 60 (8МГц) -- 120 (16МГц)?

DO>> а что бы эти 14 каналов в один цикл не свернуть? ;) NAS>

NAS> Порты разные, придется в цикле смотреть номер канала и выбирать PORTB иль NAS> PORTC а собрать все выходные данные в один word а потом двумя командами выдать в порты

NAS>>> Так вот, что лучше, ассемблерная вставка, или отдельный NAS>>> ассемблерный файл с отдельной функцией? DO>> лучше подумать и написать на С :) NAS>

NAS> ;)

в текущей реализации получается что если запихать во все 14 каналов большую скважность, то частота ШИМ упадет (вернее ширина импульсов вырастет)

Reply to
Dmitry E. Oboukhov

DEO>> он еще слюнями исходил по этому поводу. DO> Ошибка там только в твоем воображении, недоумок. и продолжает исходить

Reply to
Dmitry E. Oboukhov
*** Ответ на письмо из carbonArea (carbonArea).

Привет, Dmitry !

01 Nov 06 , 15:22 Dmitry E. Oboukhov писал к Nickita A Startcev:

DO> там где PORTA/PORTB инициализируется проинициализируй две переменные DO> bufa и bufb

DO> фронты всех каналов будут уже гулять _одинаковым_ образом,

вот этого гуляния и надо избежать. Синхронное подергивание всех исполняющих устройств ничем не лучше асинхронного.

DO> но DO> продолжат гулять, так как у тебя получается что точность установки ШИМ DO> от того что у тебя в цикле написано зависит (и по каким веткам DO> пройдет)

DO> канал у тебя по моему листингу получается в 5+4+1=10 инструкций DO> укладывается DO> 14 каналов соответственно 140 DO> 8000/140=57 DO> сотня градаций только на 16МГц выйдет, в упор DO> тут уже пора совсем на АСМ уходить :(

вот-вот. :\

NAS>> Максимальная длительность единицы; NAS>> максимальное значение елемента массива lim. DO> там абсолютные числа какие? DO> в районе 60 (8МГц) -- 120 (16МГц)?

кварц 16.000 мгц, задержки надо 1-2 мс (или 1 + [0..1]), абсолютные значения соответственно от 0 до примерно 255.

DO>>> а что бы эти 14 каналов в один цикл не свернуть? ;) NAS>>

NAS>> Порты разные, придется в цикле смотреть номер канала и выбирать NAS>> PORTB иль PORTC DO> а собрать все выходные данные в один word а потом двумя командами DO> выдать в порты

А смысл? ВСе равно гулять будет.

DO> в текущей реализации получается что если запихать во все 14 каналов DO> большую скважность, то частота ШИМ упадет (вернее ширина импульсов DO> вырастет)

Грубо говоря, раз в 20 мс у меня прерывание "всем старт", через 1 мс прерывание "начинаем считать ШИМ", еще через 1-17мс остальные прерывания.

. С уважением, Hикита. ... Толст, лыс и злопамятен

Reply to
Nickita A Startcev

 X-RFC2646: Format=Flowed; Original X-Virus-Scanned: amavisd-new at bezeqint.net

Hello, Dmitry E. Oboukhov! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Wed, 01 Nov

2006 15:25:10 +0300:

DEO>>> он еще слюнями исходил по этому поводу. DO>> Ошибка там только в твоем воображении, недоумок. DEO> и продолжает исходить

Ты же любишь чужие сопли и слюни жевать, почему не уважить?

dima

formatting link

Reply to
Dmitry Orlov

Пpивет, Nickita!

*** 01 Nov 06 13:30, Nickita A Startcev wrote to Dmitry E. Oboukhov:

NS> Хочется примерно 200 градаций на 14 каналов на 1 мс NS> 1 мс = 16 000 операций, примерно 5 операций на градацию*канал.

Да, кстати, реально нетрудно сделать два такта на канал (две команды). Hу, чуть больше на организацию цикла (по позициям PWM, обработка каналов, естественно, линейным участком кода). Так что легко и 256 позиций, и вдвое больше каналов, и даже при меньшей тактовой. Прояви чуток фантазии...

с уважением Владислав

Reply to
Vladislav Baliasov

Привет, Vladislav !

02 Nov 06 , 19:52 Vladislav Baliasov писал к Nickita A Startcev:

NS>> Хочется примерно 200 градаций на 14 каналов на 1 мс NS>> 1 мс = 16 000 операций, примерно 5 операций на градацию*канал.

VB> Да, кстати, реально нетрудно сделать два такта на канал (две команды). VB> Hу, чуть больше на организацию цикла (по позициям PWM, обработка VB> каналов, естественно, линейным участком кода). Так что легко и 256 VB> позиций, и вдвое больше каналов, и даже при меньшей тактовой. Прояви VB> чуток фантазии...

Реально сделать порядка 5 тактов на 8 каналов, но с предвычислениями.

. С уважением, Hикита. icq:240059686, lj-user:nicka_startcev ... А как выглядит щенок сфинкса?

Reply to
Nickita A Startcev

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.