STM32F4 SPI1工作,SPI5不工作?
我得到了STM32 Nucleo-F410RB开发板,并且能够使我的外部DAC与SPI1一起工作,无论是忙等待还是使用DMA。然后,我设计了我自己的定制PCB,并构建了它并能够将其闪光。在设计阶段,我使用SPI1切换到SPI5,因为我需要SPI1引脚来实现其他功能。但是我无法让SPI5在我的新设计中工作 - SCK和MOSI引脚上没有信号。当我将代码更改为使用SPI1时,我在各个SPI1 SCK和MOSI引脚上看到信号。STM32F4 SPI1工作,SPI5不工作?
我回到了我的Nucleo板,并有同样的问题 - SPI1工作正常,但SPI5根本不起作用。我正在使用带有ARM GNU编译器的Eclipse和最新版本的标准外设库(不是HAL)。
SPI初始化函数:
void init_spi(void) {
//initialize MOSI and SCK pins
//initialize SPI
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Pin = GPIO_Pin_0; //SCK
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio_init);
gpio_init.GPIO_Pin = GPIO_Pin_8; //MOSI
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_SPI5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_SPI5);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//initialize DAC CS PIN
gpio_init.GPIO_Pin = DAC_CS_PIN;
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_OUT;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio_init);
SPI_I2S_DeInit(SPI5);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI5, ENABLE); //enable SPI clock
SPI_InitTypeDef spi_init;
spi_init.SPI_Direction = SPI_Direction_1Line_Tx;
spi_init.SPI_Mode = SPI_Mode_Master;
spi_init.SPI_DataSize = SPI_DataSize_8b; //8b? Need to clock in 24 bits of data per DAC channel
spi_init.SPI_CPOL = SPI_CPOL_Low; //5134 uses low to high and high to low clock transitions. ie. idle state is LOW
spi_init.SPI_CPHA = SPI_CPHA_2Edge; //clock phase - data is clocked on falling edge of clock pulse
spi_init.SPI_NSS = SPI_NSS_Soft; //DAC chip select is handled in software
spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //APB2 clock/2, so 25 MHz SPI clock speed
spi_init.SPI_FirstBit = SPI_FirstBit_MSB; //check datasheet
spi_init.SPI_CRCPolynomial = 7; //what is this?
SPI_Init(SPI5, &spi_init);
SPI_Cmd(SPI5, ENABLE);
}
SPI写功能:
void spi_write_dac(uint16_t value, uint8_t channel) { //currently just use busy/wait to transmit data to test DAC
uint8_t dac_low = value & 0xFF; //take bottom 8 bits
uint8_t dac_high = value >> 8; //take top 8 bits
GPIO_ResetBits(GPIOA, DAC_CS_PIN); //CS low
while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_TXE) == RESET);//wait for empty buffer
SPI_I2S_SendData(SPI5, channel); //send control byte
while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_BSY) == SET); //wait for byte to be sent
SPI_I2S_SendData(SPI5, dac_high); //send first data byte
while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_BSY) == SET); //wait for byte to be sent
SPI_I2S_SendData(SPI5, dac_low); //send second data byte
while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_BSY) == SET); //wait for byte to be sent
GPIO_SetBits(GPIOA, DAC_CS_PIN);
}
此代码不能正常工作,但是当我改变SPI1所有SPI5引用和使用PB3为SCK和PB5的MOSI然后SPI正在工作。我检查了SPI控制寄存器,他们看起来像是正确配置了SPI5,所以我开始接触到我的机智。
为什么SPI1可以在我自己的设计和Nucleo电路板上正常工作,但SPI5在任一电路板上都无法工作?
当您的所有参考都是针对SPI5外设的时,您的init_spi()
函数中的SPI_I2S_DeInit(SPI1);
是否正常?
如果我没有错,STM32的目标是一个STM32F410RBT6。我让这里的数据表和参考手册未来用途:
这是一个简单的答案。 SPI5没有映射到PB3及PB5 ...... 如果你看一下39页上的数据表(数据表第5版)的,你可以看到:
在PB3可以使用JTDO-SWO,I2C4_SDA, SPI1_SCK/I2S1_CK,USART1_RX,I2C2_SDA,事件输出,但没有SPI5
在PB5,您可以使用LPTIM1_IN1,I2C1_SMBA,SPI1_MOSI/I2S1_SD,事件输出,但没有SPI5
如果你真的想用SPI5,您可以使用以下IO:
SPI5_MISO:PA12
SPI5_MOSI:PA10或PB8
SPI5_SCK:PB0
谢谢你的回复。是的,我知道引脚映射。 PB3和PB5适用于SPI1,在我的SPI5示例代码中,我使用PB0和PB8设置SPI5(也尝试了PA10,但没有运气)。 – jrl8
我做了同样的错误。
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_SPI5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_SPI5);
对于STM32F410,GPIO_AF_SPI5必须是GPIO_AF6_SPI5。
#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */
是的,抱歉,这是一个错字(现在纠正)。基本上,当所有参考SPI1和SPI1引脚设置完成时,SPI1按预期工作,但将所有对SPI5的引用和使用SPI5引脚(PB0用于SCK和PB8用于MOSI)都不起作用。 – jrl8
是的,为了确认,这些分别是我正在使用的数据表和参考手册。 – jrl8