经过几天探索、查找甄别网上别人的代码,终于达成可以在一块STM32F4芯片上用SPI1与SPI2通信的功能,spi做主,spi2做从,连线方式为:PA4 ---- PB12 (NSS) , PA5 ---- PB13 (SCK), PA6 ---- PB14(MISO), PA7 ---- PB15 (MOSI)
SPI1部分:
void init_SPI1(){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (1U << 5) | (1U << 6) | (1U << 7) ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,5,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,6,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,7,GPIO_AF_SPI1);
uint16_t tempreg = 0;
SPI_DeInit(SPI1);
tempreg = SPI1->CR1;
tempreg &= 0x3040;
tempreg |= (uint16_t)((uint32_t)SPI_Direction_2Lines_FullDuplex | SPI_Mode_Master |
SPI_DataSize_8b | SPI_CPOL_High |
SPI_CPHA_2Edge| SPI_NSS_Soft |
SPI_BaudRatePrescaler_4 | SPI_FirstBit_MSB);
SPI1->CR1 = tempreg;
SPI1->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
SPI1->CRCPR = 7;
SPI1->CR1 |= SPI_CR1_SPE;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (1U << 4) ;//用的是PA4,实际情况可随意用其它未复用的IO
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIOA->BSRRL |= (1U << 4); //PA4 写高电平
}
SPI2部分:
void init_SPI2(){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (1U << 13) | (1U << 14) | (1U <<15) ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB,13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,14,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,15,GPIO_AF_SPI2);
uint16_t tempreg = 0;
SPI_DeInit(SPI2);
tempreg = SPI2->CR1;
tempreg &= 0x3040;
tempreg |= (uint16_t)((uint32_t)SPI_Direction_2Lines_FullDuplex | SPI_Mode_Master |
SPI_DataSize_8b | SPI_CPOL_High |
SPI_CPHA_2Edge| SPI_NSS_Soft |
SPI_BaudRatePrescaler_4 | SPI_FirstBit_MSB);
SPI2->CR1 = tempreg;
SPI2->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
SPI2->CRCPR = 7;
SPI2->CR1 |= SPI_CR1_SPE;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (1U << 12) ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
传输函数部分,SPIx可以是SPI1或SPI2
u8 SPIx_transferByte(u8 data){
u8 retry=0;
while((SPIx->SR & SPI_I2S_FLAG_TXE)==0 && retry <= 0xFF)
{
retry++;
}
SPIx->DR = data;
retry=0;
while((SPIx->SR & SPI_I2S_FLAG_RXNE)==0 && retry <= 0xFF)
{
retry++;
}
return (SPIx->DR & 0x00FF);
}
主函数部分
int main(){
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB,ENABLE);
init_SPI1();
init_SPI2();
u16 data1 =0,data2=0;
while(1){
GPIOA->BSRRH |= (1U << 4); //PA4 写低电平
data1 = SPIx_transferByte(0x11);
data2= SPIx_transferByte(0x22);
GPIOA->BSRRL |= (1U << 4); //PA4 写高电平
delay(10);//wait 0.01s
}
} |