You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F407VGT6 SPI通信问题求助

STM32F407VGT6 SPI通信问题求助

我刚接触STM32不久,现在正尝试让SPI通信正常工作。我把SPI配置为主机模式,启用了软件从机管理,并且设置成了主机单向发送的单工通信格式。

但我尝试往SPI数据寄存器(DR)里加载数据时,通过调试器观察发现DR根本没有变化。希望能得到大家的帮助!

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define RCC_BASE_ADDR           0x40023800U
#define SPI_1_BASE_ADDR         0x40013000U
#define GPIO_A_BASE_ADDR        0x40020000U

// Register Address Offsets
// RCC
#define RCC_CR_OFFSET           0x00U
#define RCC_AHB_1_EN_OFFSET     0x30U
#define RCC_APB_1_EN_OFFSET     0x40U
#define RCC_APB_2_EN_OFFSET     0x44U

// SPI
#define SPIx_CR_1               0x00U
#define SPIx_CR_2               0x04U
#define SPIx_SR                 0x08U
#define SPIx_DR                 0x0CU
//#define SPIx_RX                   0x14U
//#define SPIx_TX                   0x18U
#define SPIx_CFGR               0x1CU

// GPIO
#define MODE_R                  0x00U       // Mode of GPIO
#define OTYPE_R                 0x04U       // Output type of GPIO
#define OSPEED_R                0x08U       // Output speed
#define PUPD_R                  0x0CU       // input Config (Pull Up/Down)
#define IDR                     0x10U       // input Data reg
#define ODR                     0x14U       // Output Data reg
#define AFLR                    0x20U       // Alternate function GPIOx[0:7]
#define AFHR                    0x24U       // Alternate function GPIOx[8:15]

// Bit position offsets
// RCC
//AHB1_EN
#define GPIO_A                  0

// APB1_EN
#define SPI_1                   12

// SPI
// CR1
#define BIDIMODE                15
#define BIDIOE                  14
#define DFF                     11
#define RXONLY                  10
#define SSM                     9
#define SSI                     8
#define LSBFIRST                7
#define SPE                     6
#define BAUD                    5       // [Width : 3]
#define MSTR                    2
#define CPOL                    1
#define CPHA                    0

// CR2
#define TXE                     1       // Transfer buffer status

// SR
// GPIOx

// Global vars
// ** RCC
// Enable register for APB2 buss
uint32_t* rcc_apb2_en = (uint32_t*) (RCC_BASE_ADDR + RCC_APB_2_EN_OFFSET);
uint32_t* rcc_ahb1_en = (uint32_t*) (RCC_BASE_ADDR + RCC_AHB_1_EN_OFFSET);

// ** GPIO
// GPIO Mode register
uint32_t* gpio_a_mode   = (uint32_t*) (GPIO_A_BASE_ADDR + MODE_R);
// GPIO Alternate function Selection register (LOW)
uint32_t* gpio_aflr     = (uint32_t*) (GPIO_A_BASE_ADDR + AFLR);

// ** SPI
// SPI Control Register 1
uint32_t* spi_cr1 = (uint32_t*) (SPI_1_BASE_ADDR + SPIx_CR_1);
// SPI Status register
uint32_t* spi_sr = (uint32_t*)  (SPI_1_BASE_ADDR + SPIx_SR);
// SPI data register
uint32_t* spi_dr = (uint32_t*)  (SPI_1_BASE_ADDR + SPIx_DR);

// Configure GPIO pins A5 (SCLK) and A7 (MOSI)
void GpioInit(){
    // Enable GPIO A on ahb1 bus
    *rcc_ahb1_en |= (0x1 << GPIO_A);

    // Set the mode for pins 5 and 6 on port A to their alternate functionality
    *gpio_a_mode |= (0x2 << 10) | (0x2 << 14);

    // Set Pin5 as Serial clock and pin7 as MOSI
    *gpio_aflr |= (0x5 << 20) | (0x5 << 28);
}

void SPI_init(){
    // Enable SPI on RCC clock
    *rcc_apb2_en |= (0x1 << SPI_1);

    // Reference to CR1 register in SPI 1 address region
    // Configure SPI as for 2 wire unidirectional mode aka full duplex transmission
    *spi_cr1 &= ~(0x1 << BIDIMODE);

    // Set Data frame as 16 bits wide
    *spi_cr1 |= (0x1 << DFF);

    // Not implemented
    // Internal slave select
    // Transfer is LSB first

    // Enable SPI
    // Enable software slave management
    *spi_cr1 |= (0x1 << SSM);

    // Set SSI to high to avoid mode fault
    *spi_cr1 |= (0x1 << SSI);

    // Set baud rate as default DIV2
    *spi_cr1 &= ~(0x7 << BAUD);

    // Configure as master
    *spi_cr1 |= (0x1 << MSTR);

    //  Set to mode 0
    *spi_cr1 &= ~(0x3 << CPHA);
}

void SPIx_write(uint8_t* value, uint8_t len){
    // Check the value of the DFF register
    uint8_t dff_val = ( (uint32_t)(*spi_cr1) >> DFF) & 0x1;

    // 16 Bit transmission
    if(dff_val){
        while(len > 0){
            // Check the status of the TX register
            // If empty, then transfer 2 bytes
            if(1 /*( (*spi_sr)  >> TXE ) & 0x1 */){
                // transfer first 2 bytes
                //              *spi_dr = *((uint16_t*) value);
                *spi_dr = *((uint16_t*) value);
                // decrement by 2
                len-=2;
                // Move to next 2 bytes
                (uint16_t*)value++;
                continue;
            }
            // If not empty then delay
            for(uint8_t i = 0; i < 2; i++);
        }
    }
    // 8 Bit transmission
    else{
        while(len){
            // Check the status of the TX register
            // If empty, then transfer 1 byte
            if( (*spi_sr) & (0x1 << TXE) ){
                // transfer first byte
                *spi_dr = *value;
                // decrement by 1
                len--;
                // Move to next byte
                value++;
                continue;
            }
            // If not empty then delay
            for(uint8_t i = 0; i < 2; i++);
        }
    }
}

int main(void)
{
    char data[] = "hello";

    GpioInit();     // Initialize GPIO pins 5 & 7
    SPI_init();         // SPI instantiate

    // Enable the SPI for communication
    *spi_cr1 |= (0x1 << SPE);

    // Write to SPI data reg
    SPIx_write((uint8_t*)data, strlen(data));

    /* Loop forever */
    for(;;);
}

备注:内容来源于stack exchange,提问作者Grimmace_23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 09:57:44