реклама на сайте
подробности

 
 
> Максимальное разрешение многоканального программного ШИМ на STM32, Проверьте мои измышления, плз
Dog Pawlowa
сообщение Apr 2 2009, 09:52
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



N 16 каналов
F Частота 400 Гц
n Количество градаций 1000
f Частота микроконтроллера 72 MHz
p Ресурсы времени на обслуживание ШИМ 50%

T Период прерывания обслуживания ШИМ = (1/(F*n)) = 1/(400*1000) = 2,5 мкс
Время прерывания 2,5 *50/100 = 1,25 мкс.
Допустимое количество команд 72*1,25= 90

Делаем тупо 16 раз:

if (count==pwm[NUM]) PORT->BSRR=PIN

На каждый канал тратится шесть команд, итого 96 команд плюс инкремент-пролог-эпилог.
Много. Плюс джиттер - отдельный вопрос.

Переделываем на предварительное формирование слова для записи в порт, и потом три записи этих байтов
4 команды на канал итого 64 плюс чистка и запись в три порта 11 команд всего 75.
Чуть лучше.

Какие еще варианты могут быть? (кроме снижения требований, конечно )

Сдвиговый регистр на SPI с записью по DMA? Что-то еще?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
etoja
сообщение Apr 2 2009, 09:57
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



В LPC2138 формирование ШИМ происходит аппаратно, но 16 каналов там не будет.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 2 2009, 11:06
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Попробуй нечто в таком духе:
Код
typedef struct {
    int count;
    unsigned mask;
} pwmchan_t;

pwmchan_t pwm_array[2][17];
int current_array;
int count;
unsigned mask;
    
    // прерывание

    // Вывести (приготовленную на прошлом заходе) маску в порт
    // Это минимизация джиттера
    PORT = mask;
    if( ++count == PERIOD) {
        count = 0;
        mask = 0;
        pwmptr = pwm_array[current_array];
    } else {
        while( count == pwmptr->count ) {    // тут было правильно, но ГЛУПО
            mask |= pwmptr->mask;        // видать, послобеденная полудрёма не дала
            ++pwmptr;                // нормально добавить обработку нескольких одинаковых
        }
    }

В массиве содержатся отсортированные по возрастанию count записи, при изменении
скважности какого-от канала массив пересортировывается во второй копии и делается
замена индекса current_array с 0 на 1 и назад
При желании можно замену current_array привязывать к окончанию периода - менять
current_array_next, а в обработчике прерывания по достижению PERIOD делать
current_array = current_array_next
Главное, чтобы обработчик успевал при самом худшем раскладе -
когда все каналы станут на одну скважность - уложиться в период (а не в половину).
Ну а загрузка процессора будет низкая, гораздо ниже половины (основная масса прерываний
будет отрабатывать быстро).


Да, совсем забыл. записей в массиве 17 для того, чтобы в последней записи держать такое значение .count, что оно не будет достигнуто счётчиком. Это чтобы if( count == pwmptr->count ) и аналогичное в while работало и как ограничитель инкремента указателя


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Apr 2 2009, 12:52
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(ReAl @ Apr 2 2009, 14:06) *
Попробуй нечто в таком духе:

Спасибо, идею понял.
Общее высвобождение ресурсов на порядок, но с худшим случаем нужно разбираться в симуляторе детально, что же там получается.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 2 2009, 15:30
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
Что-то еще?

Взять какую-нибудь тиню2313, в ней реализовать ШИМы на asm'е. (50 тактов на период, возможно хватит, на 8 каналов так точно хватит).
Передавать ей параметры ШИМа с частотой 400Гц, и пусть генерит с 99% ресурсом под ШИМ.
расширять будет легко, вдруг понадобится не 16, а 64-128 каналов, подключите еще n тинь и готово.
А STM пусть отдыхает smile.gif
Go to the top of the page
 
+Quote Post
KRS
сообщение Apr 2 2009, 17:09
Сообщение #6


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



у LPC29xx есть четрые 6 канальных PWM
Go to the top of the page
 
+Quote Post
Rst7
сообщение Apr 2 2009, 18:06
Сообщение #7


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



А я не понял, заранее заготовленную колбасу размером 2000 байт (1000 полуслов) уже некуда положить? Зато времени свободного будет валом.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 2 2009, 18:15
Сообщение #8


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Тьху, ну да. А можно и не всю колбасу, а только несколько нужных кусочков - т.е., как у меня, только после сортировки слить .mask с одинаковым [i].count[/i] и туда же добавить предыдущее .mask, укоротив рабочую часть массива и записать ограничитель в следующем элементе в .count. Максимальная длина будет такая, что влезет в данный массив, а (в исправленном) while(count == pwmptr->count) заменить назад на if без while - тело обработчика будет выполняться ощутимо дольше, чем для 2000-байтовой колбасы, но "худшего случая" просто не будет, тело будет всё равно достаточно быстрым.
Ну и будет не mask |= pwmptr->mask а mask = pwmptr->mask (см. про "добавить предыдущее"), ещё может малость сэкономит.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 11:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01413 секунд с 7
ELECTRONIX ©2004-2016