打印
[STM32H7]

STM32H743的SPI使用DMA方式遇到的奇怪问题

[复制链接]
3574|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nch1766|  楼主 | 2019-9-6 17:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      不使用DMA方式的时候SPI可以正常读写到数据,使用了DMA方式后,第一包数据会正常发送/接收,从第二包数据开始,就无法中断了,在外部的引脚上也测量不到电平变化;
      如果将DMA模式由DMA_NORMAL改成DMA_CIRCULAR的话,引脚上就能看到波形了,但是目前外接的器件是SPI Flash,所以没办法用循环模式,现在也不知道问题出在哪里了,目前使用的HAL库已经更新到最新的V1.5版本了,还是不行;
     目前已经在这个问题上卡住快半个月了,有没有哪位大神路过救救我啊~~~~
void spiFlashPinConfig(void)
{
    GPIO_InitTypeDef gpioInit;

        __HAL_RCC_GPIOG_CLK_ENABLE();                   //使能GPIOJ时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();                   //使能GPIOC时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();                   //使能GPIOB时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                   //使能GPIOA时钟
        //初始化SPI时钟
    __HAL_RCC_SPI1_CLK_ENABLE();

    //SCK=PG11,  MISO=PG9
    gpioInit.Pin = GPIO_PIN_11 | GPIO_PIN_9;
    gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
    gpioInit.Pull = GPIO_PULLDOWN;
    gpioInit.Alternate = 5;
    gpioInit.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOG,&gpioInit);

    //MOSI=PB5
    gpioInit.Pin = GPIO_PIN_5;
    HAL_GPIO_Init(GPIOB,&gpioInit);

    //NSS=PA15
    gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
    gpioInit.Pin = GPIO_PIN_15;
    HAL_GPIO_Init(GPIOA,&gpioInit);

    gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
    gpioInit.Pin = SPI_FLASH_RST_Pin;
    HAL_GPIO_Init(GPIOC,&gpioInit);

    HAL_GPIO_WritePin(GPIOC, SPI_FLASH_RST_Pin, GPIO_PIN_RESET);

    sleep(100);

    HAL_GPIO_WritePin(GPIOC, SPI_FLASH_RST_Pin, GPIO_PIN_SET);
}

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
    if (hspi->Instance == SPI_PORT)
    {

        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能
        spiFlashPinConfig();

        /* Configure the DMA handler for Transmission process */
        dma_TxHandler.Instance                 = SPIx_TX_DMA_STREAM;
        dma_TxHandler.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
        dma_TxHandler.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
        dma_TxHandler.Init.MemBurst            = DMA_MBURST_SINGLE;
        dma_TxHandler.Init.PeriphBurst         = DMA_MBURST_SINGLE;
        dma_TxHandler.Init.Request             = SPIx_TX_DMA_REQUEST;
        dma_TxHandler.Init.Direction           = DMA_MEMORY_TO_PERIPH;
        dma_TxHandler.Init.PeriphInc           = DMA_PINC_DISABLE;
        dma_TxHandler.Init.MemInc              = DMA_MINC_ENABLE;
        dma_TxHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        dma_TxHandler.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
        dma_TxHandler.Init.Mode                = DMA_NORMAL;//DMA_CIRCULAR;//DMA_NORMAL;
        dma_TxHandler.Init.Priority            = DMA_PRIORITY_LOW;

        HAL_DMA_Init(&dma_TxHandler);

        /* Associate the initialized DMA handle to the the SPI handle */
        __HAL_LINKDMA(hspi, hdmatx, dma_TxHandler);

        /* Configure the DMA handler for Transmission process */
        dma_RxHandler.Instance                 = SPIx_RX_DMA_STREAM;
        dma_RxHandler.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
        dma_RxHandler.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
        dma_RxHandler.Init.MemBurst            = DMA_MBURST_SINGLE;
        dma_RxHandler.Init.PeriphBurst         = DMA_MBURST_SINGLE;
        dma_RxHandler.Init.Request             = SPIx_RX_DMA_REQUEST;
        dma_RxHandler.Init.Direction           = DMA_PERIPH_TO_MEMORY;
        dma_RxHandler.Init.PeriphInc           = DMA_PINC_DISABLE;
        dma_RxHandler.Init.MemInc              = DMA_MINC_ENABLE;
        dma_RxHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        dma_RxHandler.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
        dma_RxHandler.Init.Mode                = DMA_NORMAL;//DMA_CIRCULAR;//DMA_NORMAL;
        dma_RxHandler.Init.Priority            = DMA_PRIORITY_HIGH;

        HAL_DMA_Init(&dma_RxHandler);

        /* Associate the initialized DMA handle to the the SPI handle */
        __HAL_LINKDMA(hspi, hdmarx, dma_RxHandler);

        /* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
        HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1);
        HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn);

        /* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */
        HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn);

    }
}

void spiFlashInit( )
{

        // SPI配置
        ETH_SPI_CS_HIGH;
    spiHandle.Instance = SPI_PORT;                //SP1
    spiHandle.Init.Mode = SPI_MODE_MASTER;          //设置SPI工作模式,设置为主模式
    spiHandle.Init.Direction = (0x0U << SPI_CFG2_COMM_Pos);//SPI_DIRECTION_2LINES_TXONLY;//SPI_DIRECTION_2LINES;//设置SPI单向或者双向的数据模式:SPI设置为双线模式
    spiHandle.Init.DataSize = SPI_DATASIZE_8BIT;    //设置SPI的数据大小:SPI发送接收8位帧结构
    spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平 电路中下拉
    spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;      //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    spiHandle.Init.NSS = SPI_NSS_SOFT;       //NSS信号由软件管理
    spiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;//NSS信号脉冲失能
    spiHandle.Init.IOSwap = SPI_IO_SWAP_DISABLE;//SPI_IO_SWAP_ENABLE;
    spiHandle.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
    spiHandle.Init.MasterInterDataIdleness = SPI_MASTER_SS_IDLENESS_02CYCLE;
    spiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;  //SPI主模式IO状态保持使能
    spiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为16
    spiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;     //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    spiHandle.Init.TIMode = SPI_TIMODE_DISABLE;     //关闭TI模式
    spiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    spiHandle.Init.CRCPolynomial = 7;               //CRC值计算的多项式

    HAL_SPI_Init(&spiHandle);
    __HAL_SPI_ENABLE(&spiHandle);

    memset(spiFlashRxBuffer, 0, SPI_FLASH_BUF_LEN);
    memset(spiFlashTxBuffer, 0, SPI_FLASH_BUF_LEN);

}

使用特权

评论回复
沙发
香水城| | 2019-9-9 09:42 | 只看该作者
你说的第一包数据具体有多少个? 发完第一包数据后应该是什么操作?

使用特权

评论回复
板凳
nch1766|  楼主 | 2019-9-9 12:30 | 只看该作者
香水城 发表于 2019-9-9 09:42
你说的第一包数据具体有多少个? 发完第一包数据后应该是什么操作?

第一包数据目前我试过发送一个自己,到十个字节都是有波形的;
发送/接收完成后进入DMA发送/接收中断,目前是等待5ms,在中断服务程序中并清除发送/接收完成标志位,然后拷贝数据到另外一个缓存空间,加上上面的代码就是所有的了,请问有什么建议么?

static void spiWRFlashDataDma(uint16_t len)
{
    spiHandle.State = HAL_SPI_STATE_READY;
    spiHandle.hdmarx->State = HAL_DMA_STATE_READY;
    spiHandle.hdmatx->State = HAL_DMA_STATE_READY;
    __HAL_UNLOCK(spiHandle.hdmarx);
    __HAL_UNLOCK(spiHandle.hdmatx);
    HAL_SPI_TransmitReceive_DMA(&spiHandle, spiFlashTxBuffer, spiFlashRxBuffer, len);
}


void DMA1_Stream3_IRQHandler(void)    //发送完成DMA
{
    uint32_t isrFlag = 0;

    asm("nop");

    isrFlag = __HAL_DMA_GET_FLAG(&dma_TxHandler, (0x3F << 24));


    if((isrFlag & DMA_FLAG_TCIF3_7) != RESET)//DMA传输完成
    {
        //清除DMA传输完成中断标志位
        __HAL_DMA_CLEAR_FLAG(&dma_TxHandler, DMA_FLAG_TCIF3_7);
        isrFlag &= ~DMA_FLAG_TCIF3_7;
    }

    if(isrFlag != RESET)//如果还有其他DMA传输错误
    {
        __HAL_DMA_CLEAR_FLAG(&dma_TxHandler, isrFlag);//清除传输错误中断标志位
    }
    CLEAR_BIT(SPI_PORT->CFG1, SPI_CFG1_TXDMAEN);
}

void DMA1_Stream4_IRQHandler(void)   //接收完成DMA
{
    uint32_t isrFlag = 0;

    asm("nop");

    isrFlag = __HAL_DMA_GET_FLAG(&dma_RxHandler, (0x3F << 0));


    if((isrFlag & DMA_FLAG_TCIF0_4) != RESET)//DMA传输完成
    {
        __HAL_DMA_CLEAR_FLAG(&dma_RxHandler, DMA_FLAG_TCIF0_4);//清除DMA传输完成中断标志位
        isrFlag &= ~DMA_FLAG_TCIF0_4;
    }


    if(isrFlag != RESET)//如果还有其他DMA传输错误
    {
        __HAL_DMA_CLEAR_FLAG(&dma_RxHandler, isrFlag);//清除传输错误中断标志位
    }
    CLEAR_BIT(SPI_PORT->CFG1, SPI_CFG1_RXDMAEN);
}

uint8_t spiReadFlashSR(void)
{
    spiFlashTxBuffer[0] = FLASH_CMD_READ_SR1;
    ETH_SPI_CS_LOW;                            //使能器件
    spiWRFlashDataDma(1);         //发送读取状态寄存器命令
    sleep(5);
    spiFlashTxBuffer[0] = 0xFF;
    spiWRFlashDataDma(1);          //读取一个字节
    sleep(5);
    ETH_SPI_CS_HIGH;
    return spiFlashRxBuffer[0];

}

使用特权

评论回复
地板
香水城| | 2019-9-23 12:03 | 只看该作者
我这边使用相同的开发板,分别就几个SPI都做了测试,使用DMA传输,

不论是循环还是非循环模式,都可以正常运行。

使用特权

评论回复
5
buffered| | 2019-9-24 15:12 | 只看该作者
还是DMA的配置没有弄好吧应该

使用特权

评论回复
6
coshi| | 2019-10-12 11:57 | 只看该作者
换成普通模式呢

使用特权

评论回复
7
磨砂| | 2019-10-12 12:36 | 只看该作者
是不是配置的问题

使用特权

评论回复
8
aoyi| | 2019-10-13 08:35 | 只看该作者
不太用过dma

使用特权

评论回复
9
drer| | 2019-10-13 09:05 | 只看该作者
帮楼主顶一下吧

使用特权

评论回复
10
kxsi| | 2019-10-13 10:25 | 只看该作者
我一般就用普通模式就够用了

使用特权

评论回复
11
方孔恩| | 2020-5-6 16:30 | 只看该作者
香水城 发表于 2019-9-23 12:03
我这边使用相同的开发板,分别就几个SPI都做了测试,使用DMA传输,

不论是循环还是非循环模式,都可以正常 ...

兄台,能不能看下我的spi传输的代码,我的dma传输一直收不到数据,请看看有什么问题,谢谢了
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
          GPIO_InitTypeDef GPIO_Initure;
    RCC_PeriphCLKInitTypeDef SPI2ClkInit;
       
          __HAL_RCC_SPI2_CLK_ENABLE();                    //使能SPI2时钟                  
                __HAL_RCC_GPIOB_CLK_ENABLE();
                __HAL_RCC_GPIOF_CLK_ENABLE();                                                                                //使能GPIOF时钟

                SPI2ClkInit.PeriphClockSelection=RCC_PERIPHCLK_SPI2;          
                SPI2ClkInit.Spi123ClockSelection=RCC_SPI123CLKSOURCE_PLL;       
                HAL_RCCEx_PeriphCLKConfig(&SPI2ClkInit);

                __HAL_RCC_DMA1_CLK_ENABLE();

    //PB13,15 (SCK|MISO|MOSI)
    GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;              //复用推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;   //快速   
    GPIO_Initure.Alternate=GPIO_AF5_SPI2;           //复用为SPI2
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);             //初始化
       
                //PB9(NSS引脚,用作其他)
                GPIO_Initure.Pin=GPIO_PIN_9;
          GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;     //高速
                HAL_GPIO_Init(GPIOB,&GPIO_Initure);   
               
                //W25Q256片选信号拉高,防止W25Q256干扰
                GPIO_Initure.Pin=GPIO_PIN_10;                         //PF10
                HAL_GPIO_Init(GPIOF,&GPIO_Initure);     //初始化
               
                 
          /*##-3- Configure the DMA ##################################################*/
    /* Configure the DMA handler for Transmission process */
    hdma_tx.Instance                 = SPIx_TX_DMA_STREAM;
                hdma_tx.Init.Request             = SPIx_TX_DMA_REQUEST;
    hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
    hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
//    hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
//    hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
    hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma_tx.Init.Mode                = DMA_CIRCULAR;
    hdma_tx.Init.Priority            = DMA_PRIORITY_HIGH;

    HAL_DMA_Init(&hdma_tx);

    /* Associate the initialized DMA handle to the the SPI handle */
    __HAL_LINKDMA(hspi, hdmatx, hdma_tx);

    /* Configure the DMA handler for Transmission process */
    hdma_rx.Instance                 = SPIx_RX_DMA_STREAM;
    hdma_rx.Init.Request             = SPIx_RX_DMA_REQUEST;
    hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
    hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
//    hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
//    hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
    hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma_rx.Init.Mode                = DMA_CIRCULAR;
    hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;

    HAL_DMA_Init(&hdma_rx);

    /* Associate the initialized DMA handle to the the SPI handle */
    __HAL_LINKDMA(hspi, hdmarx, hdma_rx);
   
    /*##-4- Configure the NVIC for DMA #########################################*/
    /* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
    HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1);
    HAL_NVIC_DisableIRQ(SPIx_DMA_TX_IRQn);
   
    /* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */
    HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn);
}

void SPI2_Init(void)
{
    SPI2_Handler.Instance=SPI2;                      //SP2
    SPI2_Handler.Init.Mode=SPI_MODE_MASTER ;         //设置SPI工作模式,设置为主模式
    SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES;//设置SPI单向或者双向的数据模式:SPI设置为双线模式
    SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT;    //设置SPI的数据大小:SPI发送接收8位帧结构
    SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平
    SPI2_Handler.Init.CLKPhase=SPI_PHASE_1EDGE;      //串行同步时钟的第1个跳变沿(此处指上升沿)数据被采样
       
    SPI2_Handler.Init.NSS=SPI_NSS_SOFT;              //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制,主模式SSI必须置位1
    SPI2_Handler.Init.NSSPMode=SPI_NSS_PULSE_DISABLE;//NSS输出信号脉冲失能,配置成主模式才有用,目的是让ns引脚成为普通IO
                SPI2_Handler.Init.NSSPolarity=SPI_NSS_POLARITY_LOW;
       
                //SPI2_Handler.Init.MasterInterDataIdleness=SPI_MASTER_SS_IDLENESS_15CYCLE;
                //SPI2_Handler.Init.s = SPI_MASTER_SS_IDLENESS_04CYCLE;
       
       
    SPI2_Handler.Init.MasterKeepIOState=SPI_MASTER_KEEP_IO_STATE_ENABLE;  //SPI主模式IO状态保持使能
    SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16;//定义波特率预分频的值:波特率预分频值为16
    SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;     //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE;     //关闭TI模式
    SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    SPI2_Handler.Init.CRCPolynomial=7;               //CRC值计算的多项式
                if (HAL_SPI_DeInit(&SPI2_Handler) != HAL_OK)
                {
                        printf("error\t\n");
                }
  if(HAL_SPI_Init(&SPI2_Handler) != HAL_OK)
  {
    /* Initialization Error */
    printf("error\t\n");
        }
        __HAL_SPI_ENABLE(&SPI2_Handler);

         SPI2_ReadWriteByte(0Xff);                        //启动传输
}


在主程序中,
if(HAL_SPI_TransmitReceive_DMA(&SPI2_Handler, (uint8_t *)SpiTxBuffer, (uint8_t *)SpiRxBuffer, BUFFERSIZE) != HAL_OK)
        {
                        printf("error\t\n");
        }
        //printf("");
        while(1)
        {

        }

而且又设置了
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
        SCB_InvalidateDCache_by_Addr ((uint32_t *)SpiRxBuffer, BUFFERSIZE);
       
        printf("Received: %s \t\n", SpiRxBuffer);
       
        //HAL_SPI_DMAStop(&SPI2_Handler);
}


但是进入中断接收时,一直为空,这是什么原因呢?

使用特权

评论回复
12
香水城| | 2020-5-7 15:55 | 只看该作者
本帖最后由 香水城 于 2020-5-7 16:03 编辑
方孔恩 发表于 2020-5-6 16:30
兄台,能不能看下我的spi传输的代码,我的dma传输一直收不到数据,请看看有什么问题,谢谢了

你注意下 数据缓冲区 是否是你配置的DMA可以到达的地方。
基于STM32H7 DMA传输的SPI 应用示例

使用特权

评论回复
13
方孔恩| | 2020-5-9 11:17 | 只看该作者
香水城 发表于 2020-5-7 15:55
你注意下 数据缓冲区 是否是你配置的DMA可以到达的地方。
基于STM32H7 DMA传输的SPI 应用示例
...

多谢兄弟,这个我看了,我自己用库函数写的spi—dma的代码,主机的miso和mosi相连,是可以接收到自己发的数据的,但是正常连接之后,在从机上面就收不到主机发的东西了,一直为0,我从机的代码跟主机没有多少区别的,在之前的spi中断方式试可以实现的,但是不知道这个为啥不能

使用特权

评论回复
14
香水城| | 2020-7-5 22:37 | 只看该作者
方孔恩 发表于 2020-5-9 11:17
多谢兄弟,这个我看了,我自己用库函数写的spi—dma的代码,主机的miso和mosi相连,是可以接收到自己发的 ...

方小弟,你的这个问题还没解决吗? 我看你是2019年9月发的贴了。

使用特权

评论回复
15
lemonwind| | 2020-9-24 06:42 | 只看该作者
我也碰到相同的问题了,请问楼主解决了吗?

使用特权

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

本版积分规则

1

主题

4

帖子

0

粉丝