ADC1 Datasheet
12-bit conversion flow, reference-manual concepts, and PA1 / CURRENT_SENSE channel mapping
Contents
- General description
- Main features
- Reference figures and tables
- ADC architecture
- Channel map
- Functional description
- Register description
- 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
Figure 1. Reconstructed ADC regular-conversion path based on RM0008 Figure 22
Figure 2. Reconstructed ADC input equivalent circuit based on DS5319 Figure 38
Figure 3. Reconstructed regular conversion timing based on RM0008 Figure 23
Figure 4. Reconstructed analog watchdog guarded area based on RM0008 Figure 24
| Table 1. Pin mapping examples used in this chapter | ||
|---|---|---|
| Signal source | ADC channel | Meaning |
| PA1 | ADC1_IN1 | External analog input pin; current trainer route is CURRENT_SENSE |
| PB0 | ADC_IN8 | Another GPIO pad routed to a different channel |
| PB1 | ADC_IN9 | Another GPIO pad routed to a different channel |
| Temperature sensor | ADC_IN16 | Internal channel, not an external GPIO pad |
| VREFINT | ADC_IN17 | Internal 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_APB2ENR | Use now | Turns on GPIOA and ADC1 on APB2. | Figure 1 block path, Section 6.1 clock path, GPIOA_CRL. |
| GPIOA_CRL | Use now | Places PA1 in analog mode so the pad can feed the ADC input path. | Figure 2 input equivalent circuit, ADC1_CR. |
| ADC1_CR | Use now | Trainer-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_CH1 | Use now | Trainer-specific raw result for PA1 / ADC1_IN1 / CURRENT_SENSE. | Trainer subset only; compare with official ADC_DR. |
| ADC1_DR_CH0 | Reference-visible | Legacy trainer raw result for PA0 / ADC1_IN0. | Trainer compact register view; not part of the current motor-driver lab map. |
| RCC_CFGR | Reference-visible | Selects ADCPRE so PCLK2 -> ADCPRE -> ADCCLK is clear. | RCC chapter clock tree, Section 6.1 ADC clock. |
| ADC_SMPR2 | Reference-visible | Sets sample time for channels such as CH1. | Figure 2 sample capacitor behavior. |
| ADC_SQR3 | Reference-visible | Chooses the first regular conversion channel in the full STM32F103 flow. | Figure 1 Analog MUX path. |
| ADC_SR | Reference-visible | Shows EOC and AWD status after a conversion. | Figure 3 timing and Figure 4 watchdog. |
| ADC_CR2 | Full STM32F103 example | Holds ADON, CAL, trigger, and software-start control. | Figure 3 timing, ADC_DR. |
| ADC_DR | Full STM32F103 example | Official regular conversion result register. | Figure 1 converter output and Figure 3 end-of-conversion point. |
| ADC_HTR / ADC_LTR | Full STM32F103 example | Set 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
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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
- Enable RCC->APB2ENR.IOPAEN and RCC->APB2ENR.ADC1EN.
- Place PA1 in analog mode through GPIOA->CRL.
- Set ADC1->CR bit 1 so the current-sense channel path is active.
- 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
- Enable GPIOA and ADC1 clocks in RCC->APB2ENR.
- Select RCC_CFGR.ADCPRE so the conversion clock path PCLK2 -> ADCPRE -> ADCCLK is valid.
- Configure the input pin as analog input through GPIOA->CRL.
- Choose sample time in ADC_SMPR2 and choose the regular channel order in ADC_SQR3.
- Enable and calibrate the ADC through ADC_CR2.
- 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
- GPIO pin names and ADC channel numbers are different concepts.
- Analog MUX decides which channel reaches the converter.
- Sample & Hold explains why sample time matters, especially with higher source impedance.
- A 12-bit result spans 0 .. 4095; official STM32F103 voltage conversion uses the ADC reference range up to 3.6 V, while the trainer board display may scale the simplified current-sense route over 0.0 V .. 5.0 V.
- The official result destination is ADC_DR, while the current lab uses trainer-specific ADC1_DR_CH1 for PA1 / ADC1_IN1 / CURRENT_SENSE.
- EOC, DMA, timer trigger, scan mode, and analog watchdog are core ADC workflow concepts even when the trainer exposes only a reduced register set.
- When the current trainer path is incomplete, the student should see a gated state and fix the missing prerequisite rather than guessing that every official ADC register is required immediately.