п.с. камень - stm32f407vet6
помогите с алгоритмом для DMA и TIM на STM32
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
здравствуйте. у меня такая задача: генерировать 2 периода скважности PWM-генератора используя DMA и буфер из байтов. причем 3 подряд идущих байта это будущий цвет на светодиоде, каждая логическая "единица" в бите буфера с цветами должна на выходе PWM-генератора иметь определенную скважность, а каждый "ноль" - другую скважность. предложите пожалуйста лучший по быстродействию и памяти алгоритм работы чтобы по минимуму загрузить CPU (собираюсь использовать DMA и буферизацию, если DMA закончил предыдущую пересылку, то CPU ждет 50 микросекунд и снова запускает DMA и таймеры уже с другим подготовленным буфером). если просто цвет (3 байта) превращать в блок из 24 х 16 бит для пересылки генератору, то это будет отнимать процессорное время и отжирать много памяти, хочется чтобы это выполнялось "на лету". заранее всем спасибо.
п.с. камень - stm32f407vet6
п.с. камень - stm32f407vet6
- Реклама
Огласите таки условия задачи. Насколько часто меняются битики?avmartugin писал(а):здравствуйте. у меня такая задача: генерировать 2 периода скважности PWM-генератора используя DMA и буфер из байтов.
Может быть имеет смысл посчитать для всего байта среднюю скважность и сказать таймеру ее генерировать?
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
каждый светодиод требует 24 бита на цвет (усреднять ниче не получится как бы не хотелось). каждый этот бит должен быть послан на частоте 800 КГц цепочке светодиодов связанных последовательно. задача: получить максимально возможное быстродействие, т.к. цепочек из светодиодов может быть много (чуть меньше чем таймеров в системе) это для экономии, чтобы не городить микрух много, а взять одну и она бы рулила многими светодиодами. кроме этой задачи микруха должна выполнять и сложный код, поэтому максимизировать использование инструментов, которые позволяют обойти сам проц в работе.
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
https://github.com/x893/stm-ledstrip
вот такой проект, после беглого изучения понятно что CPU напрягать эта библиотека будет довольно сильно. вот я и хочу обойти ее изъяны. что можно еще аппаратно здесь улучшить?
вот такой проект, после беглого изучения понятно что CPU напрягать эта библиотека будет довольно сильно. вот я и хочу обойти ее изъяны. что можно еще аппаратно здесь улучшить?
Все таки как звучит задача? Есть N светодиодных лент, и надо управлять их яркостью? Или что-то другое? Сколько градаций яркости планируется.avmartugin писал(а):каждый светодиод требует 24 бита на цвет
Я просто пытаюсь понять, почему нельзя воспользоваться хардварным PWM, которое в таймерах есть. Оно там хорошее с изменяемой скважностью.
Частота приличная, излучение будет немаленькое, если провода будут не 5 см. Чтото плохо представляю схему, которую вы хотите сделать.avmartugin писал(а):каждый этот бит должен быть послан на частоте 800 КГц
- Реклама
Посмотрел на исходники, теперь задача таки понятнаavmartugin писал(а):https://github.com/x893/stm-ledstrip
вот такой проект, после беглого изучения понятно что CPU напрягать эта библиотека будет довольно сильно. вот я и хочу обойти ее изъяны. что можно еще аппаратно здесь улучшить?
Ключевое слово WS2812
Лично мое мнение - оптимальнее, чем в той библиотеке не сделать.
color2pwm правда не особо быстрая, а в остальном там все хорошо, и DMA используется.
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
есть ли способ для STM запихивать в таймер значение скважности исходя из значения бита в массиве? или если ли способ задать значение скважности как функцию от значения ячейки памяти?
http://www.micromouseonline.com/2013/01 ... z2e5C7ieOP
ссылка про bit banding, как думаете это поможет оптимизировать color2pwm функцию?
http://www.micromouseonline.com/2013/01 ... z2e5C7ieOP
ссылка про bit banding, как думаете это поможет оптимизировать color2pwm функцию?
Можно попытаться использовать spi. Кодировать в обном байте SPI 2 бита цвета. Предположительно будет быстрее чем через таймер. Недостаток - нужно подбирать частоту кварца что бы SPI работало с нужными частотами.
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
spi мало в системе, всего 3. а мне нужно 10-12 таких каналов передачи чтобы уж микруху по полной использовать и не городить гирлянду из микрух
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
avmartugin выплевывать буфер через DMA, DMA пинать таймером .
Итого до 16 каналов . Единственное памяти уйдет много ...
uint16_t buf[240] - где то так , плюс где то хранить уже обработанные массивы для эффектов
Итого до 16 каналов . Единственное памяти уйдет много ...
uint16_t buf[240] - где то так , плюс где то хранить уже обработанные массивы для эффектов
Последний раз редактировалось dosikus Пт сен 06, 2013 12:27:26, всего редактировалось 1 раз.
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
нашел в итоге крутую возможность для портов STM32: GPIOx->ODR=0xFFFF - устанавливает все ножки порта в 1, GPIOx->ODR=0x0000 - в ноль, так что если научится при этом рулить скважностью этих ногодрыганий, то это и будет решением задачи. да и еще тут можно получить больше чем 10-12, может даже на 2 порта кидать данные. будет 32 канала вообще. памяти должно быть всего в 2 раза больше кушать чем объем данных для передачи. товарищи, хакеры, есть у кого идеи? : )
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
вот я и предлагаю скважностью рулить по времени, а не по значению скважности таймера для каждой ножки. при этом надо как-то эмулировать скважность сигнала, хотя вроде можно завести с 1 таймера все ноги в "1", потом прерывание от второго таймера часть ног в "0", а часть в единицу и далее все ноги в "0".
3 таймера и дма.
памяти нужно будет с такой схемой всего в 2 раза больше чем объем данных о цветах (учитываю буферизацию), т.е. на каждый светодиод по 24 бита. и кстати не надо будет при этом вычислять массив данных для скважности, тут и производительность подскочит.
3 таймера и дма.
памяти нужно будет с такой схемой всего в 2 раза больше чем объем данных о цветах (учитываю буферизацию), т.е. на каждый светодиод по 24 бита. и кстати не надо будет при этом вычислять массив данных для скважности, тут и производительность подскочит.
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
1 таймер и DMA и никаких прерываний . Вечером более детально обрисую , а пока здесь посмотри - с этого поста и далее http://kazus.ru/forums/showpost.php?p=6 ... count=3218avmartugin писал(а): 3 таймера и дма.
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
dosikus, ты предлагаешь создать массив из значений нужной скважности, запустить 1 таймер и прикрутив к нему DMA мы получим нужный сигнал на 1 ноге. множим этот принцип на нужное кол-во ног и получаем profit? это будет работать, да (я уже это попробовал). но такой подход отжирает кучу памяти (для каждого светодиода 24 х sizeof(uint16_t)) и необходимо значение каждого бита цвета превращать в значение скважности (хотя здесь очевидная оптимизация это создание таблицы значений скважности для 1 байта к примеру, тут мы потратим кучу флеш-памяти, но ее и так очень много. сэкономим процессорное время)
http://www.pjrc.com/teensy/td_libs_OctoWS2811.html
оригинальное решение этой задачи для процессоров freescale. как я понял они сразу 8 ног дрыгают по 2 таймерам и DMA. в разделе Technical Details есть картинки и описание:
The hardware events which trigger the DMA channels are a pair of PWM waveforms, corresponding to the WS2811 bit low and high waveforms. The rising edge (both PWM rise at the same moment) triggers channel #1, which copies a fixed byte (0xFF) to an I/O register which sets all 8 output bits, causing the WS2811 waveform to begin each bit. The first falling edge triggers DMA channel #2, which copies one byte of the actual frame buffer data to all 8 pins. The bits which are low transition to low at the correct time to create a zero bit to each WS2811 LED.
т.е. нужно так настроить DMA чтобы он реагировал на подъем/спад сигнала от нужных таймеров (PWM-генераторов) настроенных на заранее заданные скважности.
http://www.pjrc.com/teensy/td_libs_OctoWS2811.html
оригинальное решение этой задачи для процессоров freescale. как я понял они сразу 8 ног дрыгают по 2 таймерам и DMA. в разделе Technical Details есть картинки и описание:
The hardware events which trigger the DMA channels are a pair of PWM waveforms, corresponding to the WS2811 bit low and high waveforms. The rising edge (both PWM rise at the same moment) triggers channel #1, which copies a fixed byte (0xFF) to an I/O register which sets all 8 output bits, causing the WS2811 waveform to begin each bit. The first falling edge triggers DMA channel #2, which copies one byte of the actual frame buffer data to all 8 pins. The bits which are low transition to low at the correct time to create a zero bit to each WS2811 LED.
т.е. нужно так настроить DMA чтобы он реагировал на подъем/спад сигнала от нужных таймеров (PWM-генераторов) настроенных на заранее заданные скважности.
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
Памяти уйдет куча. Зато это полностью аппаратно, ядро не тревожим.avmartugin писал(а):dosikus, ты предлагаешь создать массив из значений нужной скважности, запустить 1 таймер и прикрутив к нему DMA мы получим нужный сигнал на 1 ноге. множим этот принцип на нужное кол-во ног и получаем profit? это будет работать, да (я уже это попробовал). но такой подход отжирает кучу памяти (для каждого светодиода 24 х sizeof(uint16_t)) и необходимо значение каждого бита цвета превращать в значение скважности (хотя здесь очевидная оптимизация это создание таблицы значений скважности для 1 байта к примеру, тут мы потратим кучу флеш-памяти, но ее и так очень много. сэкономим процессорное время)
Длтельность бита - 1,25uS . Разбиваем на 10 дискрет . То есть настраиваем таймер на пинки DMA длительностью 0.12 uS .
И того нам нужен буфер 10*24*(uint16_t)
Расписываем длительности согласно даташиту на WS2812.
Для первой посылки первого бита(посылаем единицу) - нулевые биты буфера ( первые 10 ) будут содержать :
1111110000
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
так не проще ли завести таймер и прикрутив к нему DMA получить все тоже самое и затраты памяти в 24*(uint16_t) на светодиод? или я что-то не понял? DMA на основе матрицы скважностей будет пихать для каждого бита информации одну из 2-х возможных значений скважности и таймер будет выдавать то, что нужно на выходе. все тоже аппаратно, в конце прерывание на окончание передачи информации.dosikus писал(а): Памяти уйдет куча. Зато это полностью аппаратно, ядро не тревожим.
Длтельность бита - 1,25uS . Разбиваем на 10 дискрет . То есть настраиваем таймер на пинки DMA длительностью 0.12 uS .
И того нам нужен буфер 10*24*(uint16_t)
Расписываем длительности согласно даташиту на WS2812.
Для первой посылки первого бита(посылаем единицу) - нулевые биты буфера ( первые 10 ) будут содержать :
1111110000
я про другую возможность хочу узнать. на камнях STM32F4 можно ли замутить вот что: на 2 ножки из порта к примеру GPIOA будем посылать 2 разных сигнала PWM (частота 800КГц, скважности соответствуют "0" и "1" которые понимает светодиод, т.е. 20% и 48% заполнение по документации к светодиоду), весь порт GPIOD будем использовать как каналы для управления светодиодами, итого 16 каналов. надо настроить DMA так, чтобы он сначала сработал на подъем с любого из 2-х портов GPIOA и передал в порт GPIOD все единицы, затем сработал на спад в PWM с 20% заполнением и передал в порт GPIOD заранее подготовленный в памяти массив со значением битов для всех 16-ти каналов со светодиодами, далее сработал на спад в PWM с 48% заполнением и передал в порт GPIOD все нули. вот это будет все полностью аппаратно и занимать минимальный объем памяти.
и еще, как DMA записывает данные в порт? может это сделать на основе возможности процов STM32 bit banding? есть ли в этом профит с точки зрения того что в этом случает запись в порт не будет сбита каким-то прерыванием?
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
Это только 1 канал . У меня все 16 сразу...avmartugin писал(а): так не проще ли завести таймер и прикрутив к нему DMA получить все тоже самое и затраты памяти в 24*(uint16_t) на светодиод? или я что-то не понял? DMA на основе матрицы скважностей будет пихать для каждого бита информации одну из 2-х возможных значений скважности и таймер будет выдавать то, что нужно на выходе. все тоже аппаратно, в конце прерывание на окончание передачи информации.
?
- Сообщения: 12
- Зарегистрирован: Ср авг 28, 2013 13:01:49
но дальше-то я предложил вариант с минимальными затратами памяти, полностью аппаратный и тоже на 16 каналовdosikus писал(а): Это только 1 канал . У меня все 16 сразу...


