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

 
 
> Максимальное разрешение многоканального программного ШИМ на 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
Ответов
ReAl
сообщение Apr 2 2009, 11:06
Сообщение #2


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

Группа: Свой
Сообщений: 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
Сообщение #3


Гуру
******

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



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

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 12:19
Рейтинг@Mail.ru


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