Analog-to-digital converterADC1 Chapter

ADC1 Datasheet

12-bit conversion flow, reference-manual concepts, and PA1 / CURRENT_SENSE channel mapping

Document ID
ADC1-DS002
Revision
Rev 2.0
Trainer base
0x40000010
Scope
STM32-style concepts + simulated subset
This chapter teaches the STM32-style ADC signal path first, then narrows down to the current simulator subset. The real STM32F103 maps ADC1 at 0x40012400 and uses ADC_SR, ADC_CR1, ADC_CR2, ADC_SMPRx, ADC_SQRx, and ADC_DR for conversion control. On the official device, the ADC conversion input range is bounded by the analog reference and supply domain, with 0 V .. 3.6 V as the STM32F103 operating limit used in this chapter. The current trainer instead exposes a teaching subset beginning at 0x40000010 with ADC1_CR and ADC1_DR_CH1 for the current motor-driver lab route PA1 / ADC1_IN1 / CURRENT_SENSE. The channel-specific trainer data register is a teaching subset; these trainer registers are not the literal STM32F103 register structure.

Contents

  1. General description
  2. Main features
  3. Reference figures and tables
  4. ADC architecture
  5. Channel map
  6. Functional description
  7. Register description
  8. Student register guide and code examples

1 General description

ADC1 converts an analog input voltage into a 12-bit digital result. The ADC path is GPIO analog input -> ADC channel -> Analog MUX -> Sample & Hold -> ADC converter -> ADC_DR, with status and transfer helpers such as EOC, DMA, and Analog watchdog around that path.

A GPIO pin is the physical analog pad, while the ADC channel number is the internal input index used by the converter. For example, PA1 maps to ADC1_IN1, while other package pins map to different ADC channel numbers. The channel selection logic is separate from the external pad itself.

In the current motor-driver trainer lab, PA1 carries the CURRENT_SENSE signal. That fixed implemented route is separate from full STM32-style multiplexed channel coverage.

2 Main features

2.1 Official STM32-style concepts

  • 12-bit unsigned conversion result, 0 .. 4095
  • Official STM32F103 analog conversion range: 0 V .. 3.6 V maximum operating range
  • Regular conversion, single-shot, continuous mode, and scan mode
  • Channel order configured through ADC_SQR1 and ADC_SQR3
  • Sample time configured through ADC_SMPR1 and ADC_SMPR2
  • End-of-conversion status in ADC_SR.EOC
  • DMA request support and analog watchdog thresholds
  • Temperature sensor and VREFINT internal channels

2.2 Currently simulated subset

  • Fixed implemented channel for PA1 / ADC1_IN1 / CURRENT_SENSE
  • Trainer-specific channel enable bits in ADC1_CR
  • Trainer-specific current-sense result register ADC1_DR_CH1
  • Board rendering and trainer scaling may show 0.0 V .. 5.0 V mapped to 0 .. 4095
  • GPIO analog-input setup should still be taught for realism through GPIOA->CRL

3 Reference figures and tables

Reconstructed regular conversion ADC block diagram based on RM0008 Figure 22

Figure 1. Reconstructed ADC regular-conversion path based on RM0008 Figure 22

Reference source: RM0008 Reference Manual, p.217, Figure 22. Single ADC block diagram.

What this figure means: This redraw follows the RM0008 Figure 22 reading direction but isolates the regular-conversion path used in this chapter. Injected conversion blocks, ADC3-only trigger variants, and remap branches are intentionally left out of the figure so the main path GPIO analog pad -> Analog MUX -> Regular channels -> converter -> ADC_DR stays clear.

Related registers: ADC_SQRx, ADC_SMPRx, ADC_CR2, ADC_SR, ADC_DR.

Reconstructed ADC input equivalent circuit based on STM32F103 datasheet Figure 38

Figure 2. Reconstructed ADC input equivalent circuit based on DS5319 Figure 38

Reference source: STM32F103 Datasheet, p.77, Figure 38. Typical connection diagram using the ADC.

What this figure means: This redraw follows the official equivalent-circuit layout. The ADC does not read the input wire directly forever. It must briefly charge an internal sampling capacitor, so source impedance and sample time directly affect accuracy.

Related registers: ADC_SMPR1, ADC_SMPR2.

Reconstructed regular conversion timing diagram based on RM0008 Figure 23

Figure 3. Reconstructed regular conversion timing based on RM0008 Figure 23

Reference source: RM0008 Reference Manual, p.220, Figure 23. Timing diagram.

What this figure means: This redraw follows the original timing-lane layout. Enabling the ADC does not instantly produce a valid result. After enable and trigger, the converter spends time sampling and converting, then ADC_SR.EOC indicates completion and ADC_DR becomes readable.

Related registers: ADC_CR2.ADON, ADC_CR2.SWSTART, ADC_SR.EOC, ADC_DR.

Reconstructed analog watchdog guarded-area diagram based on RM0008 Figure 24

Figure 4. Reconstructed analog watchdog guarded area based on RM0008 Figure 24

Reference source: RM0008 Reference Manual, p.220, Figure 24. Analog watchdog guarded area.

What this figure means: This redraw follows the official guarded-area layout. The analog watchdog compares each conversion result with configured high and low thresholds. If a result leaves the allowed range, the watchdog sets the status flag.

Related registers: ADC_HTR, ADC_LTR, ADC_CR1.AWDEN, ADC_SR.AWD.

Table 1. Pin mapping examples used in this chapter
Signal source ADC channel Meaning
PA1ADC1_IN1External analog input pin; current trainer route is CURRENT_SENSE
PB0ADC_IN8Another GPIO pad routed to a different channel
PB1ADC_IN9Another GPIO pad routed to a different channel
Temperature sensorADC_IN16Internal channel, not an external GPIO pad
VREFINTADC_IN17Internal reference channel

Reference source: STM32F103 Datasheet, p.29, Table 5. Pin definitions. What this table means: GPIO pin names and ADC channel numbers are different concepts. Related registers: ADC_SQRx, GPIOx_CRL, GPIOx_CRH; for the current trainer route, PA1 means GPIOA_CRL[7:4] plus ADC1_IN1.

4 ADC architecture

4.1 Simplified ADC block diagram

The Analog MUX selects one channel from many possible ADC inputs. The selected voltage is captured by the Sample & Hold stage, then a 12-bit converter produces the numeric result. The official STM32-style destination is ADC_DR, and the end-of-conversion state appears in ADC_SR.EOC.

4.2 Input equivalent circuit

The equivalent circuit explains why sample time matters. The sampled capacitor must charge through the external source path. If the input circuit has high resistance, the ADC needs a longer sampling window to avoid reading a value lower or higher than the real settled voltage.

4.3 Regular conversion timing

The usual flow is ADC enable -> stabilization -> trigger -> sampling -> conversion -> EOC -> read ADC_DR. This is why software often waits for EOC before reading the result register.

4.4 Official range and trainer display scale

For the official STM32F103 ADC, treat the analog input conversion range as 0 V .. 3.6 V at the device limit. The trainer board UI may render the simplified board signal scale as 0.0 V .. 5.0 V and map that displayed training voltage to 0 .. 4095. Read the 5 V scale as trainer board rendering and current-sense scaling, not as permission to drive a real STM32F103 ADC input beyond its analog range.

4.5 Analog watchdog concept

Analog watchdog logic is useful when software needs a quick indication that an analog signal has left a safe or expected range. The watchdog compares converted data against threshold registers rather than against the raw input wire directly.

5 Channel map

5.1 Channel and pin distinction

A GPIO pin is the physical entry point for analog voltage, while the ADC channel is the converter's internal numbering system. Code configures conversion order by channel number, not by GPIO label text. In DS5319 Table 5, PA1 is still an I/O pad; ADC is one selected function of that pad, not a replacement for the idea of GPIO. The current trainer deliberately observes this pad through the CURRENT_SENSE analog route, so a GPIO-output experiment on PA1 changes the output latch but does not become a visible board output.

5.2 Currently simulated subset

GPIO pad ADC channel Trainer alias Register control Result register Description GPIO experiment result in this trainer
PA1 ADC1_IN1 CURRENT_SENSE ADC1_CR[1] ADC1_DR_CH1 Shunt-amplifier current-sense signal in the trainer Configuring PA1 as GPIO output keeps ADC1_DR_CH1 at 0 and leaves CURRENT_SENSE ADC-gated.

6 Functional description

6.1 ADC clock

In a hardware-faithful flow, software enables GPIO and ADC clocks through RCC_APB2ENR and selects an ADC clock prescaler through RCC_CFGR. The training header currently exposes RCC->APB2ENR, but not the full RCC_CFGR programming model.

Clock path checkpoint Official STM32F103 meaning Currently implemented status
RCC->APB2ENR.IOPAEN Turns on the GPIOA register and pad-side peripheral clock on APB2. Exposed and enforced.
RCC->APB2ENR.ADC1EN Turns on the ADC1 interface clock on APB2. Exposed and enforced.
RCC_CFGR.ADCPRE Derives ADCCLK from PCLK2 using /2, /4, /6, or /8. Documented as official flow, but not fully programmable in the trainer header.

Clock path summary: GPIOA and ADC1 both belong to APB2, but the final ADC conversion clock is still its own path: PCLK2 -> ADCPRE -> ADCCLK.

6.2 GPIO analog input

The GPIO pad should be configured as analog input so the digital input path does not interfere with the analog node. For the current trainer, the observable channel update path is gated by IOPAEN, ADC1EN, analog pin mode, and trainer-specific ADC1_CR. The full STM32F103 explanation should still teach analog GPIO setup first because that is the real pad-side prerequisite before the converter can sample the node.

6.3 Channel selection

The Analog MUX chooses which ADC channel reaches the converter. In the official flow, ADC_SQR3 defines the first regular conversion slot and later slots follow the sequence registers. In the trainer, channel selection is simplified to fixed channel enable bits in trainer-specific ADC1_CR.

6.4 Sample time

Sample time decides how long the selected analog voltage is connected to the sampling capacitor before conversion begins. This matters most when the source impedance is high. A larger source resistance usually requires a longer sample time so the capacitor can settle close to the actual input voltage.

6.5 Single-shot conversion

Single-shot conversion means one trigger produces one sequence result set. In the official sequence, software selects a channel, chooses sample time, starts conversion, waits for EOC, then reads ADC_DR.

6.6 Scan mode

Scan mode converts several channels in order. ADC_SQR1.L defines how many regular conversions exist in the sequence, while ADC_SQR3 and later sequence registers define the order such as CH1 -> CH2 -> CH8. The trainer does not yet model the full sequence engine, so scan mode is documented as a reference-manual concept rather than as a fully enforced runtime feature.

6.7 DMA transfer

DMA becomes helpful when repeated conversions should move into memory without CPU reads after every sample. In an STM32-style scan workflow, DMA is commonly paired with regular sequences so software can collect a channel array with less polling overhead.

6.8 Timer trigger

External trigger logic allows a timer event to start conversions at a fixed interval. This is useful when software wants evenly spaced samples and does not want to issue SWSTART by CPU software each time.

6.9 Analog watchdog

Analog watchdog monitors whether the converted result stays between the configured low and high thresholds. If the result leaves the valid range, ADC_SR.AWD can report that condition.

6.10 Temperature sensor and VREFINT

ADC_IN16 and ADC_IN17 are internal channels, not external GPIO pads. They are useful examples when teaching that not every ADC channel originates from a package pin.

7 Register description

7.1 Official and trainer register split

Register Current use Main role Read it together with
RCC_APB2ENRUse nowTurns on GPIOA and ADC1 on APB2.Figure 1 block path, Section 6.1 clock path, GPIOA_CRL.
GPIOA_CRLUse nowPlaces PA1 in analog mode so the pad can feed the ADC input path.Figure 2 input equivalent circuit, ADC1_CR.
ADC1_CRUse nowTrainer-specific compact channel enable register. Bit 1 opens the PA1 / ADC1_IN1 / CURRENT_SENSE update path.Trainer subset only; compare with official ADC_CR1, ADC_CR2, and ADC_SQRx.
ADC1_DR_CH1Use nowTrainer-specific raw result for PA1 / ADC1_IN1 / CURRENT_SENSE.Trainer subset only; compare with official ADC_DR.
ADC1_DR_CH0Reference-visibleLegacy trainer raw result for PA0 / ADC1_IN0.Trainer compact register view; not part of the current motor-driver lab map.
RCC_CFGRReference-visibleSelects ADCPRE so PCLK2 -> ADCPRE -> ADCCLK is clear.RCC chapter clock tree, Section 6.1 ADC clock.
ADC_SMPR2Reference-visibleSets sample time for channels such as CH1.Figure 2 sample capacitor behavior.
ADC_SQR3Reference-visibleChooses the first regular conversion channel in the full STM32F103 flow.Figure 1 Analog MUX path.
ADC_SRReference-visibleShows EOC and AWD status after a conversion.Figure 3 timing and Figure 4 watchdog.
ADC_CR2Full STM32F103 exampleHolds ADON, CAL, trigger, and software-start control.Figure 3 timing, ADC_DR.
ADC_DRFull STM32F103 exampleOfficial regular conversion result register.Figure 1 converter output and Figure 3 end-of-conversion point.
ADC_HTR / ADC_LTRFull STM32F103 exampleSet the analog watchdog high/low window.Figure 4 guarded area.

Official STM32F103 address note: the real ADC1 register block starts at 0x40012400. The current motor-driver lab uses the trainer's ADC1_CR plus ADC1_DR_CH1 at 0x40000010 and 0x40000018 for PA1 / ADC1_IN1 / CURRENT_SENSE. ADC1_DR_CH0 remains visible at 0x40000014 as a legacy trainer register, not as the current lab route. The trainer data registers are a teaching subset, so they expose raw channels without pretending to be the literal STM32F103 register map.

7.2 Compact trainer register map, not the STM32F103 ADC1 block

Offset Register Access Current use Description
0x00 ADC1_CR R/W Use now Trainer-specific channel enable control. The current motor-driver lab uses bit 1 for PA1 / ADC1_IN1 / CURRENT_SENSE; bit 0 is visible but not part of this lab map.
0x04 ADC1_DR_CH0 R Reference-visible Legacy trainer raw result for PA0 / ADC1_IN0. Visible in Register View but not used in the current motor-driver lab.
0x08 ADC1_DR_CH1 R Use now Trainer-specific latest raw result for PA1 / ADC1_IN1 / CURRENT_SENSE.

7.3 Trainer ADC control register (ADC1_CR)

Address offset: 0x00    Reset value: 0x00000000

313029282726252423222120191817161514131211109876543210
Reserved CH1 CH0
- R/W R/W

Bit 0 CH0_EN: Legacy trainer channel-enable bit; not part of the current motor-driver lab pin map.

Bit 1 CH1_EN: Enables the trainer update path for PA1 / ADC1_IN1 / CURRENT_SENSE.

Flow link: In the official STM32-style explanation, channel order is chosen by ADC_SQR3. In the trainer subset, the same teaching idea is simplified to explicit channel enable bits.

7.4 Trainer current-sense data register (ADC1_DR_CH1)

Address offset: 0x08    Access: read-only in the trainer subset

ADC1_DR_CH1 is the compact trainer result register for PA1 / ADC1_IN1 / CURRENT_SENSE. The official STM32F103 result destination is ADC_DR; this channel-specific name exists so the training site can expose one observable current-sense route without requiring the full STM32F103 sequence engine.

Range note: official STM32F103 ADC input behavior is described with a 0 V .. 3.6 V device-side limit here. The trainer UI may display the board-level current-sense scale as 0.0 V .. 5.0 V and still store a 12-bit raw value in ADC1_DR_CH1.

8 Student register guide and code examples

8.1 Quick first practice path

For the current trainer, the easiest first ADC exercise is to start with one visible path. Make that path work end to end first, then use the rest of the chapter to see what the full STM32F103 flow adds around it.

Try this first Write in code Check in UI What it teaches
Enable the current-sense path RCC->APB2ENR.IOPAEN, RCC->APB2ENR.ADC1EN, GPIOA->CRL[7:4] = 0x0, and ADC1->CR bit1 Register: RCC_APB2ENR, GPIOA_CRL, ADC1_CR, ADC1_DR_CH1 The visible ADC route is a chain, not a single bit.
Prove the analog route is live Read ADC1->DR_CH1 and, if needed, store it with watch_u32("current_raw", current_raw) Pin: CURRENT_SENSE. Graph: PA1 / CURRENT_SENSE voltage trace. Register: ADC1_DR_CH1 raw value. Watch / Access: watched value and register reads/writes. The student sees both the raw register result and the visible signal route.
Read the failure naturally Intentionally omit one prerequisite, such as the ADC clock or PA1 analog mode. Pin stays on ADC gated, the raw graph stays flat, and the missing prerequisite remains visible in Register. The missing prerequisite becomes visible before you need the full STM32F103 sequence.

8.2 What you can use now

Register or concept How to read it in this chapter
RCC->APB2ENR, GPIOA->CRL, ADC1->CR, ADC1->DR_CH1 These are the natural first-use registers for the current trainer path. Students can paste them, run them, and prove them directly in the site.
ADC1_DR_CH0 It is still visible in the compact register map, but it is not the current motor-driver lab proof path.
RCC_CFGR, ADC_SMPR2, ADC_SQR3, ADC_SR, ADC_CR2, ADC_DR These belong to the full STM32F103 flow. Treat code using these symbols as reference-only in the current trainer, and use the shorter trainer path first.
PA1 as a visible GPIO output Do not expect that route here. The visible trainer route for PA1 stays CURRENT_SENSE, so GPIO output experiments on PA1 remain latch-only rather than becoming a named board output.

8.3 Current trainer flow

  1. Enable RCC->APB2ENR.IOPAEN and RCC->APB2ENR.ADC1EN.
  2. Place PA1 in analog mode through GPIOA->CRL.
  3. Set ADC1->CR bit 1 so the current-sense channel path is active.
  4. Read ADC1->DR_CH1 and convert the 12-bit raw value into volts if needed.

Read this flow as APB2 clock gate -> analog pad mode -> compact channel enable -> raw data register. The visible UI proof appears in Register View ADC1_CR / ADC1_DR_CH1, Pin View CURRENT_SENSE, Graph View PA1 / CURRENT_SENSE voltage trace, and Register View ADC1_DR_CH1 raw value.

8.4 Full STM32F103 flow

  1. Enable GPIOA and ADC1 clocks in RCC->APB2ENR.
  2. Select RCC_CFGR.ADCPRE so the conversion clock path PCLK2 -> ADCPRE -> ADCCLK is valid.
  3. Configure the input pin as analog input through GPIOA->CRL.
  4. Choose sample time in ADC_SMPR2 and choose the regular channel order in ADC_SQR3.
  5. Enable and calibrate the ADC through ADC_CR2.
  6. Start conversion, wait for ADC_SR.EOC, then read ADC_DR.

Reference-only on real STM32F103: this full-device path explains where RCC_CFGR, ADC_SMPR2, ADC_SQR3, ADC_CR2, ADC_SR, and ADC_DR fit around Figure 1 through Figure 4.

8.5 Code examples

8.5.1 Current trainer code example

RCC->APB2ENR |= (1u << 2);   /* IOPAEN */
RCC->APB2ENR |= (1u << 9);   /* ADC1EN */

/* PA1 CURRENT_SENSE = analog input (MODE=00, CNF=00) */
GPIOA->CRL &= ~(0xFu << 4);

ADC1->CR |= (1u << 1);       /* CH1_EN */

uint32_t current_raw = ADC1->DR_CH1 & 0x0FFFu;

/* Trainer board display scale: 0.0 V .. 5.0 V, not the official ADC input limit. */
float trainer_current_voltage = current_raw * 5.0f / 4095.0f;

Read this example together with the RCC chapter: IOPAEN enables the GPIO pad-side block, ADC1EN enables the ADC1 interface, and GPIOA->CRL opens the analog pad path before ADC1->DR_CH1 can update.

If the result still stays at 0, do not jump straight to the full reference-manual sequence. First check the simple path above: clock bits, PA1 analog mode, and ADC1->CR bit1. The page surfaces that missing path as ADC gated instead of silently faking a reading.

8.5.2 Reference-only full STM32F103 example when every ADC register is available

Read this block as the full STM32F103 conversion path around the same analog signal chain.

/* Full STM32F103 example */
RCC->APB2ENR |= (1u << 2);   /* IOPAEN */
RCC->APB2ENR |= (1u << 9);   /* ADC1EN */
RCC->CFGR = (RCC->CFGR & ~(0x3u << 14)) | (2u << 14);   /* ADCPRE = PCLK2 / 6 */

/* PA1 = analog input (MODE=00, CNF=00) */
GPIOA->CRL &= ~(0xFu << 4);

ADC_SMPR2 = (ADC_SMPR2 & ~(0x7u << 3)) | (0x4u << 3);   /* CH1 sample time */
ADC_SQR3 = 1u;                                              /* SQ1 = channel 1 */
ADC_CR2 |= (1u << 0);                                      /* ADON */
ADC_CR2 |= (1u << 3);                                      /* CAL */
while ((ADC_CR2 & (1u << 3)) != 0u) { }

ADC_CR2 |= (1u << 22);                                     /* SWSTART */
while ((ADC_SR & (1u << 1)) == 0u) { }                    /* EOC */

uint32_t raw = ADC_DR & 0x0FFFu;

Reference-only on real STM32F103: keep this block for understanding the official device path. The current trainer subset is smaller, so students should not treat every symbol in this block as immediately pasteable into the current lab.

8.5.3 Reference-only full STM32F103 scan, trigger, and watchdog examples

Reference-only on real STM32F103: these symbols are not the current trainer-executable ADC subset.

/* Illustrative STM32-style scan sequence */
ADC_CR1 |= (1u << 8);        /* SCAN */
ADC_SQR1 = ((3u - 1u) << 20); /* L = 3 conversions */
ADC_SQR3 = (1u << 0) | (2u << 5) | (8u << 10); /* CH1, CH2, CH8 */

/* DMA is usually recommended here so software can collect each conversion
 * without tight polling after every rank in the regular sequence.
 */

8.5.4 Reference-only timer-trigger and analog-watchdog notes

Reference-only on real STM32F103: keep these as ADC workflow notes unless the trainer exposes the matching registers.

/* Timer trigger concept */
/* A timer event can become the ADC conversion trigger so the CPU does not
 * need to issue SWSTART on every sample period.
 */

/* Analog watchdog concept */
ADC_HTR = high_threshold;
ADC_LTR = low_threshold;
/* If the conversion result leaves the threshold window, AWD flag is set. */

8.6 Student summary

ADC1 datasheet subsetRev 2.0