/* ADC. H */
# Define adc1_dr_address (u32) 0x4001244c)
Void adc_configuration (void );
/* ADC. C */
# Include "ADC. H"
V16adc_convertedvalue; // This variable is used to store the ADC Conversion Result read by DMA. In the main function, extern v16adc_convertedvalue can use the converted result.
/* ADC configuration, including DMA configuration, you only need to call this function in the main function */
Void
Adc_configuration(Void)
{
Adc_inittypedef adc_initstructure;
Dma_inittypedef dma_initstructure;
Gpio_inittypedef gpio_initstructure;
Rcc_ahbperiphclockcmd (rcc_ahbperiph_dma1, enable );// Initialize the clock of the peripheral (DMA)
Rcc_apb2periphclockcmd (rcc_apb2periph_adc1 | rcc_apb2periph_gpioa | rcc_apb2periph_afio, enable );
// Initialize the clock of the peripheral (adc1, gpioa). Because the second function of gpioa is used, the second function clock has to be started.
/* Configure pa.0x (ADC channelx) as analog input -------------------------*/
Gpio_initstructure.gpio_pin = gpio_pin_5;// Set the 5th pin of gpioa to analog input (if you need other pins, you only need to change 5 to the corresponding pins and modify the corresponding ADC channel (as described below))
Gpio_initstructure.gpio_speed = gpio_speed_50mhz;
Gpio_initstructure.gpio_mode = gpio_mode_ain;// Set it to analog input
Gpio_init (gpioa, & gpio_initstructure );// Call the initialization library function to write the above configuration to the Register
/* DMA channel1 configuration -------------- set dma1 Channel 11 --------------------------------*/
Dma_deinit (dma1_channel1 );
Dma_initstructure.dma_peripheralbaseaddr = adc1_dr_address ;//The Source Address for the DMA channel to read data (that is, the address of the ADC data register defined in ADC. h. After the ADC is converted, the result will be saved in this register)
Dma_initstructure.dma_memorybaseaddr = (u32) & adc_convertedvalue;// The target address of the DMA channel, that is, the variable defined above for storing the ADC Conversion Result
Dma_initstructure.dma_dir = dma_dir_peripheralsrc;// Set the direction of the DMA transmission to the memory.
Dma_initstructure.dma_buffersize = 1;// Cache space. Because it is a single-channel ADC conversion, you only need to set it to 1 (DMA transfer starts after the buffer space is full! So do not define it as needed)
Dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable;
// Because the result of ADC conversion is always stored in its data register, this address will never change, so automatic address increment is prohibited here.
Dma_initstructure.dma_memoryinc = dma_memoryinc_disable;// Because it is a single channel and only has one variable, the automatic increment of the memory address is also forbidden (an array is used to store the Conversion Result in multi-channel mode, and the automatic increment is required in this case)
Dma_initstructure.dma_peripheraldatasize = dma_peripheraldatasize_halfword;// The data width of the peripherals (you can view the corresponding data manual. The data register of the ADC is 16, so set it to half a word)
Dma_initstructure.dma_memorydatasize = dma_memorydatasize_halfword;
// Memory data width
Dma_initstructure.dma_mode = dma_mode_circular;
// Enable cyclic transmission so that you can read the continuously changing ADC conversion value.
Dma_initstructure.dma_priority = dma_priority_high;
Dma_initstructure.dma_m2m = dma_m2m_disable;
Dma_init (dma1_channel1, & dma_initstructure );
/* Enable dma1 channel1 */
Dma_cmd (dma1_channel1, enable );
/* Adc1 configuration ------------------------------------------------------*/
Adc_initstructure.adc_mode = adc_mode_independent;// Independent ADC Mode
Adc_initstructure.adc_scanconvmode = Disable;
// Scan prohibited, not required for Single Channel
Adc_initstructure.adc_continuousconvmode = Enable;// Enable Continuous Conversion
Adc_initstructure.adc_externaltrigconv = adc_externaltrigconv_none;// The conversion is triggered externally and disabled.
Adc_initstructure.adc_dataalign = adc_dataalign_right;// Align the ADC data to the right (the ADC conversion result is 12 bits, and the ADC data register is 16 bits)
Adc_initstructure.adc_nbrofchannel = 1;// Number of ADC conversion channels: 1
Adc_init (adc1, & adc_initstructure );
/* Adc1 regular channel6 configuration */
Adc_regularchannelconfig (adc1, adc_channel_5, 1, adc_sampletime_239cycles5 );// ADC rule conversion configuration, adc1, Channel 5 (if you need to change other pins, this should also be changed to the corresponding ADC channel), because it is a single channel, therefore, the channel sequence is set to 1, and the last is the sampling time.
/* Enable adc1 DMA */
Adc_dmacmd (adc1, enable );// Enable DMA transfer of the ADC
/* Enable adc1 */
Adc_cmd (adc1, enable );// Enable adc1 Conversion
/* Enable adc1 reset calibaration register */
Adc_resetcalibration (adc1 );// ADC correction. Check my previous blog.
/* Check the end of adc1 reset calibration register */
While (adc_getresetcalibrationstatus (adc1 ));
/* Start adc1 calibaration */
Adc_startcalibration (adc1 );
/* Check the end of adc1 calibration */
While (adc_getcalibrationstatus (adc1 ));
/* Start adc1 software conversion */
Adc_softwarestartconvcmd (adc1, enable );// The External Trigger conversion is disabled because we use software to trigger the conversion.
}
The analysis of the ADC single-channel program ends here, and the main function code is attached. If there is any error, you are welcome to make a picture and communicate with each other...
/* Main. C */
/* Includes ------------------------------------------------------------------*/
# Include "stm32f10x. H"
# Include "usart. H" // header file printed by serial port
# Include "ADC. H"
# Include "ick. H"// This is mainly used for latency. If the latency is not applicable, do not
# Include <stdio. h>
Void
Nvic_configuration(Void)
// Interrupt priority Configuration
{
Nvic_inittypedef nvic_initstructure;// Define the data structure
Nvic_setvectortable (nvic_vecttab_flash, 0x0000 );// Place the interrupt vector to the 0 address of Flash
Nvic_prioritygroupconfig (nvic_prioritygroup_1 );// Set the priority configuration mode. For details, please read the article in raw materials.
Nvic_initstructure.nvic_irqchannel = usart?irqn;
Nvic_initstructure.nvic_irqchannelpreemptionpriority = 1;
Nvic_initstructure.nvic_irqchannelsubpriority = 0;
Nvic_initstructure.nvic_irqchannelcmd = Enable;
Nvic_init (& nvic_initstructure );// Drop the struct into the configuration function, that is, write it to the corresponding register.
}
FloatAd_value;
Extern v16adc_convertedvalue;
Int main (void)
{
U32 I = 0x03;
Systeminit ();
Delay_init ();
Usart_configuration ();
Adc_configuration ();
Nvic_configuration ();
While (1)
{
/* Printf message with ad value to serial port every 1 second */
Ad_value = adc_convertedvalue;
Ad_value = (ad_value/4096) * 3.3;
Printf ("the current ad value = % 4.2fv \ r \ n", ad_value );
Delay (1000);/* Delay 1000 ms */
}
}