Аналого цифровой преобразователь stm32 adc

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

К примеру при частоте 24 МГц, время преобразования будет 1,17 мкс.

АЦП в микроконтроллерах STM32 имеет следующие параметры:

  • разрядность  - 12 бит;
  • количество каналов -18 шт (16 внешиних и 2 внутренних)
  • самокалибровка;
  • возможность запуска по внешнему событию;
  • работа с DMA - прямым доступом к памяти;
  • старт преобразования от внешнего события;
  • одиночное и непрерывное преобразование;
  • генерация прерывания после завершения преобразования.

Для считывания данных с 16-ти внешних каналов имеется мультиплексор, обращение к каждому каналу осуществляется поочередно.

Преобразование сигнала может осуществлятся в разных режимах : однократном, непрерыном, по таймеру, по триггеру. Имеет возможность работы с DMA (прямого доступа к памяти). 

Структурная схема микроконтроллера STM32

Структурная схема stm32 adc

Измеренное напряжение сравнивается с опорным V_REF- и V_REF+.

V_REF- подключается к земле, а V_REF+ можно подключить к питанию микроконтроллера либо к источнику опорного напряжения (ИОН)

Напряжение Результат
V_Ref- 0
V_in V_in/(V_Ref+-VRef-)*4096
V_Ref+ 4096

Не буду описывать регистры для работы с АЦП вы их можете сами посмотреть в документации на соответствующий микроконтроллер stm, а лучше приведу код программы для настройки АЦП.

Код программы инициалицации ADC (АЦП) микроконтроллера stm32

void adc_init()
{
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
 // настройки ADC
 ADC_InitTypeDef ADC_InitStructure;
 ADC_StructInit(&ADC_InitStructure);
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // режим работы - одиночный, независимый
 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // не сканировать каналы, просто измерить один канал
 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // однократное измерение
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // без внешнего триггера
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //выравнивание битов результат - прижать вправо
 ADC_InitStructure.ADC_NbrOfChannel = 1; //количество каналов - одна штука
 ADC_Init(ADC1, &ADC_InitStructure);
 ADC_Cmd(ADC1, ENABLE);
 
 // настройка канала
 ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
 
 // калибровка АЦП
 ADC_ResetCalibration(ADC1);
 while (ADC_GetResetCalibrationStatus(ADC1));
 ADC_StartCalibration(ADC1);
 while (ADC_GetCalibrationStatus(ADC1)); 
}

 Метод получения результата измерения

uint16_t get_adc_value()
{
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
 while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
 return ADC_GetConversionValue(ADC1);
}

Данный метод работает следующим образом: сначала запускается преобразование, преобразование осуществляется до тех пор пока флаг преобразования EOC (END of Conversion) не будет изменен,  далее производится считывание данных с регистра DR.

Остается только в главном методе main проинициализировать на АЦП и в цикле получать значение.

void main()
{
 adc_init();
 uint16_t value = 0;
 while(1)
  value = get_adc_value();
} 

Добавить комментарий


Защитный код
Обновить

Последние комментарии

Последнии темы форума

  • Нет сообщений для показа