STM32F0通过SPI驱动MAX7219点阵显示异常问题求助
问题解决:STM32F0通过SPI驱动MAX7219点阵无输出+函数隐式声明错误
一、先解决编译错误:SPI_I2S_SendData隐式声明
你的代码里注释掉了SPI头文件#include "stm32f0xx_spi.h",这直接导致编译器找不到SPI_I2S_SendData、SPI_I2S_GetFlagStatus等SPI函数的声明,必须取消注释:
#include "stm32f0xx_spi.h"
二、核心问题:引脚配置冲突与错误
你的硬件连接PA4是MAX7219的片选(CS),但代码里犯了两个致命错误:
- 错误将PA4定义为MISO引脚:MAX7219作为SPI从机,不需要回传数据,根本用不到MISO。你需要重新定义引脚宏:
/* SPI1 pin definition */ #define SPI1_SCK_PIN GPIO_Pin_5 // 对应硬件PA5 #define SPI1_MOSI_PIN GPIO_Pin_7 // 对应硬件PA7 #define SPI1_CS_PIN GPIO_Pin_4 // 对应硬件PA4(MAX7219的CS) #define SPI1_GPIO_PORT GPIOA #define SPI1_GPIO_CLK RCC_AHBPeriph_GPIOA
PA4被DAC代码错误配置为模拟模式:代码里的
main2和DAC_Setup是无关的冗余代码,其中DAC_Setup把PA4设置成了模拟输出,完全覆盖了你SPI初始化里的配置,直接导致CS引脚失效。必须删除或注释掉整个main2和DAC_Setup相关代码。正确配置CS引脚:CS引脚不需要复用为SPI功能,要配置成普通推挽输出,在
SPI1_Init里单独添加:
// 配置CS引脚为推挽输出 GPIO_InitStruct.GPIO_Pin = SPI1_CS_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 默认拉高,取消选中MAX7219 GPIO_Init(SPI1_GPIO_PORT, &GPIO_InitStruct);
三、SPI与MAX7219通信修正
- 移除重复初始化:
MAX7219_Init里重复调用了SPI1_Init,会导致配置被重置,删掉这行。 - 修正SPI复用配置:之前的代码错误配置了PinSource6(PA6)作为MISO,现在不需要MISO,直接删掉这行:
// 删掉这行,因为不用MISO // GPIO_PinAFConfig(SPI1_GPIO_PORT, GPIO_PinSource6, GPIO_AF_0); // MISO
- 优化通信等待逻辑:用
SPI_I2S_FLAG_TXE(发送缓冲区空)代替BSY标志,更准确判断发送完成:
/* Send data */ SPI_I2S_SendData(SPI1, reg); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, data); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); // 最后等待传输完全结束 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
修正后的完整核心代码
/****************************************************************************** * File : Main program - Single Mode *****************************************************************************/ #include "stm32f0xx.h" #include "stm32f0_discovery.h" #include "helper.h" #include "stm32f0xx_gpio.h" #include "stm32f0xx_spi.h" // 取消注释SPI头文件 /* SPI1 pin definition */ #define SPI1_SCK_PIN GPIO_Pin_5 // 硬件PA5 #define SPI1_MOSI_PIN GPIO_Pin_7 // 硬件PA7 #define SPI1_CS_PIN GPIO_Pin_4 // 硬件PA4(MAX7219 CS) #define SPI1_GPIO_PORT GPIOA #define SPI1_GPIO_CLK RCC_AHBPeriph_GPIOA /* MAX7219 command definitions */ #define MAX7219_NOOP 0x00 #define MAX7219_DIGIT0 0x01 #define MAX7219_DIGIT1 0x02 #define MAX7219_DIGIT2 0x03 #define MAX7219_DIGIT3 0x04 #define MAX7219_DIGIT4 0x05 #define MAX7219_DIGIT5 0x06 #define MAX7219_DIGIT6 0x07 #define MAX7219_DIGIT7 0x08 #define MAX7219_DECODEMODE 0x09 #define MAX7219_INTENSITY 0x0A #define MAX7219_SCANLIMIT 0x0B #define MAX7219_SHUTDOWN 0x0C #define MAX7219_DISPLAYTEST 0x0F /* Function prototypes */ void SPI1_Init(void); void MAX7219_Init(void); void MAX7219_SendData(uint8_t reg, uint8_t data); int main(void) { /* Initialize SPI1 */ SPI1_Init(); /* Initialize MAX7219 */ MAX7219_Init(); /* Main loop */ while (1) { /* Display a "H" character on the matrix */ MAX7219_SendData(MAX7219_DIGIT0, 0x7E); MAX7219_SendData(MAX7219_DIGIT1, 0x09); MAX7219_SendData(MAX7219_DIGIT2, 0x09); MAX7219_SendData(MAX7219_DIGIT3, 0x7E); MAX7219_SendData(MAX7219_DIGIT4, 0x00); MAX7219_SendData(MAX7219_DIGIT5, 0x00); MAX7219_SendData(MAX7219_DIGIT6, 0x00); MAX7219_SendData(MAX7219_DIGIT7, 0x00); } } /* Initialize SPI1 */ void SPI1_Init(void) { SPI_InitTypeDef SPI_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; /* Enable SPI1 and GPIOA clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); RCC_AHBPeriphClockCmd(SPI1_GPIO_CLK, ENABLE); /* Configure SPI1 pins: SCK, MOSI */ GPIO_InitStruct.GPIO_Pin = SPI1_SCK_PIN | SPI1_MOSI_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(SPI1_GPIO_PORT, &GPIO_InitStruct); /* Connect SPI1 pins to AF */ GPIO_PinAFConfig(SPI1_GPIO_PORT, GPIO_PinSource5, GPIO_AF_0); // SCK GPIO_PinAFConfig(SPI1_GPIO_PORT, GPIO_PinSource7, GPIO_AF_0); // MOSI /* Configure CS pin as push-pull output */ GPIO_InitStruct.GPIO_Pin = SPI1_CS_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(SPI1_GPIO_PORT, &GPIO_InitStruct); /* Configure SPI1 */ SPI_StructInit(&SPI_InitStruct); SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_Init(SPI1, &SPI_InitStruct); /* Enable SPI1 */ SPI_Cmd(SPI1, ENABLE); } /* Initialize MAX7219 */ void MAX7219_Init(void) { /* Send initialization data to MAX7219 */ MAX7219_SendData(MAX7219_SCANLIMIT, 0x07); // Display all digits MAX7219_SendData(MAX7219_DECODEMODE, 0x00); // No decoding MAX7219_SendData(MAX7219_SHUTDOWN, 0x01); // Normal operation MAX7219_SendData(MAX7219_DISPLAYTEST, 0x00); // No display test MAX7219_SendData(MAX7219_INTENSITY, 0x0F); // Maximum intensity } /* Send data to MAX7219 */ void MAX7219_SendData(uint8_t reg, uint8_t data) { /* Select MAX7219 */ GPIO_ResetBits(GPIOA, SPI1_CS_PIN); /* Send data */ SPI_I2S_SendData(SPI1, reg); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, data); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); // Wait for transfer complete while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET); /* Deselect MAX7219 */ GPIO_SetBits(GPIOA, SPI1_CS_PIN); }
最后检查硬件连接
确认MAX7219的:
- VCC接5V,GND接GND
- DIN接PA7(MOSI)
- CLK接PA5(SCK)
- CS接PA4
内容的提问来源于stack exchange,提问作者jmneedshelp
相关产品推荐
相关产品推荐

