精华内容
下载资源
问答
  • 串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负 在使用串口接受数据时,如果用while在主函数等待,或者用if在主函数判断,传输少量的标志位可以,程序效率很低,如果用DMA+单字节串口接受中断,这样效率高了...

    串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负
    在使用串口接受数据时,如果用while在主函数等待,或者用if在主函数判断,传输少量的标志位可以,程序效率很低,如果用DMA+单字节串口接受中断,这样效率高了,但是当我们需要不间断传输大量数据时,单片机频繁进入中断,有时会影响main()函数的运行,如果采用串口总线空闲触发中断+DMA传输,可以完美的解决这两个问题。
    USART_SR寄存器的IDLE位该位的作用时当检测到总线空闲时触发中断,用此标志位我们可以在传输完一帧数据时进入一次中断,这样进入中断次数缩减,main()效率增加
    代码如下:

    /********************************************************************************
      * @file    LSYY_Usart_Api.c
      * @author  绿水颖颖
      * @version V1.0
      * @date    2017.7.26
      * @brief   传输大量数据时  空闲中断+DMA传输 为CPU减负
      ******************************************************************************
      * @attention 
      *
      * 
    ********************************************************************************/
    #include "LSYY_Usart_Api.h"
    #include "LSYY_usart.h"
    #include "LSYY_led.h"
    
    /*内存池*/
    uint8_t DMA_Rece_Buf[USART_RX_BUFF_SIZE];
    
    /*
     *函数名`  : void USURT1_Config(void)
     *描述        :配置USART1
     *输入        :无
     *输出        :无
     */
    
    void USART_Config(void)
    {
        GPIO_InitTypeDef GPIO_InitStructure ;
        USART_InitTypeDef USART_InitStructure ;
    
        //开启串口的时钟
        DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK ,ENABLE);
        //开启GPIO的时钟
        DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE);
        //配置串口1的寄存器
    
        //配置串口1所对应的GPIO口    
        //配置模式 复用推挽输出模式
    
        GPIO_InitStructure.GPIO_Pin=DEBUG_USART_TX_GPIO_PIN;
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP ;
        //配置输出速率
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        //初始化GPIO口
        GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
    
    
        //配置串口1GPIO口的模式
        //GPIOA10
        //GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PORT_PIN;
        GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PIN;
        //配置串口模式
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ;
        //初始化GPIOA
        GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);
    
        //配置串口
        //设置波特率
        USART_InitStructure.USART_BaudRate =DEBUG_USART_BAUDRATE ;
        //设置传输字节
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        //设置停止标志位
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        //配置奇偶校检位,不设置
        USART_InitStructure.USART_Parity=USART_Parity_No;
        //配置硬件控制流,不配置
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None ;
        //配置串口模式
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx ;
        //初始化串口1
        USART_Init(DEBUG_USARTx  ,&USART_InitStructure);
    
        /****************************************************注意**************************************************/
    
    
        /*开启空闲中断*/
        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
        /*开启DMA传输数据*/
        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);   
        //使能串口
        USART_Cmd(DEBUG_USARTx  ,ENABLE);
        USART_ClearFlag(USART1, USART_FLAG_TC);         
    
    }
    /**
      * @brief  串口空闲中断(IDLE)无
      * @param  无
      * @retval 无
     **/
    void USART_IDLE_NVIC_Configuration(void)
    {
    
        NVIC_InitTypeDef NVIC_InitStructure;
    
        /* 配置中断源:IDLE */
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        /* 配置抢占优先级 */
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        /* 配置子优先级 */
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        /* 使能中断通道 */
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    
        //初始化
        NVIC_Init(&NVIC_InitStructure);
    
    }
    /**
      * @brief  USART1  DMA配置
      * @param  无
      * @retval 无
     **/
    void USART_DMA_Config(void)
    {
    
        DMA_InitTypeDef DMA_InitStructure;
    
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输
    
        //相应的DMA配置
        DMA_DeInit(DMA1_Channel5);   //将DMA的通道5寄存器重设为缺省值  串口1对应的是DMA通道5
        //DMA外设ADC基地址
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;  
        //DMA内存基地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf;  
        //数据传输方向,从外设读取发送到内存
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 
        //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_BufferSize = USART_RX_BUFF_SIZE;  
        //外设地址寄存器不变
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
        //内存地址寄存器递增
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
        //数据宽度为8位
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  
        //数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        //工作在正常缓存模式
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  
        //DMA通道 x拥有中优先级 
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
        //DMA通道x没有设置为内存到内存传输
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
        //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
        DMA_Init(DMA1_Channel5, &DMA_InitStructure); 
         //正式驱动DMA传输
        DMA_Cmd(DMA1_Channel5, ENABLE); 
    
    
    }
    /**
      * @brief  串口DMA配置复位函数  恢复DMA指针
      * @param  无
      * @retval 无
     **/
    void DeInit_USART_DMA(DMA_Channel_TypeDef*DMA_CHx)
    {
        //串口DMA失能
        DMA_Cmd(DMA_CHx,DISABLE);
        /*DMA传输数值重装*/
        DMA_SetCurrDataCounter(DMA_CHx,USART_RX_BUFF_SIZE);
        //串口DMA使能
        DMA_Cmd(DMA_CHx,ENABLE);
    
    }
    /**
      * @brief  串口发送一个数组、字符串
      * @param  buf 字符串数组地址 len 数组字符串长度
      * @retval 无
     **/
    void Usart1_Send(u8 *buf,u8 len)
    {
        u8 t;
        //循环发送数据
        for(t=0;t<len;t++)      
        {          
            while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);   
            USART_SendData(USART1,buf[t]);
        }    
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);     
    }
    /**
      * @brief  串口中断
      * @param  无
      * @retval 无
     **/
    /*用于计算不同长度数据的长度*/
    uint32_t DMA_Buf_Cnt;
    void USART1_IRQHandler(void)
    {
        /*串口空闲标志位置1*/
        if(USART_GetITStatus(USART1,USART_IT_IDLE)==SET)
        {
            /* 必须得写,不然IDLE位清除不了 */
            USART_ReceiveData(USART1);
            /*计算出本帧数据长度*/
            DMA_Buf_Cnt=USART_RX_BUFF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel5);
    
            /*测试程序*/
            printf("Length:%d\r\n",DMA_Buf_Cnt);
            printf("Data:\r\n");
            Usart1_Send((uint8_t *)DMA_Rece_Buf,DMA_Buf_Cnt);
            printf("\r\n \r\n");
    
    
    
            //清除中断标志位
            USART_ClearITPendingBit(USART1,USART_IT_IDLE);
            /*DMA使能*/
            DeInit_USART_DMA(DMA1_Channel5);
        }
    
    }
    
    /**
      * @brief  测试函数
      * @param  无
      * @retval 无
     **/
    void USART_DMA_Test(void)
    {
        USART_IDLE_NVIC_Configuration();
        USART_DMA_Config();
    }
    
    /**
      * @brief  主函数
      * @param  无
      * @retval 无
     **/
    int main()
    {
    
        All_Init();
    
        USART_DMA_Test();
    
        while(1)
        {
    
            /*所有要处理任务*/
    //      TaskProcess();
        }
    
    }
    

    串口上位机截图
    串口上位机截图

    注意内容:
    !IDLE位清零必须进行一个读USART_SR寄存器操作,接着进行一个读取USART_DR寄存器操作

    本人菜鸟,正在学习中,有问题还请多多交流指正1558194318@qq.com,如有侵权立即删除。

    展开全文
  • DMA数据传输

    2019-05-10 10:15:00
    从字面意思上看,DMA即为“直接内存读取”的意思,换句话说DMA就是用来传输数据的,它也属于一个外设。...比如GPU与CPU之间存在着大量数据传输.CPU将需要显示的原始数据放在内存中,让GPU通过DMA的方式读取数据,经...

    从字面意思上看,DMA即为“直接内存读取”的意思,换句话说DMA就是用来传输数据的,它也属于一个外设。只是在传输数据时,无需占用CPU。

     高速IO设备可以在处理器安排下直接与主存储器成批交换数据,称为直接存储器访问(Directly Memory Access 简称DMA)

    比如GPU与CPU之间存在着大量的数据传输.CPU将需要显示的原始数据放在内存中,让GPU通过DMA的方式读取数据,经过解析和运算,将结果写至显存中,再由显示控制器读取显存中的数据并显示输出.

    GPU与CPU集成至同一个处理器芯片时,能够大大减少芯片间的数据搬运,同时因为显存和内存的合并,会大大增加访存压力

    DMA传输方向 (这里外设可以理解为DMA?)

    DMA传输方向有三个:外设到内存,内存到外设,内存到内存。

    外设到内存。即从外设读取数据到内存。例如ADC采集数据到内存,ADC寄存器地址为源地址,内存地址为目标地址。

    内存到外设。即从内存读取数据到外设。例如串口向电脑发送数据,内存地址为源地址,串口数据寄存器地址为目标地址此时内存存储了需要发送的变量数据

    内存到内存。以内部flash向内部sram传输数据为例,此时内部flash地址即为源地址,内部sram地址即为目标地址。同时,需要将DMA_CCRx寄存器的MEM2MEM置位。

    转载于:https://www.cnblogs.com/clemente/p/10842850.html

    展开全文
  • 针对数字图像处理过程中的大量数据传输需求,设计了基于FPGA的DMA数据传输系统。上位机基于WinDriver驱动开发工具开发了DMA传输控制程序,下位机基于Xilinx PCIe IP硬核设计了DMA控制逻辑,实现了上位机控制命令发送...
  • 基于Nios II的DMA传输

    2018-11-19 16:21:30
     在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令。    Nios II中的DMA传输有以下三种形式: 1、 存储器到存储器 这种情况下需要同时打开发送通道和接收通道,...

    关于DMA传输的实验。

        在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令。

     

           Nios II中的DMA传输有以下三种形式:

    1、 存储器到存储器

    这种情况下需要同时打开发送通道和接收通道,而且源地址和目标地址都是自增的。

    //打开发送通道

    tx = alt_dma_txchan_open("/dev/dma_0");

    //tx_buf是源地址、传输数据块长度是length

    dma_res = alt_dma_txchan_send(tx, tx_buf, length, NULL, NULL);

    //打开接收通道

    rx = alt_dma_rxchan_open("/dev/dma_0");

    //rx_buf是目标地址、传输数据块长度是length、dma_done()是DMA完成后被调用的回调函数

    dma_res = alt_dma_rxchan_prepare(rx, rx_buf, length, dma_done, NULL); 

     

    2、 存储器到外设

    这种情况下只要打开发送通道,而且源地址是自增的,目标地址是固定的。

    tx = alt_dma_txchan_open("/dev/dma_0"); // 打开发送通道

    alt_dma_txchan_ioctl(tx, ALT_DMA_TX_ONLY_ON, (void *)dst_addr); // dst_addr是目标地址

    dma_res = alt_dma_txchan_send(tx, tx_buf, length, dma_done, NULL); // tx_buf是源地址

     

    3、 外设到存储器

    这种情况下只要打开接收通道,而且源地址是固定的,目标地址是自增的。

    rx = alt_dma_rxchan_open("/dev/dma_0"); // 打开接收通道

    alt_dma_rxchan_ioctl(rx, ALT_DMA_RX_ONLY_ON, (void *)source_addr); // source_addr是源地址

    dma_res = alt_dma_rxchan_prepare(rx, rx_buf, length, dma_done, NULL); // rx_buf是目标地址

     

    其中通过alt_dma_txchan_ioctl,alt_dma_rxchan_ioctl还可以设置每次发送和接收的字节数。

     

    以下是基于DMA通过UART发送和接收数据的例子,注意DMA_0为接受通道,DMA_1为发送通道。当然可以将dma的read_master和writer_master同时连在uart_0和sdram_0的从端口上,这样是可以用一个dma对两者读写操作,但是不能同时做双向传输。

    #include <stdio.h>
    #include <string.h>
    #include "system.h"
    #include "sys/alt_dma.h"
    #include "unistd.h"

    int main(void)
    {/*
        alt_dma_rxchan rx;
        //创建DMA接收信道
        rx = alt_dma_rxchan_open("/dev/dma_0");
        //当信道创建成功
        if(rx != NULL)
        {
            printf("Dma transition start.");
            while(1)
            {
                //设置DMA传输的数据位宽 本例中为8位
                alt_dma_rxchan_ioctl(rx,ALT_DMA_SET_MODE_8,NULL);
                //指定从uart接收数据
                alt_dma_rxchan_ioctl(rx,ALT_DMA_RX_ONLY_ON,(void*)UART_0_BASE);
                
                //提交DMA接收请求 指定接收数据的位置(sdram)以及传输数据量
                if(alt_dma_rxchan_prepare(rx, 
                                           SDRAM_0_BASE, 
                                           1024, 
                                           NULL, 
                                           NULL) < 0)
                {
                    printf ("Error: failed to post receive request\n");
                }
                //关闭DMA接收信道
                alt_dma_rxchan_close(rx);
                usleep(1000000);
            }
        }
        
       */
        alt_dma_txchan  tx;
        tx = alt_dma_txchan_open("/dev/dma_1");
         if(tx != NULL)
        {
            printf("Dma transition start.");
        while(1)
            {    
                alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_8,NULL);
                alt_dma_txchan_ioctl(tx,ALT_DMA_TX_ONLY_ON,(void*)(UART_0_BASE+2));

              //注意是UART_0_BASE+2,因为UART的txdata寄存器在rxdata之后,偏移量为一个rxdata的长度(16位,2个字节)
                    if(alt_dma_txchan_send(tx, 
                                           SDRAM_0_BASE, 
                                           1024, 
                                           NULL, 
                                          (void*) NULL) < 0)
                {
                    printf ("Error: failed to post transmit request\n");
                }
                //关闭DMA发送信道
                alt_dma_txchan_close(tx);
                usleep(1000000);
            }
        }
        return 0;
    }

    展开全文
  • 在ADC高速采集数据时,通过DMA一次性获取大量的转换数据。比如10个ADC,一次 void ADCDMAInit(void) { u8 ADC_SampleTime; ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_In...

    在ADC高速采集数据时,通过DMA一次性获取大量的转换数据。比如5个通道,一次获取1000组数据。获得1000组数据后再统一处理,然后触发下一次转换。在调试过程中发现获取的通道数据序号出错。经过一番折腾终于调通,程序如下


    定义

    #define  adNum   10000
    u16 adsample[adNum];
    //#define DMA1_Channel4_IRQn_EN  1//DMA 电压采集中断
    #ifdef DMA1_Channel4_IRQn_EN
        #define DMA1_Channel4_IRQn_PreemptionPriority 1
        #define DMA1_Channel4_IRQn_SubPriority        1
        u16 Flag,FlagTemp;
        void DMA1_Channel1_IRQHandler(void)
        {
               if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
               {
                   DMA_ClearITPendingBit(DMA1_IT_TC1);
                   Flag++;
                }
        }   
    #endif
    

    ADC&DMA初始化

        void ADCDMAInit(void)
        {
            u8 ADC_SampleTime;
            ADC_InitTypeDef         ADC_InitStructure;
            GPIO_InitTypeDef        GPIO_InitStructure;
            DMA_InitTypeDef         DMA_InitStructure;
            NVIC_InitTypeDef NVIC_InitStructure;
    
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);//RCC_PCLK2_Div6//12M
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin  =(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
        GPIO_Init(GPIOC,&GPIO_InitStructure);
             /* DMA channel1 configuration ---------------------------*/
        DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值
        DMA_InitStructure.DMA_PeripheralBaseAddr =  (u32)&ADC1->DR;//DMA外设ADC基地址
        DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&adsample[0]; //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //内存作为数据传输的目的地
        DMA_InitStructure.DMA_BufferSize =adNum;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//正常模式!!!!
        DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级 
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道
     #ifdef DMA1_Channel4_IRQn_EN
            NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=DMA1_Channel4_IRQn_PreemptionPriority ;//抢占优先级
            NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA1_Channel4_IRQn_SubPriority;     //子优先级
            NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能
            NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
      DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);      
      #endif  
        ADC_InitStructure.ADC_Mode=ADC_Mode_RegSimult;
        ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;
        ADC_InitStructure.ADC_ScanConvMode=ENABLE;
        ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStructure.ADC_NbrOfChannel=5;
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
        ADC_Init(ADC1,&ADC_InitStructure);
           ADC_SampleTime=ADC_SampleTime_71Cycles5;//ADC_SampleTime_71Cycles5;//ADC_SampleTime_55Cycles5;//ADC_SampleTime_239Cycles5;//ADC_SampleTime_1Cycles5;//ADC_SampleTime_13Cycles5;//
        ADC_RegularChannelConfig(ADC1, ADC_Channel_10,1, ADC_SampleTime);//L1
        ADC_RegularChannelConfig(ADC1, ADC_Channel_11,2, ADC_SampleTime);//L2
        ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3, ADC_SampleTime);//L3
        ADC_RegularChannelConfig(ADC1, ADC_Channel_13,4, ADC_SampleTime);//V
        ADC_RegularChannelConfig(ADC1, ADC_Channel_17,5, ADC_SampleTime);//内部参考电压   
        ADC_DMACmd(ADC1, ENABLE);
        ADC_Cmd(ADC1,ENABLE);
        DMA_Cmd(DMA1_Channel1, ENABLE);
        ADC_ResetCalibration(ADC1);
        while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);
        while(ADC_GetCalibrationStatus(ADC1));
        ADC_SoftwareStartConvCmd(ADC1, ENABLE); 
    }
    

    主函数中

    #ifdef DMA1_Channel4_IRQn_EN
        if(Flag!=Flagtemp)
        {
            Flagtemp=Flag;
            DMA_Cmd(DMA1_Channel1, DISABLE);            //关闭DMA
            ADC_Cmd(ADC1,DISABLE);                      //关闭ADC
            ProcessUData();//数据处理
            DMA_SetCurrDataCounter(DMA1_Channel1,adNum); //传输数据变成0,必须重新设置
            DMA_Cmd(DMA1_Channel1,ENABLE);                //开DMA1   
            ADC_Cmd(ADC1,ENABLE);                           //开ADC
            ADC_SoftwareStartConvCmd(ADC1, ENABLE);         //触发转换
        }
     #endif      
       if(DMA_GetFlagStatus(DMA1_IT_TC1)!=RESET)
       {
        DMA_ClearFlag(DMA1_IT_TC1);
        DMA_Cmd(DMA1_Channel1, DISABLE);            //关闭DMA
        ADC_Cmd(ADC1,DISABLE);                      //关闭ADC
        ProcessUData();//数据处理
        DMA_SetCurrDataCounter(DMA1_Channel1,adNum); //传输数据变成0,必须重新设置
        DMA_Cmd(DMA1_Channel1,ENABLE);                //开DMA1   
        ADC_Cmd(ADC1,ENABLE);                           //开ADC
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);         //触发转换
       }
    

    注意

    1、DMA工作在DMA_Mode_Normal模式下传输完成后需要重新设定DMA_MemoryDataSize。设定该参数就需要先关闭DMA,然后再开启。
    没有这一步操作,DMA只能传输一次。
    2、DMA传输完成后要先关闭ADC,再开启ADC,然后再ADC_SoftwareStartConvCmd-ENABLE。没有这个过程,通道数据将会打乱
    3、DMA1_Channel4_IRQn_EN 配置DMA中断或查询

        DMA_Cmd(DMA1_Channel1, DISABLE);            //关闭DMA
        ADC_Cmd(ADC1,DISABLE);                      //关闭ADC
        DMA_SetCurrDataCounter(DMA1_Channel1,adNum); 
        DMA_Cmd(DMA1_Channel1,ENABLE);                
        ADC_Cmd(ADC1,ENABLE);                          
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);         //触发转换
    
    展开全文
  • 目录项目背景DMA简介DMA请求DMA通道DMA仲裁DMA配置从哪里来到哪里去要传多少,单位是什么什么时候传输完成代码示例配置GPIO相关变量...而采用DMA传输可以使ADC采样和数据刷新放在“后台”自动进行,可以节省大量的单
  • NVMe驱动解析-DMA传输

    千次阅读 2016-10-10 15:02:53
    DMA技术是一项比较古老的技术,大...这在进行大量数据搬移的情况下,能够大大降低CPU的使用率。PCIe有个寄存器位Bus Master Enable。这个bit置1后,PCIe设备就可以向Host发送DMA Read Memory和DMA Write Memory请求了。
  • STM32学习笔记之DMA传输

    千次阅读 2018-03-19 18:41:33
    CPU有转移数据、计算、控制程序转移等很多功能,但其实转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,再加上一些控制转移的部件就可以...
  • 引言 USB通用串行总线(Universal Serial Bus)是被PC机广泛采用的一种总线,目前...特别是随着USB2.0高速传输协议的出现,其数据传输速度达到了480Mb/s,使得USB接口方式的虚拟仪器系统成为今天低成本虚拟仪器系统
  • 在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令。 Nios II中的DMA传输有以下三种形式: 1、 存储器到存储器 这种情况下需要同时打开发送通道和接收通道,而且源.....
  • 最近练了一段时间的DMA传输,现做如下的总结,分享自己获得... 在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令。 Nios II中的DMA传输有以下三种形式: 1、...
  • Zigbee之旅(七):几个重要的CC2430基础实验——DMA传输 一、承上启下  上一节,我们讲到了ADC的使用,并对片内温度传感器进行了采样。在实际项目中,传感器的数量往往很多,大量的转换数据有待处理。...
  • ADC多通道采集和DMA缓冲区传输数据的详细过程 ADC采集工作在多通道连续扫描模式和连续转换模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; DMA配置中 开启...
  • 在实际项目中,传感器的数量往往很多,大量的转换数据有待处理。对这些数据的移动将会给CPU带来很大的负担。为了解放CPU,让它有精力去做其他的事儿,DMA(Direct Memory Access)就可以派上用场啦~  下面的介绍...
  • DMA

    2020-08-22 06:42:47
    DMA 传输数据从一个地址空间复制到另外一个地址空间。当CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。像是这
  • STM32数据的搬运工DMA

    2021-06-15 11:17:22
    24.1关于 DMA DMA(Direct Memory Access)直接内存访问,可以大大减轻CPU工作量。...这就是DMA设计的目的,减少大量数据转移指令消耗CPU,DMA专注数据转移,CPU专注计算、控制。 DMA主要实现将A处的数据直接
  • stm32数据传输

    2021-02-21 11:40:25
    DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。它的作用就是解决大量数据转移过度消耗CPU资源的问题。 在stm32(大容量)中有两个DMA,DMA1有7个...
  • DMA驱动

    2016-04-02 16:18:29
    1、为什么要用DMA DMA是一个片内控制模块,作用是将从...这在一些需要大量数据传输并且又不想要耗费CPU资源的场合是十分有用的,比如摄像头数据的传输,这个就可使用DMA进行传输,不耗费CPU的资源。 2、S3C2440的DMA

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 132
精华内容 52
关键字:

dma传输大量数据