ADC:模数转换器(Analog-to-Digital Converter),将外部模拟信号转换成单片机能够处理的数字信号,过程包括采样、保持、量化、编码。
原理参考:https://blog.youkuaiyun.com/gtz736781333/article/details/116045697
STM32的ADC实现:(1条消息) STM32---ADC模数转换详解_阿槐123456的博客-优快云博客_stm32ad转换模块
ADC分为三种模式:单次模式、连续模式、扫描模式;
1、单次模式:初始化-单次模式;ADC只执行一次转换
选择时钟源:RCC_ADC_CLK_SOURCE_RCO48M
开启时钟:A、B、C、D、ADC
void adc_single_mode_test(void)
{
uint32_t i;
gpio_t *gpiox;
uint32_t pin;
float gain_value;
float dco_value;
adc_get_calibration_value(false, &gain_value, &dco_value);
gpiox = GPIOA;
pin = GPIO_PIN_8;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
pin = GPIO_PIN_11;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
adc_init();
adc_config_clock_division(20); //sample frequence 150K
adc_config_sample_sequence(0, 1);
adc_config_sample_sequence(1, 2);
adc_config_sample_sequence(2, 2);
adc_config_conv_mode(ADC_CONV_MODE_SINGLE);
adc_enable(true);
adc_start(true);
for (i = 0; i < ADC_DATA_NUM; i++)
{
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_1[i] = adc_get_data();
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_2[i] = adc_get_data();
while(!adc_get_interrupt_status(ADC_ISR_EOC));
(void)adc_get_data();
adc_start(true);
}
adc_start(false);
adc_enable(false);
for (i = 0; i < ADC_DATA_NUM; i++)
{//calibration sample value
calibrated_sample_1[i] = ((1.2/4096) * adc_data_1[i] - dco_value) / gain_value;
calibrated_sample_2[i] = ((1.2/4096) * adc_data_2[i] - dco_value) / gain_value;
}
}
2、连续模式:当前面ADC转换一结束马上就启动另一次转换
void adc_continue_mode_test(void)
{
uint32_t i;
gpio_t *gpiox;
uint32_t pin;
float gain_value;
float dco_value;
adc_get_calibration_value(false, &gain_value, &dco_value);
gpiox = GPIOA;
pin = GPIO_PIN_8;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
pin = GPIO_PIN_11;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
adc_init();
adc_config_clock_division(20); //sample frequence 150K
adc_config_sample_sequence(0, 1);
adc_config_sample_sequence(1, 2);
adc_config_conv_mode(ADC_CONV_MODE_CONTINUE);
adc_enable(true);
adc_start(true);
for (i = 0; i < ADC_DATA_NUM; i++)
{
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_1[i] = adc_get_data();
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_2[i] = adc_get_data();
}
adc_start(false);
adc_enable(false);
for (i = 0; i < ADC_DATA_NUM; i++)
{//calibration sample value
calibrated_sample_1[i] = ((1.2/4096) * adc_data_1[i] - dco_value) / gain_value;
calibrated_sample_2[i] = ((1.2/4096) * adc_data_2[i] - dco_value) / gain_value;
}
}
3、不知道是不是扫描模式,名字叫不连续模式
void adc_discontinuous_mode_test(void)
{
uint32_t i;
gpio_t *gpiox;
uint32_t pin;
float gain_value;
float dco_value;
adc_get_calibration_value(false, &gain_value, &dco_value);
gpiox = GPIOA;
pin = GPIO_PIN_8;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
pin = GPIO_PIN_11;
gpio_init(gpiox, pin, GPIO_MODE_ANALOG);
adc_init();
adc_config_clock_division(20); //sample frequence 150K
adc_config_sample_sequence(0, 1);
adc_config_sample_sequence(1, 2);
adc_config_conv_mode(ADC_CONV_MODE_DISCONTINUE);
adc_enable(true);
adc_start(true);
while(!adc_get_interrupt_status(ADC_ISR_EOC));
(void)adc_get_data();
for (i = 0; i < ADC_DATA_NUM; i++)
{
adc_start(true);
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_1[i] = adc_get_data();
adc_start(true);
while(!adc_get_interrupt_status(ADC_ISR_EOC));
adc_data_2[i] = adc_get_data();
}
adc_start(false);
adc_enable(false);
for (i = 0; i < ADC_DATA_NUM; i++)
{//calibration sample value
calibrated_sample_1[i] = ((1.2/4096) * adc_data_1[i] - dco_value) / gain_value;
calibrated_sample_2[i] = ((1.2/4096) * adc_data_2[i] - dco_value) / gain_value;
}
}