STM32F1 CubeMX配置I2C DMA调用HAL_I2C_Mem_Xxx_DMA函数异常求助
Hey Frank, let's troubleshoot why your LIS35 DMA init is throwing errors—since you already got the non-DMA I2C path working, we can narrow this down efficiently. Here are the most likely issues and fixes to try:
1. Validate CubeMX DMA Configuration
- Double-check you’ve assigned the correct DMA channels for your I2C peripheral. For STM32F1, I2C1 TX/RX typically map to DMA1 Channel 6/7, but confirm this in your STM32F1 reference manual to be safe.
- Set DMA mode to Normal (not Circular) unless you’re doing continuous streaming—sensor initialization is a one-time write, so Normal mode is the right choice here.
- Match DMA Data Width to your I2C settings: if you’re using 8-bit I2C transactions, set DMA Data Width to Byte.
- Ensure Memory Increment Mode is enabled (you’ll be writing multiple consecutive register bytes) and Peripheral Increment Mode is disabled (I2C peripheral registers don’t increment automatically).
2. Check HAL Initialization Order
- In your code, make sure you initialize the DMA peripheral before the I2C peripheral or calling
LIS35_I2C_Init(). CubeMX’s generated code usually handles this correctly, but if you’ve rearranged the init order, it can cause silent failures during sensor init. - Verify that
__HAL_RCC_DMA1_CLK_ENABLE()(or the appropriate DMA clock enable macro for your setup) runs beforeHAL_I2C_Init()and your sensor init function.
3. Debug the
LIS35_I2C_Init() Logic - Break down what your init function is doing with DMA. If you swapped to
HAL_I2C_Mem_Write_DMA()from the working blocking call, check these details:- Device address: Don’t forget the read/write bit shift. The LIS35’s 7-bit base address is usually 0x18, so the write address is
0x18 << 1= 0x30, and read is 0x31—confirm this with your sensor’s datasheet. - Register address length: LIS35 uses 8-bit register addresses, so pass
I2C_MEMADD_SIZE_8BITto the DMA write function. - Buffer validity: Ensure you’re passing a valid buffer pointer and correct length for the init registers (like writing to the control register to enable measurement mode).
- Device address: Don’t forget the read/write bit shift. The LIS35’s 7-bit base address is usually 0x18, so the write address is
- Add breakpoints or debug prints to capture the return value of
HAL_I2C_Mem_Write_DMA()—it might return a specific HAL error (e.g.,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT) that points directly to the root cause.
4. Confirm DMA Interrupt Setup
- Make sure DMA interrupts for your TX/RX channels are enabled in CubeMX’s NVIC Settings. If the DMA IRQ isn’t enabled, the transfer won’t complete, and your init function will likely time out or return an error.
- If your init logic waits for DMA completion, ensure you’ve implemented the required callback functions (like
HAL_I2C_MemWriteCpltCallback()) or that you’re correctly pollingHAL_I2C_GetState()until it’s no longerHAL_I2C_STATE_BUSY_TX.
5. Rule Out Hardware/Timing Issues
- Even though non-DMA works, double-check your I2C pull-up resistors—DMA transfers are more sensitive to timing glitches. For 100kHz standard mode, use 4.7k-10kΩ resistors.
- Temporarily lower the I2C clock speed from 400kHz fast mode to 100kHz standard mode to eliminate timing-related DMA transfer failures.
Quick Isolation Test
Replace the DMA write in LIS35_I2C_Init() with the working blocking HAL_I2C_Mem_Write() call temporarily. If it works, the problem is definitely in your DMA setup. Then reintroduce DMA step-by-step, verifying each configuration setting as you go.
内容的提问来源于stack exchange,提问作者frank
相关产品推荐
相关产品推荐

