打印
[N32G430]

SPI片选相关问题

[复制链接]
287|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
用示波器去抓波形的时候发现片选会在时钟和MOSI前面就拉高片选信号,此时我的函数发送数据都还没开始执行片选就拉高了,主要的问题还是时序不同步,请教下大家这是什么问题导致的具体的配置如下
#include "./flash/spi.h"

void spi_gpio_init(void)
{
    GPIO_InitType GPIO_InitStructure;

    RCC_Pclk2_Config(RCC_HCLK_DIV2);

    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_SPI2);

    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA|RCC_AHB_PERIPH_GPIOB);

    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);


    GPIO_Structure_Initialize(&GPIO_InitStructure);

    // SPI_MISO  PA9 AF1  ||SPI_CLK  PA10 AF6 ||SPI_MOSI   PB1 AF2 ||SPI_CS  PA15  ||
    GPIO_InitStructure.Pin            = SPI_MISO;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF1_SPI2;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);


    GPIO_InitStructure.Pin            = SPI_MOSI;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_SPI2;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);

    /* If CLKPOL is HIGH, set SPI_SCK GPIO to GPIO_PULL_UP, otherwise set to GPIO_PULL_DOWN */
    GPIO_InitStructure.Pin            = SPI_CLK;   
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_SPI2;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);


    // GPIO_InitStructure.Pin          = SPI_CS;
    // GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_OUT_PP;
    // GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
    // GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);


}

void spi_gpio_cs_init(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_InitStructure.Pin          = SPI_CS;
    GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_OUT_PP;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);
}


void spi_init(void)
{
    SPI_InitType SPI_InitStructure;

    spi_gpio_init();
    spi_gpio_cs_init();
    SPI_I2S_Reset(SPI2);

    SPI_Initializes_Structure(&SPI_InitStructure);
    SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
    SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;
    SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;
    SPI_InitStructure.CLKPOL        = SPI_CLKPOL_HIGH;
    SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;
    SPI_InitStructure.NSS           = SPI_NSS_SOFT;
    /* It is recommended that the SPI master mode of the C version chips should not exceed 18MHz */
    SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_256;
    SPI_InitStructure.FirstBit      = SPI_FB_MSB;
    //SPI_InitStructure.CRCPoly       = 7;
    SPI_Initializes(SPI2, &SPI_InitStructure);
    SPI_SS_Output_Enable(SPI2);
    /* Enable SPI_MASTER */
     SPI_Set_Nss_Level(SPI2,SPI_NSS_HIGH);

    SPI_ON(SPI2);

    SPI_CS_HIGH();
}


uint8_t spi_tramsit_receive(uint8_t data)
{
   uint8_t brxbuff;
//    printf("data = %2X\n",(uint16_t)data);
   SPI_I2S_Data_Transmit(SPI2,data);
   while(SPI_I2S_Flag_Status_Get(SPI2, SPI_I2S_FLAG_TE) == SET);
   brxbuff = SPI_I2S_Data_Get(SPI2);
   while(SPI_I2S_Flag_Status_Get(SPI2, SPI_I2S_FLAG_BUSY) != SET) ;
   return brxbuff;
}
**/

下面主要是main函数中的内容和宏定义
#define SPI_CS_HIGH()   GPIO_Pins_Set(GPIOA,GPIO_PIN_15);
#define SPI_CS_LOW()    GPIO_Pins_Reset(GPIOA,GPIO_PIN_15);
//PA
#define SPI_MISO    GPIO_PIN_9
#define SPI_CLK     GPIO_PIN_10
#define SPI_CS      GPIO_PIN_15
//PB
#define SPI_MOSI    GPIO_PIN_1



uint32_t spi_read_id(void)
{
   uint32_t data = 0 ;
   uint8_t receiveid[3] = {0x00};
   uint8_t id = 0;
   SPI_CS_LOW();
   spi_tramsit_receive(0x01);
   receiveid[0] = spi_tramsit_receive(0X01);
   receiveid[1] = spi_tramsit_receive(0X01);
   receiveid[2] = spi_tramsit_receive(0X01);
   SPI_CS_HIGH();

   data =  receiveid[0] <<16 |receiveid[1]<<8  | receiveid[2];
   return id ;

}


int main(void)
{
    uint8_t data = 0xAA;
    uint32_t id = 0;
    uart_init();   
    spi_flash_init();
    while(1)
    {
         id = spi_read_id();
         printf("id = %d",id);
        SysTick_Delay_Ms(1000);


   }
}

使用特权

评论回复
沙发
春风知意|  楼主 | 2023-12-11 17:20 | 只看该作者
这是时序图

微信截图_20231211171655.png (103.7 KB )

微信截图_20231211171655.png

微信截图_20231211171655.png (103.7 KB )

微信截图_20231211171655.png

使用特权

评论回复
板凳
jobszheng| | 2023-12-12 08:50 | 只看该作者
我看您在初始化配置SPI时,有使能硬件CS引脚。您将这个disable掉,即使用手动GPIO控制CS引脚,和当前的一样。
这行代码:
SPI_SS_Output_Enable(SPI2);

使用特权

评论回复
评论
春风知意 2023-12-12 09:27 回复TA
您好,在屏蔽后也是类似的波形,麻烦您帮我看下是不是漏掉哪些关键关键的配置导致的? 
地板
春风知意|  楼主 | 2023-12-12 09:27 | 只看该作者
您好,在屏蔽后也是类似的波形,是不是漏掉哪些关键关键的配置导致的?

使用特权

评论回复
5
delin17| | 2023-12-12 11:57 | 只看该作者
发送前,是不是应该清一下标志?

使用特权

评论回复
6
春风知意|  楼主 | 2023-12-12 16:00 | 只看该作者
delin17 发表于 2023-12-12 11:57
发送前,是不是应该清一下标志?

这里应该是不用清楚的,因为提供的接口里面没有这部分状态标志位

使用特权

评论回复
7
jobszheng| | 2023-12-12 18:00 | 只看该作者
https://bbs.21ic.com/icview-3294508-1-1.html
这个是我之前发布的读写TF卡时使用SPI外设的初始化代码

使用特权

评论回复
8
jobszheng| | 2023-12-12 18:02 | 只看该作者
uint8_t bsp_spi_sendbyte(uint8_t dat)
{
  /*!< Loop while DAT register in not emplty */
  while (SPI_I2S_GetStatus(SPI1, SPI_I2S_TE_FLAG) == RESET)
    ;

  /*!< Send byte through the SPI1 peripheral */
  SPI_I2S_TransmitData(SPI1, dat);

  /*!< Wait to receive a byte */
  while (SPI_I2S_GetStatus(SPI1, SPI_I2S_RNE_FLAG) == RESET)
    ;

  /*!< Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI1);
}
这个是使用官方提供的固件库进行的读写API。
以上代码经验证通过。



使用特权

评论回复
9
春风知意|  楼主 | 2023-12-13 10:58 | 只看该作者
jobszheng 发表于 2023-12-12 18:02
这个是使用官方提供的固件库进行的读写API。
以上代码经验证通过。

问题我找到了,感谢您的回复,提早的上拉是因为我收发的那个函数判断标志位有问题,需要判断发送接收,而不能判断忙碌,再次十分感谢您的回复

使用特权

评论回复
10
春风知意|  楼主 | 2023-12-13 11:06 | 只看该作者
春风知意 发表于 2023-12-13 10:58
问题我找到了,感谢您的回复,提早的上拉是因为我收发的那个函数判断标志位有问题,需要判断发送接收,而 ...

关于您提到官方提供的固件库,您方便分享官方库链接给我吗,我参考的官方库里面没有收发这些api,只是简单的示例。

使用特权

评论回复
11
jobszheng| | 2023-12-13 13:52 | 只看该作者
楼主,您现在应该就使用的是官方的固件库在编写。
在ftp://download.nationstech.com 这个FTP里面,对应的型号文件夹里面的
类似 Nationstech.N32G45x_Library.2.1.0 这个文件夹

使用特权

评论回复
12
春风知意|  楼主 | 2023-12-13 14:10 | 只看该作者
jobszheng 发表于 2023-12-13 13:52
楼主,您现在应该就使用的是官方的固件库在编写。
在ftp://download.nationstech.com 这个FTP里面,对应的 ...

是的,我这里的显示的版本是1.2.1

使用特权

评论回复
13
两只袜子| | 2023-12-15 15:34 | 只看该作者
可能是硬件方面的问题

使用特权

评论回复
14
jcky001| | 2023-12-15 15:34 | 只看该作者
如果片选信号的拉高是由驱动或固件控制的,那么可能是驱动或固件中的某些设置或代码导致了这个问题。

使用特权

评论回复
15
cr315| | 2023-12-15 15:35 | 只看该作者
调整示波器设置

使用特权

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

本版积分规则

11

主题

41

帖子

0

粉丝