项目场景:
STM32F407
固件库编程
SPI | SPI1 |
---|---|
MOSI | PA7 |
MISO | PA6 |
SCK | PA5 |
问题描述:
STM32F407使用固件库调试SPI的时候,写了一个发送数据的函数,如下
uint16_t SPI_SendByte(uint16_t byte)
{
/*!< Loop while DR register in not empty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, byte);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/*!< Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
发现程序卡死在SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET处,示波器测量SPI CLK端口也没有波形。
原因分析:
经过几个小时的调试发现存在两个问题
1.GPIO_PinAFConfig(AD_PORT, AD_SCLK, GPIO_AF_SPI1);
将SPI连接到GPIO的时候,将下面函数的GPIO_PinSource参数误传为GPIO_Pin
void GPIO_PinAFConfig ( GPIO_TypeDef * GPIOx,
uint16_t GPIO_PinSource,
uint8_t GPIO_AF
)
;
#define AD_PORT GPIOA
#define AD_SCLK GPIO_Pin_5
#define AD_DOUT GPIO_Pin_6
#define AD_DIN GPIO_Pin_7
GPIO_PinAFConfig(AD_PORT, AD_SCLK, GPIO_AF_SPI1);
GPIO_PinAFConfig(AD_PORT, AD_DOUT, GPIO_AF_SPI1);
GPIO_PinAFConfig(AD_PORT, AD_DIN, GPIO_AF_SPI1);
查看宏定义之后发现:
#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */
#define GPIO_PinSource0 ((uint8_t)0x00)
#define GPIO_PinSource1 ((uint8_t)0x01)
#define GPIO_PinSource2 ((uint8_t)0x02)
#define GPIO_PinSource3 ((uint8_t)0x03)
#define GPIO_PinSource4 ((uint8_t)0x04)
#define GPIO_PinSource5 ((uint8_t)0x05)
#define GPIO_PinSource6 ((uint8_t)0x06)
#define GPIO_PinSource7 ((uint8_t)0x07)
#define GPIO_PinSource8 ((uint8_t)0x08)
#define GPIO_PinSource9 ((uint8_t)0x09)
#define GPIO_PinSource10 ((uint8_t)0x0A)
#define GPIO_PinSource11 ((uint8_t)0x0B)
#define GPIO_PinSource12 ((uint8_t)0x0C)
#define GPIO_PinSource13 ((uint8_t)0x0D)
#define GPIO_PinSource14 ((uint8_t)0x0E)
#define GPIO_PinSource15 ((uint8_t)0x0F)
GPIO_Pin和GPIO_PinSource这两种参数的宏定义是不同的,不能混用。
2.RCC_AHB2PeriphClockCmd (RCC_APB2Periph_SPI1 , ENABLE);
开启SPI的时钟时,将RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1 , ENABLE) 误写为RCC_AHB2PeriphClockCmd ( RCC_APB2Periph_SPI1 , ENABLE ) ,出现这种错误编译器也不报错,肉眼又很难检查出来。
void RCC_APB2PeriphClockCmd ( uint32_t RCC_APB2Periph,
FunctionalState NewState
)
SPI1、SPI4、SPI5、SPI6都是挂载在APB2总线上的设备,最高通信速率达 42Mbtis/s,SPI2、SPI3 是 APB1 上的设备,最高通信速率达 21Mbtis/s.
解决方案:
1.将GPIO_PinAFConfig(AD_PORT, AD_SCLK, GPIO_AF_SPI1);中AD_SCLK改为AD_SCLK_Source: GPIO_PinSource5
2.将RCC_AHB2PeriphClockCmd (RCC_APB2Periph_SPI1 , ENABLE);
改为RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1 , ENABLE);