ЦАП в XMEGA(DAC)

Posted by Reason89 | Posted in , ,

    В микроконтроллерах есть высокоскоростные 12-разрядные аналоговые модули. В дополнении к АЦП и аналоговым компараторам, есть еще и высокопроизводительные цифроаналогвые преобразователи.
    Разрядность ЦАПа XMEGA 12 бит, скорость преобразования — до 1 Мбит/с. ЦАП получает частоту с периферийной тактовой частоты, запуск на преобразование могут осуществлять различные периферийные модули, подключенные к системе событий(Event System). Есть функция формирования нулевого выходного напряжения. Обычно все ЦАПы не отличаются линейностью, когда выходное напряжение в районе нуля. Для этого в  XMEGA есть два регистра, в которые можно записывать 7-битные калибровочные данные, для более точного выставления напряжения.
     Преобразования ЦАП инициируется либо записью значения во входные регистры ЦАП, либо поступлением события от Event System. Данные для преобразования во входные регистры можно записывать как из программы, так и через DMA. Выход с ЦАП может быть выполнен двумя способами. В одном случае один линейный выход на выводе микроконтроллера. В другом два независимых выхода на двух выводах микроконтроллера. В результате два канала ЦАП могут работать независимо друг от друга и выдавать два аналоговых сигнала, различающихся как по амплитуде, так и по частоте.
    В XMEGA отдельные регистры для записи входных данных на выдачу в оба канала. Выход ЦАП можно подключать внутри кристалла к другим узлам, таким как АЦП или к компаратору.
    Привожу самый простой пример работы ЦАПа, программа для микроконтроллера atxmega32a4. Пример просто выводит на вывод микроконтроллера половину питания AVCC.
volatile int Voltage = 0x7F;

void dac_init()
{
    DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc; // Используем AVCC
    DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_SINGLE_gc; // Используем один канал ЦАП
    DACB.CTRLA = DAC_CH0EN_bm | DAC_ENABLE_bm;
}

void DACB_out(int Voltage)
{
   //DACB.CH0DATA = Voltage;  // Можно выводить значение из этой переменной
   DACB.CH0DATAH = 0x0F;    // А можно в ручную заполнять значения регистров
   DACB.CH0DATAL = 0xFF;
   while (!DACB.STATUS & DAC_CH0DRE_bm);
}

void dac_init();
void DACB_out(int Voltage);

int main(void)
{
    PORTB.DIR = 0xFF;//0x08;
    PORTB.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;
    dac_init();
    
   while(1)
   {
      DACB_out(Voltage);
   }
}

    В регистре CTRLC настраивается источник опорного напряжения:
DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc;

    В регистре CTRLA необходимо разрешить канал или каналы, который мы будем использовать, и включить сам ЦАП
DACB.CTRLA = DAC_CH0EN_bm | DAC_ENABLE_bm;
     В регистре CTRLB выбирается режим, в котором будет работать ЦАП, т.е. однолинейный или двухлинейный.
DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_SINGLE_gc;
     Соответственно регистры в которые заносится значение. Не стоит забывать, что ЦАП 12 разрядный.
DACB.CH0DATAH = 0x0F; 
DACB.CH0DATAL = 0xFF;
     И в завершении не стоит забывать отключать от порта цифровой вывод.
PORTB.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;



Comments (0)

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