EdigE
← ЛЕНТА

STM32G474 принимает 12-битный DAC только 32-битными DMA-записями

Таймер TIM6 выдаёт очередной триггер, DMA берёт следующий отсчёт синуса, а DAC должен без участия ядра обновить выход. Таблица из 64 значений занимает по 16 бит на отсчёт: полезных данных внутри каждого элемента всего 12. Настройка выглядит очевидно — HalfWord со стороны памяти и HalfWord со стороны периферии. На STM32G474 такая симметрия способна закончиться флагом DMA Transfer Error ещё до появления формы сигнала на выводе.

Поле на 12 бит, транзакция на 32

Регистр DAC_DHR12R1 действительно содержит 12-битное поле данных. Сам периферийный блок при этом подключён непосредственно к 32-битной AHB-шине и не принимает byte- или half-word-записи. Размер значения и размер шинной транзакции описывают разные уровни устройства: первый определяет, какие биты попадут в преобразователь, второй — какой цикл доступа разрешён регистровому интерфейсу.

DMA позволяет задать эти размеры независимо. Memory Data Alignment остаётся HalfWord, поэтому контроллер читает из массива очередной uint16_t и двигает адрес памяти на два байта. Peripheral Data Alignment устанавливается в Word: прочитанное значение расширяется до 32 бит и одной допустимой AHB-транзакцией попадает в DAC_DHR12R1. Младшие 12 бит становятся кодом преобразования, остальные биты регистра не меняют аналоговый результат.

У 32-битной шины есть второй смысл

RM0440 использует ту же ширину AHB для режима DMA double data. DAC хранит два последовательных 12-битных отсчёта, а один запрос DMA подготавливает их сразу для двух следующих внешних триггеров. Это снижает частоту DMA-запросов вдвое. Речь идёт о двух отсчётах одного канала; отдельный dual-DAC режим служит другой задаче — совместной загрузке двух каналов через объединённый регистр.

Даже правильная ширина доступа не гарантирует бесконечную скорость. Перед первым триггером программа должна заранее заполнить data holding register. Если новый внешний триггер приходит раньше, чем DMA подтвердил предыдущий запрос, запросы не образуют очередь: DAC выставляет флаг underrun и продолжает преобразовывать старые данные. Тогда исправлять приходится частоту триггера, загрузку DMA или организацию буфера, а не alignment.

Где искать такие ловушки

Выбор Byte, HalfWord или Word нельзя выводить только из названия поля в CubeMX. Сначала нужно проверить описание шины и ограничений доступа к периферии в reference manual, затем формат конкретного регистра и уже после этого согласовать PSIZE с MSIZE. STM32G474 хорошо показывает эту границу: массив остаётся компактным 16-битным, DAC остаётся 12-битным, но мост между ними обязан пройти по AHB полным 32-битным словом.