DMA sampling problem for stm32f030 ADC1

Source: Internet
Author: User

After 1 days, the ADC has not come out and found that the value of the processing is always fixed value.

Go to 21IC for help stickers. [STM32F0] stm32f030 ADC1 sampling Questions to ask

It was a long time since no one replied, but someone reminded me that I needed to wait for DMA data to complete.

After comparing the code of others,

/* ADC DMA request in circular mode */
Adc_dmarequestmodeconfig (ADC1, adc_dmamode_circular);

Other people have this code, so I add this word, you can normally sample the data,

Therefore, you must add, otherwise you cannot get to the sampled value.


Then we find that the DMA transfer to the specified array data is out of order .....

Like someone else's help sticker: [STM32F0] stm32f030 multi-channel ADC DMA read problem

After the solution, according to the last post to resolve the way

"The F0 ADC needs to be calibrated before it can be used. This 7-bit calibration value is also placed in the ADC_DR, which also triggers the DMA request. You can refer to the ADC-DMA routine of the F0, do the ADC calibration first, then set the DMA, and then enable the DMA of the ADC. "


Insert the code directly, the correct initialization code:

typedef enum {adc_porta0 = adc_channel_0, adc_porta1 = adc_channel_1, Adc_porta2 = adc_channel_2, adc_porta3 = AD C_channel_3, adc_porta4 = adc_channel_4, Adc_porta5 = adc_channel_5, adc_porta6 = adc_channel_6, ADC_PORTA7 = ADC_Chan nel_7, adc_porta8 = adc_channel_8, adc_porta9 = adc_channel_9, adc_porta10 = adc_channel_10, ADC_PORTA11 = ADC_Channel _11, Adc_porta12 = Adc_channel_12, Adc_porta13 = adc_channel_13, adc_porta14 = adc_channel_14, ADC_PORTA15 = ADC_Chann

El_15,}ad_port;


typedef enum {key_line_1, key_line_2, Adc_key_line_max = key_line_2, Battery_ad, adc_num_cnt,//ADC total}adc_num;		Volatile u16 g_uadc_conval[adc_num_cnt] = {0};


ADC conversion Value U32 const g_uadnum[]= {//keyporta1, adc_porta9, Adc_porta8, Adc_porta2,//KEYPORTA0,};   
	
	void Adc_init (void) {adc_deinit (ADC1);

	Rcc_ahbperiphclockcmd (Rcc_ahbperiph_gpioa, ENABLE);

	Rcc_ahbperiphclockcmd (Rcc_ahbperiph_gpiob, ENABLE); Turn on the DMA1 clock Rcc_ahbperiphclockcmd (rcc_ahbperiph_dma1, ENABLE);

	Turn on the ADC1 clock rcc_apb2periphclockcmd (rcc_apb2periph_adc1,enable);

	Rcc_adcclkconfig (RCC_ADCCLK_PCLK_DIV4);
	Initialize IO port gpio_inittypedef gpio_initstruct;
	Gpio_structinit (&gpio_initstruct);
	Gpio_initstruct.gpio_mode = Gpio_mode_an;
	Gpio_initstruct.gpio_pin = Ad_key1_pin;				Gpio_init (ad_key1_port,&gpio_initstruct);
	KEY1 gpio_initstruct.gpio_pin = Ad_key2_pin;				Gpio_init (ad_key2_port,&gpio_initstruct);
	KEY2 gpio_initstruct.gpio_pin = Battery_ad_pin;			Gpio_init (battery_ad_port,&gpio_initstruct);
	Battery power sampling//configuration ADC1 DMA mode adc_inittypedef adc_initstructure;
	Dma_inittypedef dma_initstructure;
	Dma_deinit (DMA1_CHANNEL1);				Dma_initstructure.dma_peripheralbaseaddr = (u32) & (ADC1->DR);		Defines the DMA peripheral base address, which is the register DMA_INITSTRUCTURE.DMA_MEMORYBASEADDR = (u32) g_uadc_conval that holds the conversion result;			Define memory Base Address Dma_initstructure.dma_dir = DMA_DIR_PERIPHERALSRC;		Defines the ad peripheral as the source of data transmission dma_initstructure.dma_buffersize = adc_num_cnt; Specifies the DMA cache size of the DMA channel, which requires a few memory spaces, and this experiment has two conversionsChannel, so opened two dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable;			Set register address fixed dma_initstructure.dma_memoryinc = dma_memoryinc_enable; Sets the memory address sliding scale, that is, each DMA is the value of the peripheral register to the three memory space dma_initstructure.dma_peripheraldatasize = Dma_peripheraldatasize_halfword		;			Set peripheral data width dma_initstructure.dma_memorydatasize = Dma_memorydatasize_halfword;						Set the width of the memory Dma_initstructure.dma_mode = dma_mode_circular;					Set DMA working Recycle cache mode dma_initstructure.dma_priority = Dma_priority_high;
	Set DMA selected channel software priority dma_initstructure.dma_m2m = dma_m2m_disable;

	Dma_init (dma1_channel1,&dma_initstructure);					/* ADC DMA request in circular mode */Adc_dmarequestmodeconfig (ADC1, adc_dmamode_circular);
	Must be added, otherwise cannot get to the sampled value Adc_structinit (&adc_initstructure);
	Adc_initstructure.adc_resolution = adc_resolution_12b;					Adc_initstructure.adc_continuousconvmode = ENABLE;			Set ad conversion in continuous mode adc_initstructure.adc_externaltrigconv = Adc_externaltrigconvedge_none; Do not use external trigger conversion ADC_INITSTRUCTURE.ADC_DATAALign = Adc_dataalign_left;
  	The collected data is left-aligned in the register to store adc_initstructure.adc_scandirection = Adc_scandirection_backward; 

	Adc_init (ADC1, &adc_initstructure); for (U8 ucnt = 0;ucnt < adc_num_cnt;ucnt++) {/* Convert the ADC1 with 55.5 Cycles as sampling time */Adc_channe 	Lconfig (ADC1, g_uadnum[ucnt], adc_sampletime_55_5cycles); 	Sets the rule group channel for the specified ADC, sets their conversion order and sampling time}//adc_channelconfig (ADC1, adc_channel_2, adc_sampletime_55_5cycles); 	Sets the rule group channel for the specified ADC, setting their conversion order and sampling time//adc_channelconfig (ADC1, Adc_channel_8, adc_sampletime_55_5cycles); 	Sets the rule group channel for the specified ADC, setting their conversion order and sampling time//adc_channelconfig (ADC1, Adc_channel_9, adc_sampletime_55_5cycles); 

	
	Sets the rule group channel for the specified ADC, setting their conversion order and sampling time//adc_dmarequestmodeconfig (ADC1, adc_dmamode_circular);						/* ADC Calibration */adc_getcalibrationfactor (ADC1);
	
	Calibrating ADC Dma_cmd (dma1_channel1,enable);  

	/* Enable ADC_DMA */Adc_dmacmd (ADC1, enable);																	Adc_cmd (adc1,enable); Enables the specified ADC1 while (! Adc_getflagstatus (ADC1, Adc_fLag_aden));						<span style= "White-space:pre" > </span>//wait for ADC to be ready adc_startofconversion (ADC1);
 Start conversion}


A brief description of Adc_scandirection_upward and Adc_scandirection_backward is also added. Suppose ADC1 has 18 channels, 1,2....18

Adc_scandirection_upward means scanning starts from 1~18

Adc_scandirection_backward means scanning from 18~1 direction

This determines the order in which the values are stored in the user-specified memory array.

Like the code above, the corresponding relationship is g_uadc_conval[0]--->ain9 g_uadc_conval[1]--->ain8 g_uadc_conval[2]-->ain2


From: http://blog.csdn.net/lan120576664

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.