Понимание и использование цифроаналогового преобразователя sam4s

Понимание и использование цифроаналогового преобразователя sam4s
Понимание и использование цифроаналогового преобразователя sam4s
Anonim

Понимание и использование цифрового преобразователя SAM4S

Часть вторая в этой серии из трех статей исследует ЦАП SAM4S. Мы рассмотрим конфигурацию оборудования, электрические характеристики и интерфейс прикладного программирования.

Вспомогательная информация

  • Введение в разработку проекта с помощью Atmel SAM4S Xplained Pro
  • Введение в цифро-аналоговое преобразование

Требуемое оборудование / программное обеспечение

  • Комплект оценки SAM4S Xplained Pro
  • Студия Atmel

Предыдущая статья

DMA цифро-аналоговое преобразование с микроконтроллером SAM4S: таймер / счетчик

DACC

Цель этой статьи - сделать SAM4S DACC (цифро-аналоговый преобразователь) генерировать простую треугольную волну (мы перейдем к синусоидальной волне и включим прямой доступ к памяти в части 3). В конце этой статьи мы рассмотрим множество важных деталей, связанных с электрическими характеристиками ЦАП, регистрами, которые управляют работой ЦАП, и программным интерфейсом, предоставляемым Atmel Software Framework (ASF). На мой взгляд, раздел DACC в спецификации SAM4S и документация для модуля DACC ASF не так понятны и информативны, как могли бы быть. Если у вас были проблемы с DACC в прошлом, эта статья должна расширять и упрощать ваше понимание этого удобного периферийного устройства. Если вы полностью новичок в DACC, это будет тщательное и полезное введение.

Основы

SAM4S DACC включает два идентичных независимых аналого-цифровых канала. Они предлагают 12-битное разрешение, что означает, что значение, записанное в регистр данных преобразования ЦАП, может быть любым числом от 0 до (2 12 - 1), то есть 4095. Как обсуждалось в предыдущей статье, ЦАП может работать бесплатно режим записи, когда запись в регистр данных преобразования инициирует обновление на аналоговом выходе или в запущенном режиме, когда обновления инициируются нарастающим фронтом внутреннего или внешнего сигнала синхронизации. Мы будем использовать триггерный режим для обеспечения идентичных интервалов между обновлениями; в предыдущей статье мы сконфигурировали канал 1 модуля таймера / счетчика 0 для обеспечения квадратной волны 100 кГц для запуска ЦАП. Вот захват области действия триггерного сигнала; он внутренне перенаправляется в DACC, но мы также управляем его портом, чтобы мы могли его исследовать.

Image
Image

Оба канала ЦАП могут быть обновлены через контроллер периферийной прямой памяти SAM4S (прямой доступ к памяти сокращен как DMA, а этот модуль контроллера, в свою очередь, сокращенно PDC). PDC позволяет нам непрерывно отправлять новые значения преобразования в ЦАП с минимальным вовлечением ЦП. Мы рассмотрим часть PDC этого проекта в части 3.

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

Этот FIFO не так полезен, как вы думаете, потому что он может хранить только четыре значения преобразования, но я полагаю, что это лучше, чем возможность писать только одно значение за раз. Как вы увидите, когда мы смотрим на прошивку, прежде чем записывать данные в регистр данных преобразования, вы должны убедиться, что FIFO не заполнен, проверив флаг TXRDY в регистре состояния прерывания DACC.

Проблемы с ASF

Интерфейс ASF для SAM4S DACC, по-видимому, включает в себя некоторые недочеты, которые могут привести к значительной путанице, поэтому давайте внимательно рассмотрим процесс настройки DACC.

Первые два шага по запуску DACC не представляют никаких проблем. Сначала вы перезагружаете аппаратное обеспечение DACC, затем выбираете режим полуслова или режим полного слова:


//begin DACC configuration by resetting the DACC hardware dacc_reset(DACC); //write one 16-bit value at a time, not two 16-bit values in one 32-bit word dacc_set_transfer_mode(DACC, HALFWORD_MODE);

В режиме полуслова аппаратное обеспечение DACC смотрит только на младшие 16 бит значения, которое вы записываете в регистр данных преобразования. В режиме полного слова аппаратное обеспечение интерпретирует младшие 16 бит как одно значение, а верхние 16 бит - как второе значение. В любом случае мы имеем дело с 12-разрядным ЦАПом, поэтому верхние 4 бита любого 16-битного значения преобразования игнорируются (если только вы не используете режим тегов), вы можете узнать больше об этом на стр. 1124 SAM4S (PDF)).

Теперь нам нужно настроить параметры синхронизации DACC, и здесь все становится немного грязным. Функция, которую мы используем для этого, - dacc_set_timing (). Эта одна функция используется для множества микроконтроллеров Atmel, что означает, что эта одна функция должна иметь возможность настраивать синхронизацию для разных модулей DACC, что, в свою очередь, означает, что ASF включает в себя различные версии функции dacc_set_timing (). Версия, которую ASF будет использовать для проекта SAM4S, следующая:


uint32_t dacc_set_timing(Dacc *p_dacc, uint32_t ul_refresh, uint32_t ul_maxs, uint32_t ul_startup) { uint32_t mr = p_dacc->DACC_MR & (~(DACC_MR_REFRESH_Msk | DACC_MR_STARTUP_Msk)); mr |= DACC_MR_REFRESH(ul_refresh); if (ul_maxs) mr else { mr &= ~DACC_MR_MAXS; } mr |= (DACC_MR_STARTUP_Msk & ((ul_startup)

К сожалению, есть две проблемы с этой функцией. Во-первых, он включает параметр ul_refresh. Аналоговое напряжение, генерируемое ЦАП, постепенно уменьшается с течением времени в результате утечки; для поддержания надлежащего выходного напряжения ЦАП должен быть «обновлен». Это обновление может быть выполнено простым написанием того же значения (или нового значения, если требуется) в регистр данных преобразования в указанное «время обновления». Однако аппаратное обеспечение ЦАП в устройствах XMEGA Atmel (возможно, и другие) включает в себя функции автоматического обновления. Параметр ul_refresh, который используется для установки интервала обновления, отражает эту возможность автоматического обновления. Проблема в том, что модуль SAM4S DACC не имеет автоматического обновления, и, следовательно, это не функция, которая должна использоваться с проектом SAM4S.

Вторая проблема связана с первой. При попытке сконфигурировать несуществующее аппаратное обеспечение автоматического обновления, вышеуказанная версия функции dacc_set_timing () очищает бит 8 регистра режима DACC. И почему мы должны заботиться о бит 8 "// www.atmel.com/images/atmel-11100-32-bit%20cortex-m4-microcontroller-sam4s_datasheet.pdf#page=1128" target = "_ blank"> стр. 1128 (PDF) спецификации SAM4S:

Image
Image

Я не утверждаю, что знаю ничего о природе или последствиях этого таинственно критического бита; я знаю, что я не игнорирую ужасные, явные предупреждения, содержащиеся в технических описаниях, опубликованных авторитетными производителями ИС. Таким образом, я отказываюсь иметь какое-либо отношение к функции dacc_set_timing (), которая осмеливается очистить бит 8 регистра режима DACC.

К счастью, средство для этой неприятной ситуации довольно просто: во-первых, измените два файла ASF, чтобы версия SAM4E dacc_set_timing () использовалась также для проекта SAM4S. SAC4E DACC не имеет автоматического обновления, и насколько я могу судить, существенных различий между SAC4E DACC и SAM4S DACC нет. Во-вторых, удалите часть dacc_set_timing (), которая вызывает очистку бит 8. Я буду использовать Diffchecker, чтобы прояснить изменения. Ниже приведены изменения для первого файла «dacc.c» (исходная версия слева, а измененная версия - справа):

Image
Image
Image
Image

И вот изменения для второго файла, «dacc.h»:

Image
Image

Прежде чем двигаться дальше, давайте поговорим о том, как мы обновим ЦАП, поскольку у нас нет автоматического обновления. Page 1181 (PDF) спецификации SAM4S сообщает нам, что интервал обновления для «8-разрядной точности» составляет 24 мкс:

Image
Image

Мне кажется, что 8-битная точность довольно низкая для 12-разрядного ЦАП, поэтому я предпочел бы использовать более короткий интервал обновления - возможно, 10 мкс? Наша цель в этом проекте - генерация непрерывных сигналов, поэтому мы можем обеспечить соблюдение этого минимального интервала между обновлениями ЦАП, поддерживая частоту дискретизации, превышающую или равную 100 кГц.

Часы ЦАП

Когда вы создаете новый проект в Atmel Studio, конфигурация часов по умолчанию (найденная в «conf_clock.h») дает вам частоту основного тактового генератора (MCK) 120 МГц. Частота периферийных часов равна частоте MCK, а частота тактовых импульсов, которая управляет схемой ЦАП (называемая тактовой частотой ЦАП), - это частота периферийных тактовых импульсов, разделенная на два. Таким образом, конфигурация по умолчанию оставляет нам f DAC_clock = 60 МГц. К сожалению, максимальная тактовая частота DAC составляет 50 МГц:

Image
Image

Чтобы исправить это, я изменил «conf_clock.h» следующим образом:


// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div) // Use mul and div effective values here. #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL #define CONFIG_PLL0_MUL 16 //previously this was 20 #define CONFIG_PLL0_DIV 1

Это приводит к f MCK = 96 МГц и, следовательно, f DAC_clock = 48 МГц.

Время запуска

В рамках настройки DACC нам нужно указать, сколько тиков DAC-часов требуется для обеспечения требуемого времени запуска. Мы не спешим здесь, поэтому мы будем использовать максимальное значение:

Image
Image

(startup \ clock \ ticks = \ frac {40 \ \ mu s} { frac {1} {48 \ MHz}} = \ 1920 )

Таким образом, мы используем десятичное значение 30 в качестве третьего аргумента в нашем вызове dacc_set_timing (). (Второй параметр для этой функции используется для включения или отключения режима максимальной скорости, вы можете узнать больше об этом на стр. 1125 (PDF) таблицы данных.)

Image
Image

Наконец, мы можем использовать ЦАП

Вот код конфигурации DACC:


//enable peripheral clock for DACC pmc_enable_periph_clk(ID_DACC); //begin DACC configuration by resetting the DACC hardware dacc_reset(DACC); //write one 16-bit value at a time, not two 16-bit values in one 32-bit word dacc_set_transfer_mode(DACC, HALFWORD_MODE); //refer to the article for details dacc_set_timing(DACC, MAXSPEED_MODE_DISABLED, STARTUP_TIME_1920_TICKS); //select channel 0 dacc_set_channel_selection(DACC, DACC_CHANNEL0); /*Choose the TIO output from timer/counter channel 1 as the trigger. Note that "channel 1" in this case refers only to channel 1 of timer/counter module 0, not channel 1 of timer/counter module 1. Also, the datasheet specifies only "TIO output" as the trigger source, without clarifying whether this refers to TIOA or TIOB or both. With a little experimentation I determined that only TIOA will trigger the DAC, not TIOB.*/ dacc_set_trigger(DACC, TC_CHANNEL1_TIO); //enable DACC channel 0 dacc_enable_channel(DACC, DACC_CHANNEL0);

И вот код, который мы используем для создания треугольной волны, которая начинается с нуля, увеличивается до максимального напряжения ЦАП (соответствующего значению преобразования 4095), уменьшается до нуля, увеличивается до максимума и т. Д.


n = 0; while (1) { //check the TXRDY flag if ((dacc_get_interrupt_status(DACC) & TXRDY) == false) { continue; } //write the conversion value dacc_write_conversion_data(DACC, n); if (Increase_or_Decrease == INCREASE) { if (n == 4095) { Increase_or_Decrease = DECREASE; } else { n+; } } else { if (n == 0) { Increase_or_Decrease = INCREASE; } else { n--; } } }

Вы можете зондировать сигнал ЦАП с помощью клеммы 10 в ряду сквозных отверстий с надписью «SPARE / ALTERNATE SIGNALS». Потенциометр слева от этих сквозных отверстий позволяет регулировать опорное напряжение ЦАП; Я установил свой 2, 4 В.

Результаты и выводы

Вы можете использовать следующую ссылку для загрузки исходных файлов и файлов проекта:

Файлы источника и проекта

Вот захват области формы сигнала ЦАП:

Image
Image

Почему минимальные и максимальные значения составляют 0, 42 В и 2, 0 В вместо 0 В и 2, 4 В? Ответ найден в электрических характеристиках ЦАП:

Image
Image

Эта небольшая деталь, легко упускаемая из виду, сообщает нам, что диапазон выходного сигнала ЦАП несколько ограничен. С опорным напряжением 2, 4 V, теоретический диапазон составляет 0, 4 В до 2 В, что согласуется с нашими измерениями.

Этот следующий захват области подтверждает, что обновления выходного напряжения ЦАП синхронизируются с сигналом триггера (я увеличил приращение до 350 отсчетов вместо 1 счетчика, чтобы сделать переходы более очевидными):

Image
Image

Аппаратное обеспечение ЦАП нуждается в 25 циклах ЦАП для обновления выходных данных. Таким образом, интервал между нарастающим фронтом на триггерный сигнал и изменение напряжения ЦАП должен составлять 25 / f DAC_clock = 521 нс, что согласуется с тем, что мы видим в области видимости.

Теперь, когда ЦАП работает и правильно запускается сигналом частоты дискретизации от модуля таймера / счетчика, мы готовы к части 3, в которой мы будем генерировать значения преобразования для синусоиды и передавать эти значения в ЦАП с использованием PDC.

Следующая статья в серии: цифро-аналоговое преобразование с периферийным контроллером DMA SAM4S

Попробуйте этот проект сами! Получить спецификацию.