48510

[i] Пример и особенности работы с АЦП

Дата последнего изменения: 30.11.2023 09:22:11
Материал из настоящей статьи, относящийся к микросхемам К1986ВЕ92QI и К1986ВЕ1QI, распространяется в том числе на микроконтроллеры К1986ВЕ92FI, К1986ВЕ92F1I, К1986ВЕ94GI и К1986ВЕ1FI, К1986ВЕ1GI

В данной статье рассмотрен простой пример работы с блоком аналого-цифрового преобразователя микроконтроллера К1986ВЕ92QI в составе отладочной платы. Блок АЦП идентичен по своей структуре в следующих МК: К1986ВЕ1QI, К1901ВЦ1QI , К1986ВЕ92QI , К1986ВК214 и К1986ВК234. Однако в каждом процессоре есть свои особенности. МК К1901ВЦ1QI содержат два независимых АЦП разрядностью 12 бит, до 16 каналов каждый, в то время как в МК К1986ВЕ1QI, К1986ВК214 и К1986ВК234 по одному АЦП такой же разрядности, до 8 каналов.  Пример проекта, для К1986ВЕ92QI, рассмотренного в статье, доступен для скачивания в конце статьи.

Введение

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

АЦП может быть как отдельной микросхемой, так и быть в составе микроконтроллера. К1986ВЕ1QI, К1901ВЦ1QI, К1986ВЕ92QI, К1986ВК214 и К1986ВК234 содержат в себе интегрированный блок АЦП. Основные характеристики АЦП — это разрядность и время преобразования. Разрядность 12 бит, следовательно, АЦП может различать 212 = 4096 различных уровней подаваемого на вход напряжения. А время преобразования, в свою очередь, зависит от частоты, подаваемой на АЦП. По спецификации для осуществления преобразования требуется не менее 28 тактов синхронизации CLK, в качестве которой можно использовать как частоту процессора CPU_CLK, так и частоту ADC_CLK, формируемую в блоке «Сигналов тактовой частоты».

Стоит отметить, что согласно спецификации на микроконтроллеры, указанные в данной статье, частота тактирования (частота следования тактовых импульсов) АЦП не может превышать 14 МГц.

АЦП имеет следующие основные режимы работы:

-режим одиночного преобразования по одному каналу (с возможностью опроса бита окончания преобразования или с прерыванием по окончанию преобразования);

-режим многократного преобразования (по одному каналу/с автоматическим переключением нескольких каналов и возможностью использования прямого доступа к памяти).

Преобразование с контролем границ

Микроконтроллеры К1901ВЦ1QI и К1986ВЕ92QI имеют в своём арсенале 2 независимых АЦП – ADC1, ADC2, которые входят в состав блока АЦП. Общая схема приведена на рисунке 1. Только у К1986ВЕ92QI АЦП имеют по 8 каналов, у К1901ВЦ1QI по 16.

 Рисунок 1 - Структурная схема АЦП К1901ВЦ1QI 

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

H_Level = 0x900;

L_Level = 0x800;

которые являются границами и за которыми МК будет следить. Изменять на входе напряжение будем с помощью подстроечного резистора, который согласно описанию платы, подключен к 7 каналу АЦП. Для этого необходимо установить перемычку на разъём XP6 в положение “TRIM” (рисунок 2).

 Рисунок 2 - Фрагмент платы К1986ВЕ92QI с подстроечным резистором и перемычкой XP6

Таким образом, в случае нарушения данных границ, то есть выхода за границы интервала от 0x800 до 0x900, МК возведёт флаг Flg REG AWOIFEN в регистре ADCx_STATUS.

Настройка АЦП

Как было отмечено ранее, в микроконтроллерах серии К1986ВЕ92QI и К1901ВЦ1QI есть два независимых АЦП. Поэтому в спецификации есть два регистра настроек ADC1_CFG и ADC2_CFG.

В МК К1986ВЕ1QI,  К1986ВК214 и К1986ВК234 по одному АЦП, однако регистр ADC2_CFG тоже присутствует. В этом регистре (ADC2_CFG) описан только 17 бит ADC1_OP "Выбор источника для формирования внутренней рабочей точки".

Настройка АЦП в К1986ВЕ92QI происходит с использованием двух структур: ADC_StructInit и ADCx_StructInit. Это обусловлено тем, что первая структура ADC_StructInit содержит «общие настройки», которые применимы для самого контроллера блока ADC. А уже структура ADCx_StructInit содержит в себе настройку конкретного АЦП1 или АЦП2. Рассмотрим каждую структуру по отдельности.

Первую структуру ADC_StructInit оставим без изменений:


 ADC_InitStruct->ADC_SynchronousMode = ADC_SyncMode_Independent;
 /* параметр отвечает за синхронный/независимый запуск двух АЦП (только для К1986ВЕ92QI и К1901ВЦ1QI )*/

 #endif

 ADC_InitStruct->ADC_StartDelay = 0;
 /* позволяет задать задержку между запусками АЦП1 и АЦП2 */

 ADC_InitStruct->ADC_TempSensor = ADC_TEMP_SENSOR_Disable;
 /* запрет работы температурного датчика и источника опорного напряжения (бит TS_EN) */

 ADC_InitStruct->ADC_TempSensorAmplifier = ADC_TEMP_SENSOR_AMPLIFIER_Disable;
 /* запрет работы выходного усилителя (бит TS_BUF) */

 ADC_InitStruct->ADC_TempSensorConversion = ADC_TEMP_SENSOR_CONVERSION_Disable;
 /* запрет выбора датчика температуры (бит SEL_TS) */

 ADC_InitStruct->ADC_IntVRefConversion = ADC_VREF_CONVERSION_Disable;
 /*запрет выбора источника опорного напряжения для оцифровки

 ADC_InitStruct->ADC_IntVRefTrimming = 0;
/*задавая значения от 0 до 7, можно в небольших пределах подстроить */


Здесь стоит отметить следующий момент: параметр ADC_IntVRefConversion разрешает и запрещает выбор источника опорного напряжения бит SEL_VREF регистра ADC1_CFG. Затем с помощью параметра ADC_IntVRefTrimming можно выполнить подстройку значений от 0 до 7 - биты 24..21 TR того же регистра ADC1_CFG. 

В микроконтроллерах  К1986ВЕ1QI,  К1986ВК214 и К1986ВК234  разрешение выбора данного датчика, а также подстройка значений, выполняется в отдельном регистре ADC1_TRIM.

Рассмотрим конфигурацию АЦП1.

sADCx.ADC_ClockSource = ADC_CLOCK_SOURCE_CPU;
/* выбор источника тактирования, частота ядра */

sADCx.ADC_SamplingMode = ADC_SAMPLING_MODE_CICLIC_CONV;
/* режим многократного преобразования */

sADCx.ADC_ChannelSwitching = ADC_CH_SWITCHING_Disable;
/* автоматическое переключение каналов */

sADCx.ADC_ChannelNumber = ADC_CH_ADC7;
/* выбор номера канала */

sADCx.ADC_Channels = 0;
/* количество используемых каналов, если включен перебор */

ADC_CH_SWITCHING_Enable sADCx.ADC_LevelControl = ADC_LEVEL_CONTROL_Enable;
/* контроль уровня входного сигнала */

sADCx.ADC_LowLevel = L_Level;
/* нижний уровень контроля */

sADCx.ADC_HighLevel = H_Level; // верхний уровень

sADCx.ADC_VRefSource = ADC_VREF_SOURCE_INTERNAL;
/* выбор внутреннего источника опорного напряжения */

sADCx.ADC_IntVRefSource = ADC_INT_VREF_SOURCE_INEXACT;
/* вид источника для датчика опорного напряжения */

sADCx.ADC_Prescaler = ADC_CLK_div_32768; //выбор делителя тактовой частоты

sADCx.ADC_DelayGo = 0xF;
/* значение задержки перед началом следующего преобразования */

Прерывания по завершению преобразования

После инициализации АЦП с помощью функции ADC1_ITConfig разрешим прерывания по завершению преобразования. Затем функцией ADC1_Cmd (ENABLE) разрешаем работу АЦП. Как только АЦП выполнит преобразование, произойдет переход в функцию обработчика прерываний, в котором сначала будет выполнена проверка установки флага выхода за границы. Если значение на входе АЦП не попадает в обозначенные границы, загорается диод VD3. После этого считывается значение регистра ADC1_RESULT и накладывается маска, поскольку биты данного регистра содержат также номер канала.  Сравнивается результат. Если верхнее значение границы было превышено, то вместе с VD3 горит диод VD4. При попадании значения на входе АЦП в нужный интервал все диоды погаснут. В конце обработчика выполняется очистка флагов.

Функция обработчика прерывания:

void ADC_IRQHandler(void)
{
    if(ADC1_GetFlagStatus(ADCx_FLAG_OUT_OF_RANGE) == SET)
    {
        /* Turns LED1 On */
        PORT_SetBits(MDR_PORTC, PORT_Pin_0);
    }
    else
    {
        /* Turns LED1 Off */
        PORT_ResetBits(MDR_PORTC, PORT_Pin_0);
    }
    tmp = MDR_ADC->ADC1_RESULT & 0x0FFF;
    if(tmp > H_Level)
    {
        /* Turns LED2 On */
        PORT_SetBits(MDR_PORTC, PORT_Pin_1);
    }
    else
    {
        /* Turns LED2 Off */
        PORT_ResetBits(MDR_PORTC, PORT_Pin_1);
    }
    /* Clear ADC1 OUT_OF_RANGE interrupt bit */
    MDR_ADC->ADC1_STATUS = (ADCx_IT_END_OF_CONVERSION | ADCx_IT_OUT_OF_RANGE)<<2;
 }

В режиме отладки можно посмотреть, как происходят изменения значения в регистре ADC1_RESULT в зависимости от изменения сопротивления подстроечного резистора, чтобы отловить момент выхода за объявленные границы (рисунок 3).

 Рисунок 3 - Регистры АЦП в режиме "отладки"


Расчет и измерение времени преобразования АЦП описано в статье "Расчет времени преобразования АЦП и время заряда внутренней емкости"

 Последовательное преобразование нескольких каналов

 В данном режиме работы есть определенное условие, которое надо обязательно соблюдать. Необходимо обеспечить выставление бит каналов, в регистре ADC1_CHSEL, участвующих в преобразовании до конфигурирования самого блока АЦП, то есть до записи в регистр ADCx_CFG.

Пример работы:

#define Amount_Conv 10

uint32_t status[Amount_Conv], data[Amount_Conv], counter = 0;
volatile uint32_t a=0;

int main (void)
{
MDR_RST_CLK->PER_CLOCK=0xFFFFFFFF;
MDR_PORTD->ANALOG=0xFFFF;
MDR_PORTD->PWR=0xFFFFFFFF;
MDR_PORTD->OE=0xFFFF;

MDR_ADC->ADC1_CHSEL=(1<<2) | (1 <<3);
MDR_ADC->ADC1_CFG |= (1<<3) | (1<<9) | (3<<12) | (7<<25);
MDR_ADC->ADC1_CFG |= 0x1;

while( counter < Amount_Conv )
  {
    while( ( MDR_ADC->ADC1_STATUS & (1<<2) ) == 0){}         
    status[counter] = MDR_ADC->ADC1_STATUS;
    data[counter] = MDR_ADC->ADC1_RESULT;                        
    counter++;
  }
while(1);
}

Сохранить статью в PDF

Файлы для скачивания

Теги

Была ли статья полезной?