Давайте попробуем разобраться как работает аналого цифровой преобразователь - АЦП или adc в stm32. АЦП как следует из названия преобразует аналоговый сигнал в сигнал понятный микроконтроллеру а именно цифровой код. Измерение аналогового сигнала на входе происходит с определенной частотой (дискретно), чем выше частота измерения тем выше дискретизация измеряемого сигнала тем точнее произойдет преобразования аналога в цифру.
К примеру при частоте 24 МГц, время преобразования будет 1,17 мкс.
АЦП в микроконтроллерах STM32 имеет следующие параметры:
Для считывания данных с 16-ти внешних каналов имеется мультиплексор, обращение к каждому каналу осуществляется поочередно.
Преобразование сигнала может осуществлятся в разных режимах : однократном, непрерыном, по таймеру, по триггеру. Имеет возможность работы с DMA (прямого доступа к памяти).
Измеренное напряжение сравнивается с опорным V_REF- и V_REF+.
V_REF- подключается к земле, а V_REF+ можно подключить к питанию микроконтроллера либо к источнику опорного напряжения (ИОН)
| Напряжение | Результат |
| V_Ref- | 0 |
| V_in | V_in/(V_Ref+-VRef-)*4096 |
| V_Ref+ | 4096 |
Не буду описывать регистры для работы с АЦП вы их можете сами посмотреть в документации на соответствующий микроконтроллер stm, а лучше приведу код программы для настройки АЦП.
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();
}