Change the ad conversion value and voltage value by adjusting the potentiometer
stm32f1 ADC Configuration steps
1. Enable Gpio clock and ADC clock
2. Configure PIN mode for analog input
3. Configure the ADC's divide factor
4. Initialize the ADC parameters, Adc_inittypedef
5. Enable ADC
6. Perform ADC calibration
7. Set the ADC software to start
8. Read ADC conversion values
9. Set ADC rules, sampling time, etc.
10. Convert software to enable ADC
11. Read ADC Conversion results
Example
u16 ADC_value (u8 time)
{
u8 i = 0;
u16 value;
for (i = 0; i <time; i ++)
{
ADC_SoftwareStartConvCmd (ADC1, ENABLE); // Enable ADC software conversion
while (ADC_GetFlagStatus (ADC1, ADC_FLAG_EOC)! = SET);
value + = ADC_GetConversionValue (ADC1); // Read ADC conversion result
}
return value / time;
}
typedef struct
{
uint32_t ADC_Mode; // Dual mode selection
FunctionalState ADC_ScanConvMode; // Scan mode
FunctionalState ADC_ContinuousConvMode; // Continuous conversion
uint32_t ADC_ExternalTrigConv; // External trigger conversion mode for injection channel
uint32_t ADC_DataAlign; // Data alignment
uint8_t ADC_NbrOfChannel; // Regular channel sequence length
} ADC_InitTypeDef;
void ADC_init ()
{
GPIO_InitTypeDef gpio =
{
GPIO_Pin_1,
GPIO_Speed_50MHz,
GPIO_Mode_AIN // Analog input
};
ADC_InitTypeDef adc =
{
ADC_Mode_Independent, // Independent mode
DISABLE, // Turn off scan mode
DISABLE, // Single conversion mode
ADC_ExternalTrigConv_None, // start conversion without external events
ADC_DataAlign_Right, // Right alignment
1, // Number of channels 1
};
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); // Enable GPIO clock and ADC clock
GPIO_Init (GPIOA, & gpio); // Configure pin mode
RCC_ADCCLKConfig (RCC_PCLK2_Div6); // Configure ADC divide factor 72/6 = 12 (usually)
ADC_RegularChannelConfig (ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); // Set ADC rule, sampling period
ADC_Init (ADC1, & adc); // Initialize ADC parameters
ADC_Cmd (ADC1, ENABLE); // Enable ADC
ADC_ResetCalibration (ADC1); // Perform ADC reset calibration
while (ADC_GetResetCalibrationStatus (ADC1) == SET); // wait for calibration to complete
ADC_StartCalibration (ADC1); // Perform ADC calibration
while (ADC_GetCalibrationStatus (ADC1) == SET);
ADC_SoftwareStartConvCmd (ADC1, ENABLE); // ADC software starts
}
int main (void)
{
ADC_init ();
while (1)
{
adc = ADC_value (15); // 15 times average
printf ("ADC_value is% d. \ n", adc);
printf ("vol is% .3fV. \ n", adc * (3.3 / 4096)); // Voltage value
delay_ms (500);
led1 = ~ led1;
}
}
Voltage Calculation
vol = ADC * (3.3/4096);
The ADC has a reference voltage of vref+ 3.3V. ADC is 12-bit conversion accuracy, 2^12 is 4096
DMA Mode
Adc_dmacmd turn on DMA, after ADC initialization
Adc_regularchannelconfig Channel Configuration after initialization of the ADC
Dma_memoryinc to be set to dma_memoryinc_enable, memory address incremented
Dma_buffersize size is the size of the DMA_MEMORYBASEADDR memory that is defined. Based on dma_memorydatasize memory data width, Halfword is 16bit
#define CHANNEL_NUM 4
volatile u16 AD_Bufer [4];
volatile u8 adc1_ok;
// Multi-channel configuration. 4 inputs
void ADC_init ()
{
...
ADC_InitTypeDef adc =
{
ADC_Mode_Independent, // Independent mode
ENABLE, // Enable scan mode
ENABLE, // Enable continuous conversion mode
ADC_ExternalTrigConv_None, // start conversion without external events
ADC_DataAlign_Right, // Right alignment
CHANNEL_NUM, // Number of channels 4
};
ADC_Init (ADC1, & adc);
ADC_RegularChannelConfig (ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig (ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig (ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig (ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);
DMA_adc_init (ADC1, (u32) AD_Bufer, CHANNEL_NUM);
...
}
void DMA_adc_init (ADC_TypeDef * ADCx, u32 mem_addr, u32 size)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE); // Enable DMA controller clock
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init (& NVIC_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) & ADCx-> DR; // peripheral address
DMA_InitStructure.DMA_MemoryBaseAddr = mem_addr; // Memory address
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = size; // 4 buffer sizes
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Circular mode
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init (DMA1_Channel1, & DMA_InitStructure);
DMA_ITConfig (DMA1_Channel1, DMA1_IT_TC1, ENABLE); // Enable interrupt
DMA_Cmd (DMA1_Channel1, ENABLE);
ADC_DMACmd (ADCx, ENABLE); // Enable ADC1 DMA acquisition
}
void DMA1_Channel1_IRQHandler (void)
{
if (DMA_GetITStatus (DMA1_IT_TC1)! = RESET)
{
DMA_ClearITPendingBit (DMA1_IT_TC1);
adc1_ok = 1;
}
}
int main (void)
{
ADC_init ();
while (1)
{
if (adc1_ok == 1)
{
v0 = AD_Bufer [0];
v1 = AD_Bufer [1];
v2 = AD_Bufer [2];
v3 = AD_Bufer [3];
printf ("v0 is% .3fV. \ n", v0 * (3.3 / 4096)); // Voltage value
printf ("v1 is% .3fV. \ n", v1 * (3.3 / 4096));
printf ("v2 is% .3fV. \ n", v2 * (3.3 / 4096));
printf ("v3 is% .3fV. \ n", v3 * (3.3 / 4096));
led1 = ~ led1;
adc1_ok = 0;
}
delay_ms (500);
}
}