[STM32F1]

关于SPI_NSS_Hard的问题

[复制链接]
1614|6
手机看帖
扫描二维码
随时随地手机跟帖
shipeng1989|  楼主 | 2019-6-13 20:34 | 显示全部楼层 |阅读模式
spi, IO, gp, GPIO, ni
#ifdef        SPI3_NSS_HARD
#define SPI3_CS_ENABLE             SPI_Cmd(SPI3, ENABLE)
#define SPI3_CS_DISABLE            SPI_Cmd(SPI3, DISABLE)
#else
#define SPI3_CS_ENABLE             PAout(15)=0
#define SPI3_CS_DISABLE            PAout(15)=1
#endif

void SPI3_Configuration(void)
{
        SPI_InitTypeDef  SPI_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//JTAG Disable SWDP Enable

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3  |  GPIO_Pin_4  | GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        /* SPI: CS推挽输出 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        #ifdef        SPI3_NSS_HARD
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        #else
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        #endif
  GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* SPI 初始化定义 */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                      //设置为主 SPI
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  //SPI发送接收 8 位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                        //时钟悬空高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                       //数据捕获于第二个时钟沿
  #ifdef        SPI3_NSS_HARD
        SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;                          //硬件控制 NSS 信号
  #else
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                          //软件控制 NSS 信号
        #endif
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //波特率预分频值为2
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                 //数据传输从 MSB 位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;                           //定义了用于 CRC值计算的多项式
  SPI_Init(SPI3, &SPI_InitStructure);
        #ifdef        SPI3_NSS_HARD
        SPI_SSOutputCmd(SPI3, ENABLE);
        SPI_Cmd(SPI3, DISABLE);
        #else
        SPI_Cmd(SPI3, ENABLE);
        #endif
        
        DMA_Config();
}

如上定义宏SPI3_NSS_HARD配置为硬件控制NSS输出,现烧录两个硬件:一个是采用HSI+PLL时钟64MHz,另一个采用HSE+PLL时钟72MHz。


测试如下代码:


void SFLASH_FastReadNByte(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t nByte)
{
  while (PAin(15)==0);//Wait CS Disable
        SFLASH_WaitForNoBusy();
        SPI3_CS_ENABLE;                                 //使能器件
  SPI3_WriteByte(SFLASH_FAST_READ);               //《快读数据》指令
  SPI3_WriteByte((uint8_t)((ReadAddr)>>16));      //发送24bit地址
  SPI3_WriteByte((uint8_t)((ReadAddr)>>8));
  SPI3_WriteByte((uint8_t)ReadAddr);
  SPI3_WriteByte(0xFF);                           //等待8个时钟

  while(nByte--)                                 //循环读数
  {
    *pBuffer = SPI3_ReadByte();
    pBuffer++;
  }

  SPI3_CS_DISABLE;                                //失能器件
}

uint8_t SPI3_WriteByte(uint8_t TxData)
{
  while((SPI3->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
  SPI3->DR = TxData;

  while((SPI3->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);//发现程序会卡在此处
  return SPI3->DR;
}

发现64MHz硬件运行正常,但72MHz时钟硬件程序会卡在“while((SPI3->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);”导致异常复位,而如果不采用硬件控制NSS信号输出(即不定义宏SPI3_NSS_HARD)则都不会有此问题。到底是我的代码有bug还是在运行SPI_Cmd(SPI3, ENABLE)使能SPI后到SPI正常工作有延迟。请高人指教。

使用特权

评论回复
香水城| | 2019-6-13 22:09 | 显示全部楼层
#ifdef        SPI3_NSS_HARD
         SPI_SSOutputCmd(SPI3, ENABLE);
         SPI_Cmd(SPI3, DISABLE);               
         #else

你红色这句什么意思?要关闭SPI?

使用特权

评论回复
dongnanxibei| | 2019-6-14 00:23 | 显示全部楼层
楼主自己搞错了

使用特权

评论回复
shipeng1989|  楼主 | 2019-6-14 08:51 | 显示全部楼层
香水城 发表于 2019-6-13 22:09
#ifdef        SPI3_NSS_HARD
         SPI_SSOutputCmd(SPI3, ENABLE);
         SPI_Cmd(SPI3, DISABLE); ...

是这样的:如果配置为硬件控制NSS信号输出,则只要SPI使能NSS引脚即输出低电平,要让NSS输出高电平只有关闭SPI,不信大家可以去看一下手册。

使用特权

评论回复
kxsi| | 2019-6-19 11:30 | 显示全部楼层
因为控制信号没有过来呢把

使用特权

评论回复
labasi| | 2019-7-5 11:04 | 显示全部楼层
我极少用到这个引脚

使用特权

评论回复
wakayi| | 2019-7-5 11:34 | 显示全部楼层
程序好像有些问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

128

帖子

1

粉丝