DMA SPI/EXMC 刷屏

本文详细描述了如何在C代码中使用DMA(DirectMemoryAccess)控制器DMA0的两个通道(DMA_CH1和DMA_CH2)与SPI0进行数据传输,包括初始化、配置DMA模式、传输过程控制和标志处理等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void SPI0_DMA0_read(uint16_t *buf, int len)
{
    
    dma_parameter_struct dma_init_struct;
    uint32_t  dummy=0xffff;
    int num=len;
    uint8_t i=0;
        /* enable DMA0 */
    rcu_periph_clock_enable(RCU_DMA0);
    _START:
    dma_deinit(DMA0, DMA_CH1);
    dma_deinit(DMA0, DMA_CH2);
    spi_dma_disable(SPI0,SPI_DMA_TRANSMIT);
    int lenTemp=50000;
    #if 0 
    while(len>0)//len%50000)//分包 //bug?
    {
        if(len>=50000)lenTemp=50000;
        else lenTemp=len;
        dma_deinit(DMA0, DMA_CH1);
        dma_deinit(DMA0, DMA_CH2);
        dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
        dma_init_struct.memory_addr  = (uint32_t)dummy;
        dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
        dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;//DMA_MEMORY_WIDTH_16BIT;
        dma_init_struct.periph_width = DMA_MEMORY_WIDTH_8BIT;//DMA_PERIPHERAL_WIDTH_16BIT;
        dma_init_struct.priority     = DMA_PRIORITY_HIGH;
        dma_init_struct.number       =  lenTemp-1;///lenTemp;
        dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
        dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;//DMA_MEMORY_INCREASE_ENABLE;
        dma_init(DMA0, DMA_CH2, &dma_init_struct);
     //   dma_circulation_disable(DMA0, DMA_CH2);
        dma_circulation_disable(DMA0, DMA_CH2);
        dma_memory_to_memory_disable(DMA0, DMA_CH2);
        
        //dma_channel_disable(DMA0, DMA_CH1);
        dma_deinit(DMA0, DMA_CH1);
        dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
        dma_init_struct.memory_addr  = ((uint32_t)buf)+((uint32_t)(i*50000-1));//-(i*1);//(uint32_t)&buf;

        dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
        dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;//DMA_MEMORY_WIDTH_16BIT;
        dma_init_struct.periph_width = DMA_MEMORY_WIDTH_8BIT;//DMA_PERIPHERAL_WIDTH_16BIT;
        dma_init_struct.priority     = DMA_PRIORITY_HIGH;
        dma_init_struct.number       =  lenTemp;
        dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
        dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
        dma_init(DMA0, DMA_CH1, &dma_init_struct);
        dma_memory_to_memory_disable(DMA0, DMA_CH1);
        /* configure DMA mode */
        
        dma_circulation_disable(DMA0, DMA_CH1);
        dma_memory_to_memory_disable(DMA0, DMA_CH1);
    //    dma_memory_address_config(DMA0, DMA_CH1,&buf);///
    //    dma_flag_clear(DMA0,DMA_CH1, DMA_FLAG_FTF);//DMA0->IFCR = (uint32_t)(DMA2_FLAG_GL2);
    ////     SPI_CTL0(SPI0) |= (uint32_t)(1<<15);
    //     SPI_CTL0(SPI0) |=  (uint32_t)(1<<10);//spi  mode receive only;SPI_Direction_2Lines_RxOnly;
    //         //SPI_CTL0(SPI0) &= ~(uint32_t)(1<<14);//spi mode Rx only ;SPI_Direction_2Lines_RxOnly
        dma_channel_enable(DMA0, DMA_CH2);
        dma_channel_enable(DMA0, DMA_CH1);
        spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
        spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
    
    
    //    dma_memory_address_config(DMA0,DMA_CH1, (uint32_t)  &buf);
//    SPI_CTL0(SPI0)|=(uint32_t)SPI_CTL1_DMAREN;//SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
    
    
     
    // SPI0->DR;/spi_i2s_data_transmit( SPI0,  0xff  );
         while(!dma_flag_get(DMA0,DMA_CH1, DMA_FLAG_FTF));//while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
         
    //      while(!spi_i2s_flag_get(SPI0,SPI_FLAG_TBE));
         //while(spi_i2s_flag_get(SPI0,SPI_FLAG_TRANS));
         dma_flag_clear(DMA0,DMA_CH1,DMA_FLAG_FTF);
         dma_flag_clear(DMA0,DMA_CH2,DMA_FLAG_FTF);
         i++;
         if(len>=50000)
            len-=50000; 
         else len=0;
    
//     buf+=50000;
//     len-=50000;
    }
     #endif
     int temp_len=0;
 while(len>0)
{
    if(len>65000)temp_len=65000;
    else temp_len=len;
    /* SPI0 transmit dma config:DMA0-DMA_CH2  */
     dma_deinit(DMA0, DMA_CH2);
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
    dma_init_struct.memory_addr  = (uint32_t)dummy;
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;//DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_MEMORY_WIDTH_8BIT;//DMA_PERIPHERAL_WIDTH_16BIT;
    
    dma_init_struct.priority     = DMA_PRIORITY_HIGH;
    //dma_init_struct.number       =  len>65535?65535:len-1;//len;//len;
    
    dma_init_struct.number       =  temp_len-2;//len>65000?65000:len;//len;//len;
    
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;//DMA_MEMORY_INCREASE_ENABLE;
    dma_init(DMA0, DMA_CH2, &dma_init_struct);
    dma_circulation_disable(DMA0, DMA_CH2);
//    dma_circulation_enable(DMA0, DMA_CH2);
    dma_memory_to_memory_disable(DMA0, DMA_CH2);
    
    //dma_channel_disable(DMA0, DMA_CH1);
    dma_deinit(DMA0, DMA_CH1);
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
    dma_init_struct.memory_addr  = (uint32_t)(BANK0_LCD_D);//(uint32_t)buf; 

    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;//DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_MEMORY_WIDTH_8BIT;//DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_HIGH;
    dma_init_struct.number       = temp_len-3;// len>65000?65000:len;//len;//
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;//ENABLE;
    dma_init(DMA0, DMA_CH1, &dma_init_struct);
    dma_memory_to_memory_disable(DMA0, DMA_CH1);
    
    /* configure DMA mode */
    
    dma_circulation_disable(DMA0, DMA_CH1);
    dma_memory_to_memory_disable(DMA0, DMA_CH1);
//    dma_memory_address_config(DMA0, DMA_CH1,&buf);///
    dma_flag_clear(DMA0,DMA_CH2,DMA_FLAG_FTF);
    dma_flag_clear(DMA0,DMA_CH1,DMA_FLAG_FTF);
    //dma_transfer_number_config(DMA0,DMA_CH1,len>65000?65000:len);
    //dma_transfer_number_config(DMA0,DMA_CH2,len>65000?65000:len);
  //DMA0->IFCR = (uint32_t)(DMA2_FLAG_GL2);
////     SPI_CTL0(SPI0) |= (uint32_t)(1<<15);
//     SPI_CTL0(SPI0) |=  (uint32_t)(1<<10);//spi  mode receive only;SPI_Direction_2Lines_RxOnly;
//         //SPI_CTL0(SPI0) &= ~(uint32_t)(1<<14);//spi mode Rx only ;SPI_Direction_2Lines_RxOnly
    dma_channel_enable(DMA0, DMA_CH2);
    dma_channel_enable(DMA0, DMA_CH1);
    spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
    spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
    
    
    //    dma_memory_address_config(DMA0,DMA_CH1, (uint32_t)  &buf);
//    SPI_CTL0(SPI0)|=(uint32_t)SPI_CTL1_DMAREN;//SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
    
     
    int  timeout=1000000;//50 ~80 ms
     while(!dma_flag_get(DMA0,DMA_CH1, DMA_FLAG_FTF)  ) //卡死 ?while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
     {
          while(!spi_i2s_flag_get(SPI0,SPI_FLAG_TBE));
          while(spi_i2s_flag_get(SPI0,SPI_FLAG_TRANS));
         if(dma_transfer_number_get(DMA0,DMA_CH1)==0||dma_transfer_number_get(DMA0,DMA_CH2)==0)
         {
                  __ASM("NOP");
             break;
    
         }
         
        //if(spi_i2s_flag_get(SPI0,SPI_FLAG_TBE)){}// while(spi_i2s_flag_get(SPI0,SPI_FLAG_TRANS));
        // if(--timeout==0)goto _START; //
         //else delay_1ms(1);//break;
     }
    dma_flag_clear(DMA0,DMA_CH2,DMA_FLAG_FTF);
    dma_flag_clear(DMA0,DMA_CH1,DMA_FLAG_FTF);
    dma_channel_disable(DMA0,DMA_CH1);
    dma_channel_disable(DMA0,DMA_CH2);
     //if(len>65000)    len-=65000;
     //else len=0;
     len -= temp_len;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值