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
相关产品推荐
相关产品推荐

