Microcontrollers: Lecture 6 Sensors, ADC,...
Transcript of Microcontrollers: Lecture 6 Sensors, ADC,...
1
Microcontrollers: Lecture 7 Sensors, ADC, DMA
Michele Magno
2
Calendar
26.04.2018 Interrupts, Timers, PMW, DAC
Exercises
27.04.2018 ADC-DMA
Exercses
03.05.2018 Sensors Devices / Radios
Projects presentation and exercises.
3
Smart Sensors are Key
Long range, low BW
Short range, BW
Low rate (periodic) data
SW update, commands
TransmitAnalyze and Classify
U Controller
L2 Memory
IOs
Data processing in a few mW power envelope
Sense
Resolution just enough
for the job, order of
200x200
MEMS IMU
MEMS Microphone
ULP Imager
for Wearables & IoT
4
Node Features
Low-power processor. Limited processing.
Memory. Limited storage.
Radio. Low-power.
Low data rate.
Limited range.
Sensors. Scalar sensors:
temperature, light, etc.
Cameras, microphones.
Power.
5
CORTEXTM-M3CPU
24 MHz
AR
M®
Pe
rip
he
ral B
us
(ma
x 2
4M
Hz)
2 x I2C
1 x SPI
2 x USART/LINSmartcard / IrDa
Modem Control
37/51/80 I/Os
Up to 16 Ext. ITs
JTAG/SW Debug
Power SupplyReg 1.8V
POR/PDR/PVD
DMA
7 Channels
Nested vect IT Ctrl
1 x USART/LINSmartcard/IrDa
Modem Control
1 x SPI
Bridge
Bridge
1 x Systick Timer
AR
M®
Lit
e H
i-S
pee
d B
us
Ma
trix
/ A
rbit
er
(ma
x 2
4M
Hz)
RTC / AWU
ARM® Peripheral Bus
(max 24MHz)
XTAL oscillators32KHz + 4~25MHz
Int. RC
oscillators40KHz + 8MHz
PLL
8kB SRAM
Fla
sh
I/F
64kB - 128kB Flash Memory
Clock Control
20B Backup Data
1 x 12-bit ADC
up to16 channels
Temperature Sensor
2 x Watchdog(independent & window)
6 x 16-bit Timer1 x CEC
2-channel 12-bit DAC
1 x 16-bit PWM Synchronized AC Timer
• Core and operating conditions
- ARM® Cortex™-M3
- 1.25 DMIPS/MHz up to 24 MHz
- 2.0 V to 3.6 V range
- -40 to +105 °C
• LQFP48, LQFP/BGA64, LQFP100
• Advanced analog- 12-bit1.2 µs conversion time ADC
- Dual channel 12-bit DAC
• Enhanced control- 16-bit motor control timer
- 6x 16-bit PWM timers
• Rich connectivity- 8 communications peripherals
STM32 Value line 64K-128KBytes System Diagram
6
Sensors
6
Integrated 9DoF IMU (Invensense)
Low-power cameras (Centeye, Awaiba, SoftKinetic)
IR sensors (LEAP, PMD)
EF sensors (Microchip GestIC, Plessy sensors)
ECG contactless (EPIC from Plessey) and bio sensors
Multi-Gas sensors
Contactless Voltage + Current
Acoustic sensors (MEMS, Analog, Digital)
Grove Starter Kit for LaunchPad
7
Sensing is a Must
7Departement Informationstechnologie und
8
What they can do?
8Departement Informationstechnologie und
9
Sensing unit
Good news:
Low power, not the power bottleneck
Miniaturization is rapidly progressing (MEMS)
Integration with circuits is possible
Issues:
Data bandwidth >> information bandwidth
Offset, drift
A/D conversion: big power premium with high precision/bandwidth
Examples:
Video camera
Gyro
Accelerometer
Proximity
Gas/Bio Microvision's MEMS scanning mirror for
Wearable Displays, Vehicle Displays and
Pico Projector Displays
EmKay Sisonic
Microphone
TRW prototyped
digital propulsion
Microthruster
10
Analog MEMS block
schematic
Output voltage is proportional to measured physical quantity
Advantages:Low cost per unitLow power consumptionVery small footprint
Disadvantages:Output not always linearSignal is not filteredADC must be close to sensorRange not selectable
11
Digital MEMS block schematic
12
…open the datasheet
You will find a Table with PIN description
Block diagramshowing that thereis more than the micro-mechanicalelement
Indication of referencedirections of the 3 accelerations
13
Check the electrical characteristics
14
Sensors data acquisition
Data acquisition system components:
Sensors:
Convert analogue measurements of physical quantities (e.g. temperature, pressure, humidity, velocity, flow-rate, linear
motion, position) into electrical signals (voltage or current).
15
Data acquisition system components
Signal conditioning (filtering and amplification):- The operations required to convert the measured analogue signal to the
electrical signal range of the analogue-to-digital converter (ADC) may involve filtering, amplification, attenuation or impedance transformation.
Analogue-to-Digital Converter (ADC):- Input: Signal to be measured;
- Output: A digital code compatible with the digital processing system;
- Requires:
• Sample-and-hold: Used to take a snapshot of the continuously changinginput signal and maintain the value over the sample interval set by a clocksystem;
• A sampling frequency based on the Nyquist theorem.
16
ADC process
2 steps
Sampling and Holding (S/H)
Quantizing and Encoding (Q/E)
17
ADC conversion Sample and Hold
Sample and Hold circuit does the signal time quantization
Restriction to digital information processing.
Known digital computers can only process discrete time series
Sample and hold-devices.
Ideally: width of clock pulse 0
Convert signal function in a series of value
18
Analogue-to-Digital Converter (ADC)
The ADC takes the voltage from the acquisition system (after signal conditioning) and converts it to an equivalent digital code;
ADC architectures: Successive Approximation (SAR)
Sigma Delta (SD or )
Slope or Dual Slope
Pipeline
Flash
ADC ideal transfer function
ADC performance
19
Analog to Digital Conversion
Quantizing and Encoding
Full scale voltage
Digital value
Value exit
Analog
Voltage
Input Resolution
20
Input/Output plot – ideal ADC
Resolution
Vin inteval with the same digital
output
Example:
12Bit ADC
VFS =10 V
=>2.44mV
Resolution
Digital Outpur
Analog Input
21
Quantization error
Digital Output,
Overestimate the Vin
Digital Output, Underestimate Vin
22
ADC performance
Resolution, R:
The resolution specifies the width of the digital output word;
- 10, 12, 16 Bit ADC
The width of the word implies the smallest change to the analogue voltage that
can be converted into a digital code;
The Least Significant Bit (LSB):
Accuracy:
Degree of conformity of a digital code representing the analogue
voltage.
Speed:
Maximum output data rate expressed in sample per second (sps)
n
ref
LSB
VV
2
23
ADC Block Examples in MCUs
Voltage reference
Clock sources
Conversion trigger
24
ADC Features (STM32 F4)
3 ADCs : ADC1 (master), ADC2 and ADC3 (slaves) If used DUAL MODE (not in
this course)
Maximum frequency of the ADC analog clock is 36MHz.
12-bits, 10-bits, 8-bits or 6-bits configurable resolution.
ADC conversion rate with 12 bit resolution is up to:
2.4 M.sample/s in single ADC mode,
4.5 M.sample/s in dual interleaved ADC mode,
7.2 M.sample/s in triple interleaved ADC mode.
Conversion range: 0 to 3.6 V.
ADC supply requirement: VDDA = 2.4V to 3.6V at full speed and down to 1.65V
at lower speed.
Up to 24 external channels.
3 ADC1 internal channels connected to:
Temperature sensor,
Internal voltage reference : VREFINT (1.2V typ),
VBAT for internal battery monitoring.
25
ADC STM32F4
•The 12-bit ADC is a successive approximation analog-to-digital converter. It has up
to 18 multiplexed channels allowing it measure signals from 16 external and two
internal sources.
•A/D conversion of the various channels can be performed in single, continuous, scan
or discontinuous mode. The result of the ADC is stored in a left-aligned or right-aligned
16-bit data register.
•The analog watchdog feature allows the application to detect if the input voltage goes
outside the user-defined high or low thresholds.
•The ADC input clock is generated from the PCLK2 clock divided by a prescaler.
•To synchronize ADC conversion and timers, the ADCs could be triggered by any of
TIM1, TIM2, TIM3, TIM4 or TIM5 timer.
26
12-bit successive approximation ADC
ADC
27
Tconv = n * TCK
Successive Approximation ADC
28
Analog references / supply
ADC
29
The ADCCLK clock provided by the
Clock Controller is synchronous with
the PCLK2 (APB2 clock). The RCC
controller has a dedicated
programmable prescaler for the ADC
clock
If prescaler == 0 on the STM32
discovery ADCCLK==36MHz
ADC
30
RCC – Real Time Clock Control
31
There are 16 multiplexed channels. A
group consists of a sequence of
conversions which can be done on any
channel and in any order.
The Temperature sensor is connected to
channel ADCx_IN16 and the internal
reference voltage VREFINT is connected
to ADCx_IN17. These two internal
channels can be selected and converted
as injected or regular channels.
The recommended sampling time for the
temperature sensor is 17.1 μs.
ADC
32
Conversion can be triggered by an external
event (e.g. timer capture, EXTI line)
ADC
33
Since converted regular channels value are
stored in a unique data register, it is
necessary to use DMA for conversion of
more than one regular channel.
Only the end of conversion of a regular
channel generates a DMA request, which
allows the transfer of its converted data
from the ADC_DR register to the destination
location selected by the user.
ADC
34
When the conversion is done, data is
stored in 16 bits registers and the proper
flags are set to indicate the end of
conversion
ADC
35
ADC speed performances
AHB_PRESC
/1,2,..512
APB2_PRESC
/1, 2, 4, 8,16
ADC_PRESC
/2,4, 6, 8
ADC_CLK
(36MHz max)
AHBCLK
(168MHz max)
(1). ADC_PRESC = /2
(2). ADC_PRESC = /4
(a)APB_PRESC = /2
(b)APB_PRESC = /1
SYSCLK
(168MHz max)
APB2CLK
(84MHz max)
AHBCLK APB2CLK ADC_CLK ADC speed(15 cycles)
168MHz (a)84MHz
(2)21MHz
0.714μs1.4 Msample/s
144MHz (a)72MHz
(1)36MHz
0.416μs2.4 Msample/s
120MHz (a)60MHz
(1)30MHz
0.5μs2 Msample/s
96MHz (a)48MHz
(1)24MHz
0.625μs1.6 Msample/s
72MHz (b)72MHz
(1)36MHz
0.416μs2.4 Msample/s
36
ADCCLK, up to 36MHz, taken from PCLK through a prescaler (Div2, Div4, Div6 and Div8).
Programmable sample time for each channel (from 4 to 480 clock cycles)
Total conversion Time = TSampling + Tconversion
ADCx
112 cycles
144 cycles
480 cycles
SMPx[2:0]
With Sample time= 3 cycles @ ADC_CLK = 36MHz total conversion time is equal
to:
ADC ConversionTime
ADCCLKPrescaler
/2, /4, /6 or /8PCLK
3 cycles
15 cycles
28 cycles
84 cycles
58 cycles
Sa
mp
leT
ime
Se
lec
tion
Resolution TConversion
12 bits 12 Cycles
10 bits 10 Cycles
8 bits 8 Cycles
6 bits 6 Cycles
resolution Total conversion Time
12 bits 12 + 3 = 15cycles 0.416 us 2.4 Msps
10 bits 10 + 3 = 13 cycles 0.361 us 2.71 Msps
8 bits 8 + 3 = 11 cycles 0.305 us 3.27 Msps
6 bits 6 + 3 = 9 cycles 0.25 us 4 Msps
37
Analog peripherals in STM33: Comparators
No CPU active if not needed
ADC
Comparators
38
Comparator 1 features 38
• Non-inverting input selectable from 24 I/Os
• Selectable edge detection through EXTI Line 21
• COMP1 and ADC can’t be used at same time since they share the ADC switch matrix
VSS
CH25
CH24
CH23
CH4
ADC
VCOMP
VREFINT
1.22V
VDD
10K400K
10K400K
+
-
COMP1
CH5
CH22
Temp. Sensor *
VREFINT *
Group 8
Group 1
Group 9
Group 7
Group 3
Group 2
CH10
CH11
CH12
CH13
CH1
CH2
CH3
CH0
CH14
CH15
CH19
CH20
CH21
CH9
CH8
CH6
CH7
CH18
ADC Switch matrix
EXTI 21
CMP1OUT
Routing Interface
PC0
PC1
PC2
PC3
PA0
PA1
PA2
PA3
PA6
PA7
PC4
PC5
PB12
PB13
PB14
PB15
PB0
PB1
PA4
PA5
PE7
PE8
PE9
PE10
39
Comparator 2 features 1/2 39
• Rail-to-rail comparator with selectable threshold: Internal reference voltage VREFINT, VREFINT submultiples (1/4, 1/2, 3/4), DAC output 1 & 2 or one external I/0 (PB3).
• Selectable non-inverting input from external I/Os: PB4 or PB5.
• Selectable edge detection through EXTI line 22.
Group 6GR 6-1
GR 6-2
PB3
TIM3 OCREF Clear
TIM3 Input Capture 4
TIM2 OCREF Clear
TIM2 Input Capture 4
TIM4 Input Capture 4TIM4 OCREF ClearTIM10 Input Capture 1
DAC_OUT1
VREFINT (1.22V)
-
+
¾ VREFINT
½ VREFINT
¼ VREFINT
PB4
PB5 EXTI 22
COMP2
DAC_OUT2
VREFINT
CMP2OUT
39
40
Comparator 2 features 2/2 40
Group 6GR 6-1
GR 6-2
PB3
DAC_OUT1
VREFINT (1.22V)
-
+
¾ VREFINT
½ VREFINT
¼ VREFINT
PB4
PB5 EXTI 22
COMP2
DAC_OUT2
VREFINT
CMP2OUT
40
• COMP2 output can be redirected to:
• Timer input captures for pulse width or signal frequency measurements
• Timer output compare reference clear signal “OCREFCLR”, putting the PWM signal in safe state as soon as analog input voltage crosses the reference.
TIM2 IC4
TIM2 OCRECLR
TIM3 IC4
TIM3 OCREFCLR
TIM4 IC4
TIM4 OCRECLR
TIM10 IC1
OUTSEL[2:0]
41
Comparators in Window mode 1/2 41
• Interrupt and Wake-up
modes:
• Vin > Upper threshold
• Vin < Lower threshold
• Lower threshold < Vin < Upper threshold
• Vin < Lower threshold or Vin > Upper threshold
Lower threshold:
Multiple source
+
-
-
+
Upper threshold:
VREFINT = 1.22V
Window comparator
configuration switch
Input voltage
COMP2
COMP1
PB4
PB5
GR 6-1
GR 6-2
43
Digital Sensors are Analog?
MCU
I2C
Analog (thermistor)
Neel to be calibrated
Resolution is affected by reference resistance precision
Conditioning circuit has to be accurately designed
Use of microcontroller ADC
Low cost
Digital (IC temperature)
Factory calibrated
Fixed resolution and high accuracy
Expensive
44
Direct Memory Access - DMA
45
DMA Characteristics
Direct memory access (DMA) is used to provide high-speed data transfer between peripherals and
memory as well as memory to memory.
Data can be quickly moved by DMA without any CPU actions.
It keeps CPU resources free for other operations.
DATA TRANSFERS:
• With CPU:
• ldr
• str
• …
• ldr
• Str
• With DMA:
• Give the start command
• Wait the interrupt when transfer is completed
46
DMA in STM32F4
The two DMA controllers have 16 streams in total (8 for DMA1 and 8 for DMA2), each stream has
8 different channels each dedicated to managing memory access requests from one
peripheral. It has an arbiter for handling the priority between DMA requests.
• 16 streams for dedicated hardware DMA requests,
software trigger is also supported. The
configuration is done by software.
• 4 priority levels (very high, high, medium, low) or
hardware in case of equality (request 1 has priority
over request 2, etc.)
• Independent source and destination transfer size
(byte, half word, word), Source/destination
addresses must be aligned on the data size.
• 5 event flags (DMA Half Transfer, DMA Transfer
complete, DMA Transfer Error, DMA FIFO Error,
Direct Mode Error) logically ORed together in a
single interrupt request for each stream
47
DMA transfer modes: memory-to-memory, peripheral-to-memory, memory-to-
peripheral.
• Memory-to-Memory:
- Transfer data from one memory buffer to another
- Circular and Direct modes are not allowed.
- Only the DMA2 controller is able to perform memory-to-memory transfers
DMA Memory to memory
48
DMA Memory and peripherals
• Memory-to-Peripheral or Peripheral-to-Memory:
- When the threshold level of the FIFO is reached, its content is drained and stored into the
destination.
- Direct Mode: the threshold level of the FIFO is not used. After each single data transfer from
the peripheral to the FIFO, the data is immediately drained and stored into the destination.
Memory-to-Peripheral Peripheral-to-Memory
49
DMA Block scheme
After an event, the peripheral
sends a request signal to the DMA
Controller.
8 channels are multiplexed In one
stream.
The DMA controller serves the
request depending on the streams
priorities.
The DMA channels can also work
without being triggered by a request
from a peripheral. This mode is
called Memory to Memory mode.
50
DMA Block scheme
• DMA requests are collected and
channel multiplexed.
• The arbiter manages the stream
requests based on their priority and
launches the peripheral/memory
access sequences.
• The priorities are managed in two
stages:
- Software (defined priority)
- Hardware (if 2 requests have
the same software priority
level, the channel with the
lowest number will get priority
versus the channel with the
highest number.)
51
DMA Block scheme
• Each channel can handle DMA
transfers between a peripheral
register located at a fixed address
and a memory address.
• Peripheral and memory pointers can
optionally be automatically post-
incremented after each transaction.
• If incremented mode is enabled, the
address of the next transfer will be
the address of the previous one
incremented by 1, 2 or 4 depending
on the chosen data size.
52
DMA Block scheme
• Noncircular mode: no DMA
request is served after the last
transfer (that is once the number of
data items to be transferred has
reached zero).
• Circular mode: handle circular
buffers and continuous data flows
(e.g. ADC scan mode). When
circular mode is activated, the
number of data to be transferred is
automatically reloaded with the
initial value programmed during the
channel configuration phase, and the
DMA requests continue to be served.
53
DMA Channels
Each Stream is multiplexed up to eight channel, only one channel at a time can be active
It is not possible to activate two channels on the same stream
Is possible to perform transfers from all 8 streams
54
Exercises
We have two microcontrollers with the following
specifications
MCU A
(1.8V to 3V)
MCU B
(1.5V to 3V)
Active mode200 µA@3V/MHz (up
8MHzMaster Clock)
300µA@3V/MHz(16MHz Master
Clock)
Active mode150 µA@2V/MHz (up to 2Mhz
Master Clock)
180 µA@2V(up to 4Mhz Master
Clock)
Sleep Mode 1.2 uA 0.6 uA
The microcontroller should be selected to be attached to a Analog sensor to
acquire a analog signal with frequency at 1KHz with a voltage range of 1V. The
required resolution for the ADC is of at least 550µV. For the sensor specification
the sample and hold period should be at least of 90µs.
55
ADC Clock Diagram
ADCCLKPrescaler
/2, /4, /6 or /8
Master Clock
3 cycles
15 cycles
28 cycles
84 cycles
58 cycles
Sa
mp
leT
ime
Se
lec
tion
The ADC Block of the internal microcontroller
follows:
Goal:
• Configure the ADC to satisfy the project requirements
• Select the Microcontroller and configuration to satisfy the Project specification and consumes less energy
in continuous mode.
• Quantify the energy consumption
• Estimate the lifetime of a system (for both MCU A and MCU B) that acquires the sensor data every 4 hour
for 36s with a battery of 100mAh, and discuss the best on the best microcontroller.
• Design the block diagram of the system designed
Vref
3V
2V
1.5V
1.1V
Resolutions
12 bits
10 bits
8 bits
6 bits
56
Solution: Configure the ADC
We need to understand
the minimal Frequency needed for the ADC sampling and acquisition.
Constrains:
- Sample and hold time of the sensor (90µ) –> It Will fix the SAMPLE AND HOLD time and the minimal ADC frequency.
- Minimal Resolution of 550µV. -> It will fix Vref and the ADC-bits
- Sample frequency for Nyquist (1KHz) –> It will fix the ADC Clock, and it will depend of the
57
Solution ADC:
90µs -> 1/T => frequency of 11.11KHz of Sampling and hold.
We can select number of clock cycle of 3/15/28. Let’s select 15.
- This results on 166.66KHz of minimal clock ADCLK. NOTE IF YOU NEED A FASTER ADCLOCK YOU NEED TO GO FASTER! AND SELECT HIGHER SAMPLE&HOLD CYCLING.
ADCLK depends of Master clock of at least a prescale of /2 /4/6 etc.. Lets chose
6. So the minimal master clock is 1MHz to satisfy the sample and Hold.
550µV -> Sensor has 1V maximum value. We can choose 1.1 For the
reference. From:
With 11bits ADC -> 1.1V/211 = 530µV -> OK!
n
ref
LSB
VV
2
58
For Nyquist we need to sample at the double of the frequency of the
signal that is at 1KHz -> so we need to sample at 2KHz.
So we need a conversion time less than 1/2KHz = 500µs.
TADC = Tsample + Tconversion Where Tconversion = Tclk*bits.
Tsample = 90us
Tconversion = 66us
TADC= 156us => Maximal frequency 6.4KHz. So we fit the SPECIFICATIONS
and also we could reduce the ADC clock if needed.
59
First Selection to fit the ADC requirements.
Master Clock 1MHz
ADC Clock 166KHz (1MHz/6)
60
Code example
• We want to use a DMA and ADC to sample a signal from an input
channel.
• Configure and enable DMA
1. Configure and enable ADC
1. Configure the prescaler for ADCCLK
2. Configure and init the ADC (conversion mode, sampling time,
etc...)
3. Calibrate ADC
4. Starting the acquisition
ADC
1. Configure and enable DMA
#define ADCx_DR_Address ((uint32_t)0x4001204C)
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA2 clock*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* DMA2 Stream0 channel 0 configuration */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* Enable DMA1 channel0 */DMA_Cmd(DMA2_Stream0, ENABLE);
Address of the register where the result
of the acquisition is saved
ADC
1. Configure and enable DMA
#define ADCx_DR_Address ((uint32_t)0x4001204C)
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA2 clock*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* DMA2 Stream0 channel 0 configuration */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* Enable DMA1 channel0 */DMA_Cmd(DMA2_Stream0, ENABLE);
ADC
We read 16bits from ADC and save
16bits in the ADC1ConvertedValue variable
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
ADC in independent mode
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
Set the prescaler to have ADCCLK==18MHz
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
ADC in Continuous Mode
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
No trigger
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
Number of Conversion
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
We set the sampling time to 3 cycles
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
Enabling DMA and ADC
2. Configure and enable ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable ADC1 clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC
Enabling DMA and ADC
#include "stm32f4xx.h"
#include "stm32f401_discovery.h"
#define ADCx_DR_ADDRESS ((uint32_t)0x4001204C)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile uint16_t ADC1ConvertedValue = 0;
volatile uint32_t ADCxConvertedVoltage = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void ADC1_CH12_DMA_Config(void);
int main(void) {
int i=0;
/* ADC configuration */
ADC1_CH12_DMA_Config();
/* Start ADC Software Conversion */
ADC_SoftwareStartConv(ADC1);
while (1) {
ADCxConvertedVoltage = ADC1ConvertedValue *3300/0xFFF;
} }
ADC (code)
/** * @brief ADC3 channel07 with DMA configuration
* @note This function Configure the ADC peripheral
1) Enable peripheral clocks
2) DMA2_Stream0 channel2 configuration
3) Configure ADC Channel7 pin as analog input
4) Configure ADC3 Channel7
* @param None
* @retval None */
void ADC1_CH12_DMA_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC3, DMA2 and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
ADC (code)
/* Configure ADC1 Channel12 pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
ADC (code)