Continuing from the previous article, let's start to play with ADC's DMA transmission. Because everyone is talking about DMA, even ST's examples use DMA.
The data collected by the ADC is stored in a fixed register. When the conventional sampling method samples multiple channels, using DMA can better avoid the loss of collected data. When the DMA function of the ADC is enabled, a DMA request will be issued when each channel is converted. The DMA method cannot completely avoid the problem of data loss. To achieve data non-loss, it is necessary to enable the OVERRUN mode at the same time as the DMA, and stop data conversion when data is lost. We only need to detect whether the OVR time occurs to solve the problem caused by the loss of sampled data. For example, channel misalignment or something.
In the Reference manual of STM32F4, you can find that the DMA of ADC1 is mapped on DMA1, CH0, Stream0.
[Experiment 1, DMA method to collect single channel data]
Configure the DMA initialization settings for ADC1 as follows:
//DMA initialization
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32 _t)&adcvalue1; //Target data bit
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure. DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_BASE+0x4C; //ADC->DR address
DMA_InitStructure.DMA_PeripheralBurst =DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralInc = DMA _PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA2_Stream0,&DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
Enable DMA transfer in the ADC register. Use two functions. One is to set the DDS bit of CR2 so that DMA transfer is enabled every time the ADC data is updated.
The other is to set the DMA bit of ADC CR2 to enable DMA transfer of ADC.
Use the following two functions respectively:
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); //Start DMA transfer when source data changes
ADC_DMACmd(ADC1,ENABLE); //Enable DMA transfer of ADC
Finally, the ADC sampling value is read in adcvalue. It can be seen that the ADC sampling value can still be output without using the function ADC_GetConversionValue to read the ADC DR register:
while(1)
{
for(i = 0;i<10000;i++)
{
sum += adcvalue1;
if(i ==9999)
{
avgvota = sum/10000;
sum = 0;
printf("avg vota is: %d \r\n",avgvota*3300/0xfff);
}
}
}
[Experiment 2, DMA method to collect 4 channel data]
To sample two channels of data at the same time, first change ADC_NbrOfConversion in ADC_InitStructyre. Then use ADC_RegularChannelConfig to add channel 0 to the scan channel sequence.
From one path to four paths, a total of one line of code was changed and three lines of code were added:
ADC_InitStructyre.ADC_NbrOfConversion = 2;
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_144Cycles);
RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_144Cycles);
During the experiment, connect the inputs of PA0, PA1, PA2, and PA3 to ground or a 3.3V power supply. You can see two data jumping on the computer: 0 and 3300, indicating that the data has been sampled.
【Notes】
While conducting this experiment, a small incident occurred.
When initializing the PA port, I wrote this:
GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0 | GPIO_PinSource1 | GPIO_PinSource2 | GPIO_PinSource3;
This problem caused the failure of GPIO initialization, and the ADC could not sample the value of the corresponding pin. I have been looking for the configuration problems of DMA and ADC, and accidentally found that it is not possible to do so.
GPIO_PinSource0 and GPIO_Pin_0 are different. GPIO_Pin_0 should be used when initializing the pin. Check the macro definition in the library, the two values are different.
GPIO_PinSource0 refers to the pin number, while GPIO_Pin_0 refers to the corresponding bit in the GPIo register.
After changing this, everything works fine and the data from the four inputs can be sampled perfectly.
In the next article, we will experiment with other working modes of ADC.
Previous article:STM32F4 ADC internal temperature sensor
Next article:STM32F4 ADC1
Recommended ReadingLatest update time:2024-11-15 20:23
- Popular Resources
- Popular amplifiers
- 100 Examples of Microcontroller C Language Applications (with CD-ROM, 3rd Edition) (Wang Huiliang, Wang Dongfeng, Dong Guanqiang)
- Raspberry Pi Development in Action (2nd Edition) ([UK] Simon Monk)
- Introduction to Artificial Intelligence and Robotics (Murphy)
- Starting from scratch - TMS320C6000 series DSP principle and application system design
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- LLC formula derivation, loop compensation transfer function derivation calculation and simulation
- EEWORLD University Hall ---- Introduction to Deep Learning
- [FreeRTOS check-in station 4 opens] Inter-task communication, closing time is August 23
- After the PWM frequency of STM32 reaches 500KHZ, can it be increased or decreased by 1KHZ?
- [Technical Discussion] How to troubleshoot electromagnetic interference in wireless communications?
- Urgent recruitment
- First day of work in the Year of the Ox
- Micron ships 232-layer NAND, expanding the boundaries of 3D NAND technology——Win gifts by passing levels now!
- The Present and Future of Finger Vein Recognition Technology (Electronics Industry Procurement)
- Inventory of major domestic MCU manufacturers