Как стать автором
Обновить

Комментарии 7

Спасибо. А код этого урока можно где-нибудь скачать?
Кода не осталось… Пришлось компоновать из статьи. Пока компоновал — удалил код для следующей статьи… Ну да ладно. Все к лучшему. Переписал. Статью дополнил. Пишите об успехах или вопросах, поясню.
Я всё же не понимаю основной принцип действия этой системы. Есть массив данных для ЦАП (значения синусоиды), 100 точек. Есть контроллер ПДП и два таймера. Есть массив структур для параметров для ПДП (почему их 64?). Одна из структур «нацелена» на конец массива синусоиды, вторая-на его половину. Таймер1 «магически» (в железе) связан с каналом ПДП, и заставляет ДМА (по одному элементу массива синуса за раз?) передавать данные в ЦАП без каких-либо явных прерываний. Таймер2 генерирует прерывание каждые четверть периода синуса, в прерывании смотрим, прошли ли мы половину периода, и если прошли, переключаем ПДП на альтернативную управляющую структуру. Правильно?
Есть массив структур для параметров для ПДП (почему их 64?).

Каждый канал имеет первичную и альтеранативную структуру (того две). Каналов DMA имеет 32 (0..31). На каждый канал по 2 структуры = 64 структуры. Мы используем всего 1 канал и можем оставить только 2 структуры. Остальную память можно использовать по собственному назначению. НО. Каждая структура имеет свой фиксированный адрес со смещением в 1024. К примеру для канала «0» первичная структура может размещаться в 0x20000000 или 0x20000200, 0x20000400 и т.д… Нельзя разместить структуру для третьего канала (если мы используем только третий канал) по адресу 0x20000000. Он обязательно должен быть 0x20000030, или 0x20000230, или 0x20000430 и т.д.
Таймер1 «магически» (в железе) связан с каналом ПДП, и заставляет ДМА (по одному элементу массива синуса за раз?)

Таймер 1 железно (в чипе) связан с DMA. Когда таймер генерирует сигнал — он «производит процедуру арбитража». Иначе говоря, разрешает передачу. В структуре мы указали, что контроллер должен ждать этого разрешения после каждой передачи. Если бы мы хотели передавать, к примеру, по 128 значений, то в структуре нужно было бы указать «производить арбитраж через каждые 128 передач». Тогда бы за один вызов таймера мы бы передавали 128 значений.
Таймер2 генерирует прерывание каждые четверть периода синуса, в прерывании смотрим, прошли ли мы половину периода, и если прошли, переключаем ПДП на альтернативную управляющую структуру.

Не только половину. Мы проверяем, передал ли DMA первую структуру и хотя бы один элемент из следующей. Потому что есть риск, что мы проверим структуру как раз в тот момент, когда ПДП передал последней элемент структуры, но еще не попытался передать элемент из следующей. Тогда мы «восстановим» структуру и в этот же момент ДМА вместе перехода к новой структуре начнет заново передавать все из восстановленной.
Вроде понял. А таймер1 и передача по одному элементу нужна для того, чтобы управляя периодом таймера1 управлять выходной частотой, да? Я к тому, что можно было, наверное, настроить на передачу всего массива точек сразу, и только таймером2 контролировать момент, когда пора запускать выдачу следующего периода? Но тогда частота синуса была бы жестко привязана к тактовой частоте МК…
А таймер1 и передача по одному элементу нужна для того, чтобы управляя периодом таймера1 управлять выходной частотой, да?

Да, для этого.
Я к тому, что можно было, наверное, настроить на передачу всего массива точек сразу, и только таймером2 контролировать момент, когда пора запускать выдачу следующего периода? Но тогда частота синуса была бы жестко привязана к тактовой частоте МК…

Да, технически можно обойтись одним таймером, если сгенерировать синусоиду привязанной к частоте. Но это бред… В следующей статье (то, о чем говорю, уже дописано) мы сделаем небольшую функцию, которая будет меняя частоту таймера играть MIDI мелодию (одно голосую). А после покажу способ (сейчас еще выбираю, как будет проще), как сделать выдачу многоголосой музыки без изменения настроек таймера.
Оффтоп, конечно. Но может кто ткнет носом, как в СС2538 на том-же ядре таймером пинать пдп?..
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории