Цифро-аналоговый преобразователь

Цифро-аналоговый преобразователь

На этом уроке мы рассмотрим использование цифро-аналогового преобразователя.
 

 

Цифро-аналоговый преобразователь (сокращенно - ЦАП) — это устройство для преобразования цифрового кода (чаще всего – двоичного) в аналоговый сигнал (для микроконтроллера это сигнал напряжения), то есть выполняет функцию, обратную аналого-цифровому преобразователю.

Основными характеристиками цифро-аналогового преобразователя являются его

  • разрядность N, которая определяет количество различных аналоговых уровней выходного сигнала 2N,
  • диапазон выходных напряжений
  • максимальная частота дискретизации – это максимальная частота, при которой ЦАП может работать, выдавая на выходе корректный результат.

 
Микроконтроллер STM32F303VCT6 содержит в своем составе 12-разрядный модуль цифро-аналогового преобразователя с двумя выходными каналами – это линии PA4 и PA5 соответственно. ЦАП может формировать на выходных каналах сигнал треугольной формы, белый шум или сигнал заданный пользователем.

Цифро-аналоговый преобразователь микроконтроллера
Выходные каналы цифро-аналогового преобразователя

Давайте создадим новый проект для микроконтроллера STM32F303VCT6, и на вкладке Pinout укажем, что будем использовать выходной канал OUT1 для цифро-аналогового преобразователя. Как видим, выход ЦАП мы можем наблюдать на линии PA4.

Задание канала 1 ЦАП
Перейдем во вкладку Clock Configuration и укажем, что будем использовать умножитель частоты с коэффициентом 16. Тем самым мы получим внутреннюю частоту тактирования 64МГц. При этом предварительный делитель модуля APB1 установим в значение 2, чтобы обеспечить частоту тактирования этого модуля не более 36МГц.
Задание частоты тактирования
Перейдем во вкладку Configuration и займемся настройкой модуля цифро-аналогового преобразователя. Давайте для начала попробуем воспроизвести треугольный сигнал на выходе ЦАП. Для этого необходимо установить тип триггера.
В качестве триггера можно выбрать любой из сигналов, приведенных в документации.
Типы триггеров для ЦАП
Я выберу TIM6 Trigger Out Event. И далее мне предлагается выбрать форму генерируемого сигнала. Мы договорились, что будем генерировать сигнал треугольной формы, поэтому во вкладке Wave generation mode выбираем Triangle wave generation. Дальше нам предлагается задать амплитуду генерируемого сигнала, которая представляет собой значение, равное степени двойки без единицы и лежит в диапазоне от 1 до 212 - 1.
Выберем для примера амплитуду, равную 2047, то есть половине от максимума.
Настройка треугольного сигнала
Это означает, что при каждом событии установленного триггера выходное напряжение будет увеличиваться на аналоговую величину, соответствующую вот такому значению.
Генерация треугольного сигнала
∆U
Эта величина является отношением максимального напряжения к количеству различных уровней аналогового сигнала, которое, в свою очередь представляет собой 2 в степени, соответствующей разрядности ЦАП. И когда выходное значение достигнет величины, соответствующей выбранной амплитуде сигнала, это значение начнет уменьшаться на 1 при каждом событии триггера.

Таким образом, 1 период сигнала на выходе ЦАП будет определяться двойной амплитудой сигнала и периодом таймера, выбранного в качестве триггера.
Период треугольного сигнала
Ну, а частота, соответственно, будет обратной величиной.

Ну, и поскольку мы выбрали таймер TIM6 в качестве триггера, необходимо настроить его параметры. На вкладке Pinout активируем таймер TIM6 и переходим на вкладку Configuration.
Trigger Event Selection ставим в значение Update Event.
TIM6 Trigger Event Selection
Это событие происходит каждый раз в момент переполнения таймера.
Update Event
Ну, и нужно установить значение периода таймера. Это значение лежит в диапазоне от 0 до 65535. Допустим, мы хотим получить треугольный сигнал с частотой 50 Гц.
Частота 50 Гц
Тогда значение регистра периода для таймера TIM6 должно составлять 312.
Сохраним настройки и, наконец-то, перейдем к проекту в IAR.
Всё, что нам нужно добавить в проект – это запуск таймера TIM6 с помощью функции

 
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);

И запуск цифро-аналогового преобразователя с помощью функции

 
__weak HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);

которая в качестве аргументов принимает ссылку на дескриптор ЦАП и константу, определяющую номер канала ЦАП:

 
 
#define DAC_CHANNEL_1                     ((uint32_t)0x00000000)       /*!< DAC Channel 1 */
#define DAC_CHANNEL_2                     ((uint32_t)0x00000010)       /*!< DAC Channel 2 */


1
2
3
4
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim6);
  HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
  /* USER CODE END 2 */


Откомпилируем проект и загрузим в отладочную плату. В данном случае работоспособность программы лучше всего проверить с помощью осциллографа. Вот сигнал на линии PA4, которая является выходом канала ЦАП. Как видим, частота действительно соответствует 50Гц, а амплитуда составляем 1,5В, что является половиной питающего напряжения.
Выходной сигнал ЦАП 50 Гц
Если мы уменьшим амплитуду треугольного сигнала, допустим, в 2 раза, то и частота этого треугольного сигнала тоже уменьшится в 2 раза. И вот результирующий сигнал на выходе ЦАП.
Выходной сигнал ЦАП 100 Гц
Как видим, частота стала 100 Гц. А амплитуда уменьшилась в 2 раза.

Верну амплитуду к предыдущему варианту - 2047.
И если необходимо увеличить частоту сигнала, сохраняя его амплитуду, то достаточно уменьшить значение периода таймера, который используется в качестве триггера. Например, мы хотим получить частоту не 50 Гц, а 1кГц.
Выходной сигнал ЦАП с частотой 1кГц
При этом полученное значение регистра периода округлим до 16. Собираем проект. И вот она – частота 1кГц.
Выходной сигнал ЦАП с частотой 1кГц

Хочу отметить еще один момент. Сейчас сигнал на выходе АЦП меняется в пределах от примерно 50мВ до 1,5В.
Наличие ненулевого начального значения связано с использованием выходного буфера, который позволяет подключать нагрузку непосредственно к выводу микроконтроллера, без использования внешнего операционного усилителя.
Выходной буфер канала ЦАП
Если мы отключим выходной буфер, то это смещение пропадет. Давайте это проверим.
Отключение выходного буфера
Вот так выглядит сигнал на выводе PA4 без использования выходного буфера.
Выходной сигнал ЦАП без буфера

Мы можем программно установить начальное значение сигнала на выходе ЦАП с помощью функции
 
__weak HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)


Ей в качестве аргументов передаются ссылка на дескриптор ЦАП, константа, обозначающая номер канала, константа, обозначающая вариант выравнивания значения и само начальное значение. В качестве этого значения установим величину, соответствующую половине питания – 2048.

Согласно документации, ЦАП микроконтроллера поддерживает 3 значения константы выравнивания:

  • выравнивание 8-битного значения по правому краю DAC_ALIGN_8B_R
  • выравнивание 12-битного значения по левому краю DAC_ALIGN_12B_L
  • выравнивание 12-битного значения по правому краю DAC_ALIGN_12B_R

Выравнивание значения ЦАП
Нам подойдет последний вариант, который задается константой DAC_ALIGN_12B_R, описанной в библиотечном файле stm32f3xx_hal_dac.h.

1
2
3
4
5
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim6);
  HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2048);
  HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
  /* USER CODE END 2 */

Добавлена строка 3
Загрузим проект в отладочную плату и посмотрим, как изменилась картинка на осциллографе.
Выходной сигнал ЦАП с начальным смещением 1.5В
Теперь мы видим, что минимальное напряжение на выходе ЦАП сместилось на отметку 1,5В.

Кстати, если мы не будем формировать треугольный сигнал на выходе ЦАП принудительно, то функция HAL_DAC_SetValue() позволит нам получить заданное аналоговое значение.
Аналоговый сигнал постоянной величины

Кроме того, микроконтроллер позволяет получить на выходе ЦАП сигнал шума с заданной амплитудой. Для этого вид сигнала устанавливаем в значение Noise Wave Generation, и в появившемся поле Noise Amplitude можем указать количество бит, которые будут формировать произвольные значения для шумового сигнала.
Сигнал шума на выходе ЦАП
Вот такой шумный сигнал получился. Замечу, что пользовательский код проекта при этом не изменился.
Сигнал шума на выходе ЦАП
Но, к сожалению, все задачи цифро-аналогового преобразователя не ограничиваются генерацией треугольника, шума или постоянного сигнала. Для формирования других видов аналогового сигнала необходимо использовать пользовательские данные, и этот способ мы рассмотрим уже в следующем уроке.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх