STM32 uses DMA to realize multi-channel ADC channel data acquisition

Publisher:电子创新者Latest update time:2016-06-03 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
  Today I tried STM32's ADC sampling and used DMA to directly transfer and store the sampled data, so that the CPU does not need to participate in the operation.

  I found a lot of examples for reference and got a general understanding of the settings of ADC and DMA. I directly used the development board to do some experiments to verify the related operations and ensure my understanding of the settings of each part.

  I used three ADC channels here, one for external variable resistor input, and the other two for internal temperature sampling and Vrefint. This way, continuous sampling can be formed to test multi-channel ADC automatic scanning. ADC is divided into rule conversion and injection conversion. In fact, rule conversion is to convert sequentially according to the established settings, and injection conversion is like cutting in line in this sequential queue, and can convert in advance.

  Initialization settings:

1 //PC0 FOR ANAGLE SAMPLE
 2 static void Protect_ClkInit(void)
 3 {
 4 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1RCC_APB2Periph_GPIOC,ENABLE);
 5 RCC_ADCCLKConfig(RCC_PCLK2_Div6);
 6 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 7 }
 8
 9 static void Protect_GPIOInit(void)
10 {
11 GPIO_InitTypeDef GPIO_InitStructure;
12
13 /*GPIO PhaseA_H initialization*/
14 GPIO_InitStructure.GPIO_Pin = ADC_PIN;
15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
16 GPIO_Init(TIMER_GPIO_AH_PORT, &GPIO_InitStructure);
17 }
18
19 static void Protect_AdcInit(void)
20 {
21 ADC_InitTypeDef ADC_InitStructure;
twenty two     
23 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
24 ADC_InitStructure.ADC_ScanConvMode = ENABLE;
25 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
26 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
27 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
28 ADC_InitStructure.ADC_NbrOfChannel = 3;
29 ADC_Init(ADC1, &ADC_InitStructure);
30     
31 ADC_TempSensorVrefintCmd(ENABLE);
32 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);
33 ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,2,ADC_SampleTime_7Cycles5);
34 ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,3,ADC_SampleTime_7Cycles5);
35     
36 ADC_DMACmd(ADC1, ENABLE);
37 /* Enable ADC1 external trigger */
38 ADC_ExternalTrigConvCmd(ADC1, DISABLE);
39
40 ADC_Cmd(ADC1, ENABLE);
41
42 ADC_ResetCalibration(ADC1);
43
44 while(ADC_GetResetCalibrationStatus(ADC1));
45
46 ADC_StartCalibration(ADC1);
47
48 while(ADC_GetCalibrationStatus(ADC1));
49
50 }
51
52 static void Protect_DMAInit(void)
53 {
54
55 DMA_InitTypeDef DMA_InitStructure;
56
57 /* DMA1 channel1 configuration -*/
58 DMA_DeInit(DMA1_Channel1);
59 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (ADC1->DR);
60 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
61 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
62 DMA_InitStructure.DMA_BufferSize = 3;
63 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
64 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
65 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
66 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
67 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
68 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
69 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
70 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
71
72 /* Enable DMA1 channel1 */
73 DMA_Cmd(DMA1_Channel1, ENABLE);
74 }

  After setting up and testing, I found a serious problem. When I adjusted the variable resistor, I found that it would affect the data of the other two sampling channels, and the data changed greatly. I first tested the reference voltage of ADC, namely Vref+ and Vref-, and found no change. Is there a problem with the initialization of sampling? I found a lot of information on the Internet, but none of them showed that there was a problem with my settings. However, I still found a difference, that is, the time of ADC_sampling_time was different. So I set it to:

1 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);
2 ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,2,ADC_SampleTime_239Cycles5);
3 ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,3,ADC_SampleTime_239Cycles5);

  That is the maximum sampling time. It turned out that this was indeed the problem. Later, I tried several other sampling times, and the shortest one had to be ADC_SampleTime_71Cycles5, otherwise the data would be affected. I guess the sampling period cannot be too short, otherwise DMA data transmission may be affected.

Keywords:STM32 Reference address:STM32 uses DMA to realize multi-channel ADC channel data acquisition

Previous article:STM32 UART DMA implements unknown data length reception
Next article:AT91SAM3S serial port UART initialization and data transmission and reception

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号