新手求助DMA

2019-08-17 07:25发布

本帖最后由 wqq1104180120 于 2017-5-25 21:44 编辑

目前正在考虑用f103外接AD模块,AD的吞吐率12M/s左右,可以用DMA+GPIO的方式读取数据?数据量不是很大,2K就可以了,求大神解答一下。首先我想测一下DMA的速度最大能达到多少,用GPIO->IDR来做源地址,但是一直获取不到数据很疑惑,我的测试程序如下。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "key.h"
#include "dma.h"
#include "stm32f10x.h"
#include "delay.h"
u8 Buffer[2048]={0};
u8 Buffer1[4]={1,2,3,4};
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)//配置DMA1_CHx,第一个参数是开启的DMA通道,第二个参数是外设基地址,但三个参数是存储器基地址,第四个参数是要传输的数据量
{
        
        DMA_InitTypeDef DMA_InitStruct;
        
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA时钟

        DMA_DeInit(DMA_CHx);
        
        DMA_InitStruct.DMA_BufferSize=cndtr;
        DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;
        DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryBaseAddr=cmar;
        DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Word;
        DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//我们这是一次传输不循环
        DMA_InitStruct.DMA_PeripheralBaseAddr=cpar;
        DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Word;
        DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;//由于只开启了一个通道,所以优先级随便
        DMA_Init(DMA_CHx, &DMA_InitStruct);
        

  DMA_Cmd(DMA_CHx,ENABLE);
}

void GPIOA_Config()
{
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PA口
        
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStruct);
}


int main(void)
{
        u32 i=0;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
        uart_init(9600);         //串口初始化为9600
        LED_Init();
        delay_init();
        GPIOA_Config();
        MYDMA_Config(DMA1_Channel4,(u32)&GPIOA->IDR,(u32)Buffer,2048);
        while(1)
        {
                LED0=!LED0;
                delay_ms(200);
                if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)
                {
                        LED1=!LED1;
                        delay_ms(200);
                        for(i=0;i<2048;i++)
            printf("%d",Buffer);
                }
        }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
wqq1104180120
1楼-- · 2019-08-17 21:32
hgr211 发表于 2017-5-25 10:20
原子的列子,好像摄像头那个是不是用的你这个方式,你可以去参考下。你昨天程序,2048那里,我明显看的是1 ...

程序我昨天修改了一下,开始是1,你没看错,我去看看原子的摄像头教程,看看有没有新发现,谢谢你!
Owen
2楼-- · 2019-08-17 22:32
6楼说的对,normal模式每次传输完成要重置NDTR寄存器,清DMA_FLAG_TCIF标志位,不然的话即便使能也不会启动
wqq1104180120
3楼-- · 2019-08-18 01:32
Owen 发表于 2017-5-25 20:29
6楼说的对,normal模式每次传输完成要重置NDTR寄存器,清DMA_FLAG_TCIF标志位,不然的话即便使能也不会启动

关键是这个语句if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)判断不为真,表示传输还没完成,应该不是清标志的问题,给我感觉像DMA没启动一样。
wqq1104180120
4楼-- · 2019-08-18 05:30
 精彩回答 2  元偷偷看……

一周热门 更多>