打印

stm32f2 spi从模式使用DMA传输,不停进中断?郁闷了!求指点

[复制链接]
10510|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
戒指320|  楼主 | 2013-3-16 00:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,主机端使用103的片子配置成spi主模式,从机端使用f205 DMA方式收发,但是只要从机这段进入了相应的中断,就不停的进入,而且进去了以后我 查看中断悬起位还是0。 中断悬起位是0,竟然还会进中断。比较郁闷,求指点。
附上代码

static  DMA_InitTypeDef    DMA_InitStructureTx;
static  DMA_InitTypeDef    DMA_InitStructureRx;

static  SPI_InitTypeDef  SPI_InitStructure;

static void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure the SPI interrupt priority */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;//spi1 rx;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Configure the SPI interrupt priority */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn;//spi1 tx;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);       
}

static void SPI_RCC_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

  /*!< Connect SPI pins to AF5 */  
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);       
  // NSS CLK MISO
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
  /* MOSI        
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
*/
  /* SPI configuration -------------------------------------------------------*/
  SPI_I2S_DeInit(SPI1);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;               
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;       
  
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  
  SPI_CalculateCRC(SPI1,DISABLE);
  SPI_Init(SPI1, &SPI_InitStructure);

  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
       
  SPI_Cmd(SPI1, ENABLE);                /* 使能SPI  */
}

void DMA_Config(void)
{

        //发送通道
        DMA_DeInit(DMA2_Stream3);
        DMA_InitStructureTx.DMA_Channel = DMA_Channel_3;
        DMA_InitStructureTx.DMA_PeripheralBaseAddr =(u32)&SPI1->DR;//SPI1的DR寄存器地址
        DMA_InitStructureTx.DMA_Memory0BaseAddr = 0;//(u32)SPI1_TX_Buf;
        DMA_InitStructureTx.DMA_DIR = DMA_DIR_MemoryToPeripheral;  
        DMA_InitStructureTx.DMA_BufferSize = 1;
        DMA_InitStructureTx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructureTx.DMA_MemoryInc = DMA_MemoryInc_Enable;  //DMA内存地址自动增加模式
        DMA_InitStructureTx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructureTx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructureTx.DMA_Mode = DMA_Mode_Normal;   
        DMA_InitStructureTx.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructureTx.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructureTx.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
    DMA_InitStructureTx.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructureTx.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;       
        DMA_Init(DMA2_Stream3, &DMA_InitStructureTx);

         DMA_ITConfig(DMA2_Stream3, DMA_IT_TC, ENABLE);
     DMA_Cmd(DMA2_Stream3, DISABLE);

        //接收通道
        DMA_DeInit(DMA2_Stream2);
        DMA_InitStructureRx.DMA_Channel = DMA_Channel_3;
        DMA_InitStructureRx.DMA_PeripheralBaseAddr =(u32)&SPI1->DR;//SPI2的DR寄存器地址
        DMA_InitStructureRx.DMA_Memory0BaseAddr = 0;//(u32)SPI2_RX_Buf;
        DMA_InitStructureRx.DMA_DIR = DMA_DIR_PeripheralToMemory;  
        DMA_InitStructureRx.DMA_BufferSize = 10;
        DMA_InitStructureRx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructureRx.DMA_MemoryInc = DMA_MemoryInc_Enable;  //DMA内存地址自动增加模式
        DMA_InitStructureRx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructureRx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructureRx.DMA_Mode = DMA_Mode_Normal;   
        DMA_InitStructureRx.DMA_Priority = DMA_Priority_High;
    DMA_InitStructureRx.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructureRx.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
    DMA_InitStructureRx.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructureRx.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;               
        DMA_Init(DMA2_Stream2, &DMA_InitStructureRx);

    /* Enable SPI DMA Tx request */

     DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);
     DMA_Cmd(DMA2_Stream2, DISABLE);
         
                 DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2);      //清DMA发送完成标志
        DMA_ClearFlag(DMA2_Stream3,DMA_FLAG_TCIF3);      //清DMA发送完成标志

}
int dummy[2];
//dir =0 接收data   = 1 发送pcm
void DMA_Transmit(u32 addr, u32 size, u8 dir)
{
        if (dir==1)
        {//发送 tx
                DMA_Cmd(DMA2_Stream3, DISABLE);

                DMA_InitStructureTx.DMA_Memory0BaseAddr = addr;
                DMA_InitStructureTx.DMA_BufferSize = size;
                DMA_Init(DMA2_Stream3, &DMA_InitStructureTx);
       
                DMA_Cmd(DMA2_Stream3, ENABLE);
        }
        else
        {//接收 rx
                DMA_Cmd(DMA2_Stream2, DISABLE);

                DMA_InitStructureRx.DMA_Memory0BaseAddr = addr;
                DMA_InitStructureRx.DMA_BufferSize = size;
                DMA_Init(DMA2_Stream2, &DMA_InitStructureRx);
               
                DMA_Cmd(DMA2_Stream2, ENABLE);
        }       
}


unsigned char SPI_TX_Buf[10005];
unsigned char SPI_RX_Buf[10005];

void rt_hw_spi_init(void)
{
        SPI_RCC_GPIO_Config();
        NVIC_Configuration();
        DMA_Config();

        DMA_Transmit((u32)SPI_RX_Buf, sizeof(SPI_RX_Buf)-5, 0);
}



void DMA2_Stream2_IRQHandler(void)//rx  主机发送
{

  /* Check the interrupt source */
  if (DMA_GetITStatus(DMA2_Stream2,DMA_FLAG_TCIF2)==SET)
  {
             DMA_ClearITPendingBit(DMA2_Stream2,DMA_FLAG_TCIF2|DMA_FLAG_TEIF2);
   
      DMA_Cmd(DMA2_Stream2, DISABLE);
          rt_kprintf(" spi rx done!\r\n");
       
  }
}

void DMA2_Stream3_IRQHandler(void)//tx   主机接收
{
       
  if (DMA_GetITStatus(DMA2_Stream3,DMA_FLAG_TCIF3)==SET)
  {
             DMA_ClearITPendingBit(DMA2_Stream3,DMA_FLAG_TCIF3|DMA_FLAG_TEIF3);
          rt_kprintf(" spi tx done!\r\n");
   
      DMA_Cmd(DMA2_Stream3, DISABLE);
       
  }
}

沙发
airwill| | 2013-3-16 12:35 | 只看该作者
不停进入, 很可能是中断标志没有清除

使用特权

评论回复
板凳
戒指320|  楼主 | 2013-3-16 12:59 | 只看该作者
airwill 发表于 2013-3-16 12:35
不停进入, 很可能是中断标志没有清除

我进入中断后,没发现中断标志被置位

使用特权

评论回复
地板
airwill| | 2013-3-16 13:25 | 只看该作者
也没有说进的是什么中断, 调试器进入中断去看中断标志寄存器吧

使用特权

评论回复
5
戒指320|  楼主 | 2013-3-16 22:50 | 只看该作者
airwill 发表于 2013-3-16 13:25
也没有说进的是什么中断, 调试器进入中断去看中断标志寄存器吧

呵呵,发现中断标示全是0  。就郁闷在这里

使用特权

评论回复
6
戒指320|  楼主 | 2013-3-16 22:51 | 只看该作者
谁能指点下,谢谢了!

使用特权

评论回复
7
戒指320|  楼主 | 2013-3-16 23:58 | 只看该作者
指点下 送3.2寸 触摸屏

使用特权

评论回复
8
戒指320|  楼主 | 2013-3-16 23:58 | 只看该作者
:D

使用特权

评论回复
9
hawksabre| | 2013-3-17 11:02 | 只看该作者
可能是中断触发电平选择不对  这个有可能   换个触发电平试试

使用特权

评论回复
10
hawksabre| | 2013-3-17 11:03 | 只看该作者
实在搞不定  就找FAE   直接打电话  看看他们的指导建议  呵呵

使用特权

评论回复
11
戒指320|  楼主 | 2013-3-17 11:10 | 只看该作者
hawksabre 发表于 2013-3-17 11:03
实在搞不定  就找FAE   直接打电话  看看他们的指导建议  呵呵

使用的是spi 从接收,不用触发电平的选择的。

使用特权

评论回复
12
戒指320|  楼主 | 2013-3-17 11:16 | 只看该作者
FAE联系方式 谁能提供一个??

使用特权

评论回复
13
p1093| | 2013-3-22 15:00 | 只看该作者
碰到一樣問題
data sheet指出spi transmit完成需要三個確認步驟
TCIF=1 -> TXE=1 -> BSY=0

直接改為check BSY flag可避開


使用特权

评论回复
14
hqfmcu201| | 2013-5-16 17:23 | 只看该作者
谢谢分享经验

使用特权

评论回复
15
cjhk| | 2013-5-16 18:50 | 只看该作者
问题搞定了就好   多逛21ic     真的学到了很多东西

使用特权

评论回复
16
1044132648| | 2017-11-30 15:32 | 只看该作者
从机的输出不应该是MISO吗,楼主怎么是MISO

使用特权

评论回复
17
5768340| | 2017-12-15 16:11 | 只看该作者
请问楼主解决了吗 ?

使用特权

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

本版积分规则

个人签名:淘宝小店: http://shop73275611.taobao.com

37

主题

290

帖子

2

粉丝