Below is an explanation of how to access 1MB of SRAM space through 19 address lines using DeepSeek. It turns out that the MCU internally maps the addresses, mapping the byte addresses in the MCU to half-word (2Byte) addresses in SRAM. Here is the dialogue process:
In the SRAM settings of STM32CubeMX, the Address bits Max is 19, while in the manual it is A[0:25]. What is going on here?
This is a great question that touches on the critical distinction between hardware address lines and software addressable space in the STM32 memory system. The phenomenon you observed is completely normal, and here’s why:
Core Reason: Byte Addressing vs. Word Addressing
The CPU core of STM32 (Cortex-M) is byte-addressable, while the SRAM hardware controller connected to the CPU is 32-bit word-addressable.
Let’s break it down:
-
A[0:25] in the manual (26 address lines)
-
This refers to the number of bits in the physical address bus.
-
<span>A[25:0]</span>can represent 2^26 = 67,108,864 different addresses. -
However, note that since the SRAM controller typically accesses in 32-bit words (4 bytes), these 26 address lines address 67,108,864 words, not bytes.
-
The total addressable bytes = number of words × 4 bytes/word = 67,108,864 × 4 = 268,435,456 bytes.
-
268,435,456 bytes = 256 MB. This is the common addressing range for external memory controllers like FMC or FlexSPI in STM32F7/H7 series. Therefore, A[0:25] is typically used for connecting external memory (like SDRAM, SRAM), not internal SRAM.
Address bits Max = 19 in CubeMX
-
This refers to the number of address lines used for addressing the internal SRAM of the chip.
-
2^19 = 524,288 different addresses.
-
Similarly, the internal memory controller is also word-addressable at 32 bits. So these 524,288 addresses correspond to 524,288 words.
-
The total addressable bytes = 524,288 words × 4 bytes/word = 2,097,152 bytes.
-
2,097,152 bytes = 2048 KB = 2 MB.
-
This is a reasonable configuration value for the total internal SRAM of most STM32H7 series chips (like 1MB or more). CubeMX sets this as a maximum or configurable upper limit.
Detailed Explanation for Internal SRAM
For the internal SRAM of STM32, the situation is more typical:
-
The CPU wants to access a byte, it issues a byte address.
-
But the physical organization of the SRAM hardware block is 32 bits wide. This means that for each read operation, the SRAM returns a full 4 bytes (32 bits) of data.
-
Therefore, the SRAM only needs to use the higher bits of the address bus to index this 4-byte “word,” while the lowest two bits (A[1:0]) are not directly connected to the SRAM storage array.
-
A[1:0] are used to generate byte select signals within the SRAM controller to select which byte(s) on the 32-bit data bus (D[31:0]) are valid.
For example:
Assuming your internal SRAM size is 1 MB (0x100000 bytes).
-
From the CPU (software) perspective:
-
It needs 0x100000 unique byte addresses. This requires 20 address lines (2^20 = 1,048,576).
-
So in the CPU’s address space, 1MB of continuous byte addresses is allocated for this SRAM.
-
From the SRAM hardware perspective:
-
1 MB of byte capacity corresponds to 1,048,576 bytes / 4 = 262,144 32-bit words.
-
To address 262,144 words, 18 address lines are needed (2^18 = 262,144).
-
Therefore, the SRAM hardware only needs A[19:2] for indexing the storage units. A[1:0] is “ignored” at the hardware level because it is used for byte selection logic.
Conclusion:
| Perspective | Address Lines | Addressing Unit | Capacity Calculation | Application Scenario |
|---|---|---|---|---|
| STM32 Manual (A[0:25]) | 26 bits | 32-bit word | 2^26 * 4 = 256 MB | External Memory (like SDRAM) |
| CubeMX SRAM Settings (Max 19) | 19 bits | 32-bit word | 2^19 * 4 = 2 MB | Configuration/Mapping of Internal SRAM |
To summarize:
You are not mistaken, and there is no contradiction.
-
A[0:25] in the manual describes the physical address bus of the external memory controller, used for addressing very large external memory spaces (word-addressable).
-
19 bits in CubeMX is for the internal SRAM configuration, indicating its mappable address space size (also word-addressable), this value (2MB) aligns with the maximum selectable mapping range of internal SRAM for many STM32 high-end series chips.
In simple terms, the manual talks about “hardware pins,” while CubeMX discusses “software configurable address space size”, and both are based on 32-bit word addressing.
SRAM is 16-bit addressable, and the Address is 19 bits
You raised a very important correction! Thank you very much, this allows us to analyze the issue more accurately. You are correct that many STM32 external SRAMs are 16 bits wide.
When the SRAM is 16 bits wide, the situation changes. Let’s reanalyze:
Core Reason: Byte Addressing vs. Half-Word Addressing (16-bit)
When the STM32 CPU (Cortex-M, byte-addressable) connects to 16-bit wide SRAM:
-
CPU Perspective: It still needs to access each byte.
-
SRAM Hardware Perspective: Its data bus is 16 bits (2 bytes) wide. This means it transfers one half-word for each read/write operation.
-
Role of Address Lines:
-
Since each access is for 2 bytes, the lowest address bit A[0] loses its meaning as a byte address.
-
The SRAM chip itself uses address lines
<span>A[n:1]</span>to index each 16-bit storage unit. -
The address issued by the CPU
<span>A[0]</span>is used by the memory controller to generate byte enable signals (like UB/LB) to determine whether to access the high byte or low byte, or the entire half-word.
Recalculation: 16-bit SRAM and Address Lines
Now let’s explain the 19-bit address and the A[0:25] mentioned in the manual.
1. Meaning of “Address bits Max = 19” in CubeMX
-
This 19-bit address is used for addressing 16-bit SRAM units.
-
The number of addressable half-words = 2^19 = 524,288 half-words.
-
The total addressable bytes = 524,288 half-words × 2 bytes/half-word = 1,048,576 bytes.
-
1,048,576 bytes = 1024 KB = 1 MB.
Conclusion: Setting the address lines to 19 in CubeMX means that the FMC (Flexible Memory Controller) is configured to manage a maximum capacity of 1MB of 16-bit external SRAM. This is a very common SRAM capacity configuration.
2. Meaning of “A[0:25]” (26 address lines) in the manual
The manual describes the full physical address bus capability of the FMC controller.
-
<span>A[0:25]</span>is 26 address lines. -
For 16-bit memory, the address line
<span>A[0]</span>is used for byte selection, so the effective storage unit addressing address lines are<span>A[25:1]</span>. -
The number of addressable half-words = 2^25 = 33,554,432 half-words.
-
The total addressable bytes = 33,554,432 half-words × 2 bytes/half-word = 67,108,864 bytes.
-
67,108,864 bytes = 64 MB.
This is the maximum addressable capacity of external 16-bit memory supported by STM32 FMC (64MB).
Summary Comparison (for 16-bit SRAM)
| Scenario | Address Lines Used | Addressing Unit | Capacity Calculation | Explanation |
|---|---|---|---|---|
| CubeMX Settings (19 bits) | <span>A[19:1]</span> |
16-bit half-word | 2^19 * 2 = 1 MB | The number of address lines configured for the specific SRAM chip determines how much SRAM the current project can access. |
| STM32 Manual (A[0:25]) | <span>A[25:1]</span> |
16-bit half-word | 2^25 * 2 = 64 MB | The hardware maximum capability of the FMC controller. It supports up to 26 physical pins, allowing addressing up to 64MB for 16-bit devices. |
Why is the maximum value in CubeMX 19?
-
Actual Physical Limitations: The FMC pins of your STM32 chip model may not have all A[25:0] exposed. It may only expose A[19:1] or A[20:1], etc. CubeMX will display the maximum number of available address lines based on the specific model you select.
-
Common Capacities: 1MB (requiring A[19:1]) is a very large and common internal/external SRAM capacity. For larger capacities (like 4MB, requiring A[21:1]), you need to use a chip model that supports more address lines.
Final Conclusion:
There is absolutely no contradiction.
-
The manual tells you that the theoretical maximum capability of the FMC peripheral is 26 address lines, allowing connection to a maximum of 64MB of 16-bit memory.
-
CubeMX allows you to configure the actual number of address lines used in your specific project based on the SRAM chip capacity and MCU pin resources (for example, 19 bits corresponding to 1MB SRAM).
Your observation is very accurate; in the context of 16-bit SRAM, the 19-bit address in CubeMX corresponds exactly to the addressable space of 1MB.
From the above discussion, can we conclude that the STM32F407 can automatically handle the address access to SRAM, mapping the 1M byte address to the 512K half-word address in SRAM?
Your question is very precise and completely correct! Yes, the FMC (Flexible Memory Controller) of the STM32F407 does automatically handle this address mapping, mapping the 1MB byte address space issued by the CPU to the 512K half-word physical addresses of the external 16-bit SRAM.
Let’s break down this automatic mapping process in detail, which is key to understanding the STM32 memory controller.
Detailed Address Mapping Process
Assuming we configure the FMC to use 19 address lines (A[19:1]) to access a 1MB byte capacity 16-bit SRAM.
1. CPU Perspective (Software Perspective): 1MB Byte Address Space
-
The CPU sees a continuous byte array with address range from
<span>0x6000 0000</span>to<span>0x600F FFFF</span>(this is the starting address of FMC Bank1 NOR/PSRAM + 1MB). -
The CPU wants to access any address, for example:
-
<span>0x6000 0000</span>(byte 0) -
<span>0x6000 0001</span>(byte 1) -
<span>0x6000 0002</span>(byte 2) -
…
-
<span>0x600F FFFF</span>(byte 1,048,575)
2. SRAM Hardware Perspective: 512K Half-Word Storage Units
-
The SRAM chip internally is a half-word array, totaling 1MB / 2 = 524,288 storage units.
-
It uses 19 address lines (A[19:1]) to index these 524,288 locations.
-
Each location corresponds to a 16-bit data bus (D[15:0]).
3. FMC’s Automatic Conversion (Where the Magic Happens)
When the CPU issues a byte address, such as <span>0x6000 1234</span>, the FMC performs the following automatic conversion:
Step A: Decomposing the CPU Address
-
Subtract the base address from the CPU byte address (
<span>0x6000 0000</span>), resulting in an offset:<span>0x1234</span>. -
Decompose this offset (19 bits effective) into:
-
This bit determines whether to access the high byte or the low byte of this half-word.
-
Right shift by one bit, which is equivalent to dividing by 2. This is exactly what the SRAM chip needs to index its half-word storage units.
-
Address bits A[19:1]:
<span>0x1234 >> 1 = 0x91A</span> -
Lowest bit A[0]:
<span>0x1234 & 0x01 = 0x0</span>
Step B: Generating SRAM Physical Access
-
The FMC places the calculated
<span>0x91A</span>on the address bus<span>A[19:1]</span>. -
The FMC automatically activates the corresponding byte channel (NBL[1:0]) based on the value of
<span>A[0]</span>: -
If
<span>A[0] = 0</span>, access the low byte (possibly activating NBL0). -
If
<span>A[0] = 1</span>, access the high byte (possibly activating NBL1). -
If it is a 16-bit read/write (
<span>uint16_t</span>), both channels are activated.
A Specific Example
Assuming data <span>0xABCD</span> is stored at the half-word address <span>0x100</span> in SRAM.
-
The low byte is
<span>0xCD</span> -
The high byte is
<span>0xAB</span>
| CPU Access Address | FMC Automatic Conversion Process | What SRAM Sees | Data Read |
|---|---|---|---|
<span>0x6000 0200</span> (A[0]=0) |
Address Offset=0x200 Half-Word Address=0x200>>1=0x100 Byte Select=Low Byte | Address Lines A[19:1] = 0x100 Byte Enable = Low Active | 0xCD (from low 8 bits) |
<span>0x6000 0201</span> (A[0]=1) |
Address Offset=0x201 Half-Word Address=0x201>>1=0x100 Byte Select=High Byte | Address Lines A[19:1] = 0x100 Byte Enable = High Active | 0xAB (from high 8 bits) |
Write <span>uint16_t</span> to <span>0x6000 0200</span> |
Address Offset=0x200 Half-Word Address=0x200>>1=0x100 Byte Select=All | Address Lines A[19:1] = 0x100 Byte Enable = All Active | Write the entire 16-bit data <span>0xABCD</span>. |
Conclusion
So, your understanding is completely correct. The FMC hardware of the STM32F407 acts as a smart address translator:
-
It receives the byte address from the CPU.
-
By right-shifting the address (ignoring A[0]), it generates the half-word address for SRAM.
-
It uses the lowest address bit (A[0]) to generate the byte select signal.
This process is completely transparent to the programmer. In your C code, you can directly use <span>uint8_t</span>, <span>uint16_t</span> pointers to access external SRAM without manually performing address shift calculations; the FMC handles everything for you. This is why you can operate external SRAM as conveniently as internal memory.
So, the hardware connection is still FSMC_A0 connected to SRAM A0.
No, quite the opposite! This is a very critical and easily mistaken point.
When connecting 16-bit wide SRAM, the STM32’s FSMC_A0 should not be connected to SRAM’s A0.
The correct connection is:
-
STM32’s FSMC_A1 connected to SRAM’s A0
-
STM32’s FSMC_A2 connected to SRAM’s A1
-
And so on…
Why connect this way?
This is because the address “misalignment” needs to be reflected in the hardware connection to match the address mapping principle we just discussed.
Theoretical Analysis:
-
CPU Address:
<span>0x6000 0000</span>(byte address) -
Expected SRAM Half-Word Address:
<span>0x0000 0000</span>(half-word address) -
Conversion Relationship: SRAM Address = CPU Address >> 1
To allow <span>0x6000 0000</span> to access the 0th half-word of SRAM, the STM32’s address bus must right-shift by one bit.
Specific Connection Scheme:
| STM32 FSMC Pin | Connected to SRAM Pin | Description |
|---|---|---|
| FSMC_A[19:1] | SRAM_A[18:0] | Address Line Misalignment Connection |
| FSMC_A0 | Not Connected | Used for internal byte select signal generation |
| FSMC_NBL0, NBL1 | SRAM Byte Enable (UB/LB) | Control high/low byte access |
| FSMC_D[15:0] | SRAM_D[15:0] | 16-bit data bus |
Actual Connection Example
Assuming you want to connect a 1MB (512K × 16-bit) SRAM, requiring 19 address lines:
| STM32 FMC Pin | SRAM Pin | Address Value Correspondence |
|---|---|---|
| FMC_A1 | A0 | CPU Address bit1 → SRAM Address bit0 |
| FMC_A2 | A1 | CPU Address bit2 → SRAM Address bit1 |
| FMC_A3 | A2 | CPU Address bit3 → SRAM Address bit2 |
| … | … | … |
| FMC_A19 | A18 | CPU Address bit19 → SRAM Address bit18 |
| FMC_A0 | Not Connected | – |
| FMC_NBL0 | LB (Low Byte Enable) | – |
| FMC_NBL1 | UB (High Byte Enable) | – |
Verify this Connection
When the CPU accesses address <span>0x6000 0002</span>:
-
CPU Address Binary:
<span>... 0010</span>(bit1=1, bit0=0) -
After FMC right shifts by one bit:
<span>... 0001</span> -
FMC_A1 outputs 1, FMC_A0 not connected
-
SRAM sees A0=1, A1=0, etc. → Half-Word Address 1
This is exactly what we expect: byte addresses 2 and 3 map to half-word address 1 in SRAM.
Summary
Important Rule: For 16-bit wide memory, the STM32’s address bus starts connecting from A1, and A0 is left unconnected.
If you mistakenly connect FSMC_A0 to SRAM_A0, then:
-
All consecutive address accesses will be misaligned
-
Byte accesses will be completely confused
-
It is likely to cause system crashes
This “address line misalignment” connection is the standard practice for connecting 16-bit external memory to STM32 FMC/FSMC, as clearly stated in the official reference manual and application notes.
The statement in the chip manual does not align with your conclusion: If the external memory width is 16 bits, FSMC will use the internal HADDR[25:1] address as the addressing address for external memory FSMC_A[24:00]. Regardless of whether the external memory width is 16 bits or 8 bits, FSMC_A[0] should be connected to the external memory address A[0].
You are absolutely right! Thank you for your correction; my previous explanation indeed contained errors. The chip manual you quoted is completely correct, let me clarify this important connection issue again.
Correct Understanding: The Relationship Between HADDR and FSMC_A
The key is to understand the difference between HADDR (internal AHB address bus) and FSMC_A (external pin address bus):
-
HADDR[25:0]: This is the byte address from the Cortex-M core. It is the internal input of the FMC controller.
-
FSMC_A[24:0]: This is the word address output from the FMC controller to the external pins (for 16-bit devices, this is the half-word address).
Automatic Conversion Mechanism of the FMC Controller
When connecting to 16-bit external memory, the FMC automatically completes the following conversions:
-
Internal: The FMC receives
<span>HADDR[25:0]</span>(byte address). -
Conversion: The FMC directly maps
<span>HADDR[25:1]</span>to the<span>FSMC_A[24:0]</span>output pins. -
External:
<span>FSMC_A[24:0]</span>outputs to SRAM’s<span>A[24:0]</span>.
This means:
-
<span>FSMC_A[0]</span>corresponds to<span>HADDR[1]</span> -
<span>FSMC_A[1]</span>corresponds to<span>HADDR[2]</span> -
…
-
<span>FSMC_A[24]</span>corresponds to<span>HADDR[25]</span>
Why does the manual say “FSMC_A[0] should connect to external memory address A[0]”?
Because from the external SRAM’s perspective, it receives continuous word addresses:
-
When the CPU accesses addresses
<span>0x0</span>and<span>0x1</span>(two consecutive bytes):
-
<span>HADDR[1:0] = 00</span>and<span>01</span> -
<span>FSMC_A[0]</span>is 0 in both accesses -
SRAM sees
<span>A[0] = 0</span>, accessing the same 16-bit half-word
When the CPU accesses addresses <span>0x2</span> and <span>0x3</span>:
-
<span>HADDR[1:0] = 10</span>and<span>11</span> -
<span>FSMC_A[0] = 1</span> -
SRAM sees
<span>A[0] = 1</span>, accessing the next 16-bit half-word
Connection Example
For 16-bit SRAM, the correct connection is:
| STM32 FSMC Pin | SRAM Pin |
|---|---|
| FSMC_A[24:0] | SRAM_A[24:0] |
| FSMC_NBL0 | LB (Low Byte Enable) |
| FSMC_NBL1 | UB (High Byte Enable) |
Special Note: FSMC_A[0] connects to SRAM_A[0], FSMC_A[1] connects to SRAM_A[1], and so on—no misalignment connection is needed.
Summary
My previous explanation of “misalignment connection” was incorrect. The correct understanding is:
-
FMC hardware internally has already completed the address shift (
<span>HADDR[25:1]</span>→<span>FSMC_A[24:0]</span>). -
External hardware connections are direct (
<span>FSMC_A[0]</span>→<span>SRAM_A[0]</span>). -
Byte selection is controlled by FSMC_NBL0/NBL1.
The advantage of this design is that hardware connections are simple and intuitive, with all complex address conversions handled internally by the FMC controller.
Thank you very much for your correction! This highlights the importance of carefully reading the chip manual.