程序在SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET处卡死

项目场景:

STM32F407
固件库编程

SPISPI1
MOSIPA7
MISOPA6
SCKPA5

问题描述:

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);

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值