还没有用过STM32的SPI功能, 所以想尝试着做做看.
以前做串口通信都是用中断方式做的, 所以做SPI通信, 首先想到的就是用中断方式做, 网上有一些例程, 但是好像也有没有解释的很清楚的, 至少我没有理解.
以下我将从自己的认知来写一下, 大神绕过, 小白可以看看, 来看看是否有你自己的盲点, 本文也只是描述我自己碰到的问题的点, 不包含整个代码.
1. 关于GPIO口模式的设置
输出口没有什么可说的, 都是GPIO_Mode_AF_PP, 但是输入口模式, 需要注意, 网上有的教程是让设置成GPIO_Mode_IN_FLOATING, 实测这个模式不行, 需要使用GPIO_Mode_IPU模式, 使用floating模式时, 我监控接收到的数跟主机发送过来的数有出入, 有时候不一样, 改成IPU模式, 没有异常. 不要轻信网上的一些帖子, 别拿他们的当教条!! 要持怀疑态度.
以下是我初始化SPI的代码
//因为SPI1的输出要靠PA5&PA6&PA7来完成, 所以须先初始化PA5&PA6&PA7的工作模式
//注意SPI引脚是否和JATG口或者SWD口复用.
//先初始化引脚的模式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //初始化管脚的工作模式之前不写这一句也可以
//初始化管脚
//PA5_SPI1_CLK
PAx.GPIO_Pin = GPIO_Pin_5;
PAx.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
//PAx.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_Mode_IN_FLOATING;
PAx.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &PAx);
//PA6_SPI1_MISO
PAx.GPIO_Pin = GPIO_Pin_6;
PAx.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP;
PAx.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &PAx);
//PA7_SPI1_MOSI
PAx.GPIO_Pin = GPIO_Pin_7;
PAx.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
//PAx.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_Mode_IN_FLOATING;
PAx.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &PAx);
//打开外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
//初始化SPI相关寄存器
SPIxInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPIxInit.SPI_Mode = SPI_Mode_Slave;
SPIxInit.SPI_DataSize = SPI_DataSize_8b;
SPIxInit.SPI_CPOL = SPI_CPOL_Low;
SPIxInit.SPI_CPHA = SPI_CPHA_1Edge;
SPIxInit.SPI_NSS = SPI_NSS_Soft;
SPIxInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPIxInit.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPIxInit);