精华内容
下载资源
问答
  • DMA是啥? DMA(Direct Memory Access)—直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU,即在传输数据的时候,CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到...

    DMA是啥?
    DMA(Direct Memory Access)—直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU,即在传输数据的时候,CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH。
    说简单点,就好比你有一个苹果手机和诺基亚大砖头,平时苹果手机主要用来娱乐,为了不干扰玩手机,就用诺基亚大砖头来通讯。那么这就减少了智能手机的使用从而节省更多的电量,大砖头成了专属通讯设备,不经防水,还可以防身。哈哈!


    在这里插入图片描述
    配置DMA前需了解这四个要素

    1. DMA请求
    如果外设要想通过 DMA 来传输数据,必须先给 DMA 控制器发送 DMA 请求,DMA收到请求信号之后,控制器会给外设一个应答信号,当外设应答后且 DMA 控制器收到应答信号之后,就会启动 DMA 的传输,直到传输完毕。DMA 有 DMA1 和 DMA2 两个控制器,DMA1 有 7 个通道,DMA2 有 5 个通道,不同的 DMA 控制器的通道对应着不同的外设请求,这决定了我们在软件编程上该怎么设置,具体见 DMA 请求映像表。
    在这里插入图片描述在这里插入图片描述
    2. 通道
    DMA 具有 12 个独立可编程的通道,其中 DMA1 有 7 个通道,DMA2有 5 个通道,每个通道对应不同的外设的 DMA 请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个,不能同时接收多个。

    3. 仲裁器
    当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。

    4.传输模式
    外设到存储器
    存储器到外设
    存储器到存储器

    一. 编程要点

    1. 使能 DMA 时钟;
    2. 配置 DMA 数据参数;
    3. 使能 DMA,进行传输;
    4. 等待传输完成,并对源数据和目标地址数据进行比较。

    二.写代码
    eg: DMA 存储器到外设模式实验

    //这里的传输形式是固定的,这点要根据不同的情况来修改
    //从存储器->外设模式/8位数据宽度/存储器增量模式
    //DMA_CHx:DMA通道CHx
    //cpar:外设地址
    //cmar:存储器地址
    //cndtr:数据传输量 
    void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
    {
     	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
    	
      DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
    
    	DMA1_MEM_LEN=cndtr;
    	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
    	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
    	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设(即destination“目的地”)
    	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
    	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
    	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
    	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
    	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
    	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 
    	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
    	DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
    	  	
    } 
    

    eg:DMA 存储器到存储器实验

    一般只需修改:

     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;改为
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;改为
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;
    
    
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 改为
    DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; 
    

    整体如下:

    
    //这里的传输形式是固定的,这点要根据不同的情况来修改
    //从存储器->存储器模式/8位数据宽度/存储器增量模式
    //DMA_CHx:DMA通道CHx
    //cpar:外设地址
    //cmar:存储器地址
    //cndtr:数据传输量 
    void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
    {
     	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
    	
      DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
    
    	DMA1_MEM_LEN=cndtr;
    	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
    	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
    	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存(即source“源头”)
    	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
    	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;  //内存(外设flash)地址寄存器递增
    	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
    	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
    	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
    	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 
    	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;  //DMA通道x设置为内存到内存传输
    	DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
    }
    
    展开全文
  • DMA双缓冲

    2020-03-07 11:05:24
    现在工人就是CPU, 产品就是要处理的数据,流水线就是DMA, DMA不断的把数据从外设搬到内存供CPU处理,众所周知,DMA的速度很快的,当外设数据量很大的时候,CPU来不及处理,就会丢失数据, 这时...

    在这里插入图片描述
    举个例子很容易理解:
    比如一条流水线上有一个工人在处理产品,正常情况下进来一个产品工人处理一个,没啥问题,但是如果产品进来的速度太快,工人来不及处理,就会导致有很多产品漏处理,会产生很大问题。
    现在工人就是CPU, 产品就是要处理的数据,流水线就是DMA, DMA不断的把数据从外设搬到内存供CPU处理,众所周知,DMA的速度是很快的,当外设数据量很大的时候,CPU来不及处理,就会丢失数据, 这时候双缓存就派上用场了。
    再回到之前的工人和产品的模型,现在要处理的产品很多,工人就想办法了,为什么不把送进来的产品分堆呢, 好了,现在产品分为两堆,A堆为正在送进来的那一堆,B堆为工人正在处理的那一堆, DMA首先把数据送到A堆, CPU处理B堆,当A堆满了之后,外设通知CPU去处理A堆,然后DMA自动切换为将数据存储于B堆,以此类推。

    展开全文
  • stm32 adc的dma传输案例

    2019-03-21 10:46:12
    dma不多说了,原理的网上一大推,源码也有注释,理解起来很容易 案例传输adc的4个通道,需要多个或者其它的,照着修改就行。 #define ADC1_DR_Address ((u32)0x40012400+0X4C) //ADC数据的地址 u16 ADC_buf...

    dma不多说了,原理啥的网上一大推,源码也有注释,理解起来很容易

    案例是传输adc的4个通道,需要多个或者其它的,照着修改就行。

    #define ADC1_DR_Address ((u32)0x40012400+0X4C)		//ADC数据的地址
    
    u16  ADC_buf[4];		//DMA传输BUF
    
    void adc_dma_init()
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
    
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;	//通道引脚
    	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    	
    	DMA_InitTypeDef DMA_InitStructure;
    	ADC_InitTypeDef	ADC_InitStructure;
    
    	DMA_DeInit(DMA1_Channel1);
    	
    	DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;	//ADC数据寄存器地址
    	DMA_InitStructure.DMA_MemoryBaseAddr=(u32)ADC_buf;	//将ADC1_DR_Address数据转移到ADC_buf
    	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //数据传输方向,外设作为数据源
    	DMA_InitStructure.DMA_BufferSize=4; //传输个数据
    	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址固定
    	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
    	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; //表示每个传输的的数据大小
    	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
    	DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //循环传输
    	DMA_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道优先级
    	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //禁止内存到内存传输
    	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
    	
    	DMA_Cmd(DMA1_Channel1,ENABLE);		//使能
    	
    	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
    	ADC_InitStructure.ADC_ScanConvMode=ENABLE;	//扫描模式,用于多通道采集
    	ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; //开启连续转换
    	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//b不使用外部触发转换
    	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//采集数据右对齐
    	ADC_InitStructure.ADC_NbrOfChannel=4;		//要转换的个数
    	ADC_Init(ADC1,&ADC_InitStructure);
    	
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6);	//6分频,12HZ
    	
    	//扫描顺序,55.5每个周期
    	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
    	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
    	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
    	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
    	
    	
    	ADC_DMACmd(ADC1,ENABLE);	//向DMA发出请求
    	
    	ADC_Cmd(ADC1,ENABLE);
    	
    	ADC_ResetCalibration(ADC1);	//复位矫正寄存器
    	
    	while(ADC_GetResetCalibrationStatus(ADC1)); //等待矫正完成
    	
    	ADC_StartCalibration(ADC1);	//ADC矫正
    
    	while(ADC_GetCalibrationStatus(ADC1));	//等待矫正完毕
    	
    	ADC_SoftwareStartConvCmd(ADC1,ENABLE);	//软件触发ADC转换
    	
    }
    
    
    int main(void)
    	
    {
    	
    		adc_dma_init();
    
    	
    		while(1)
    			
    		{
    			
    			
    			delay_ms(200);
    				
    		
    		}
    		
    }
    

    CSDN的代码排版真是越来越差了.....

    本来想软件仿真过来看的,但不知道怎么修改IO的电压值,只能用硬件仿真测试了。

    测试效果如下:数组里的值会不断刷新,也就是adc引脚的数据直接传输到了数组里面。这样就不会占用cpu资源了。

    仿真工程:stm32f103c8t6,我博客的芯片基本都是这款,具体可看工程的芯片设置

    https://download.csdn.net/download/hes_c/11044920

    展开全文
  • 韦东山二期驱动视频-DMA

    千次阅读 2019-10-25 15:38:52
    1、什么是DMADMA(直接存储器访问) DMA(Direct Memory Access,直接内存存取) 所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一...

    如果说为啥倒着学习的话,原因就是——先从简单的入手,也即我党宝贵的斗争经验——农村包围城市。

    1、什么是DMA?

    DMA(直接存储器访问)

    DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。

    源于百度百科:https://baike.baidu.com/item/DMA/2385376?fr=aladdin

    2、DMA怎么使用?

    既然是内存的复制,那么就必须要有源、目的、长度。

    3、DMA程序编写时的注意事项

    1、分配物理上连续的内存,作为源和目的得缓冲区

    在教程中,特别提到不能使用kmalloc给dma分配缓存,因为kmalloc分配的内存在物理上是不连续的。

    但是根据网上的文章说明,该函数分配的内存在物理上是连续的。

    2、映射dma控制器的寄存器地址到虚拟地址。

     

    DMA内核函数简单介绍

     

     

    下面分析韦东山教程中的dma驱动代码:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    #include <linux/delay.h>
    #include <linux/irq.h>
    #include <asm/uaccess.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    #include <asm/arch/regs-gpio.h>
    #include <asm/hardware.h>
    #include <linux/poll.h>
    #include <linux/dma-mapping.h>
    
    #define MEM_CPY_NO_DMA  0
    #define MEM_CPY_DMA     1
    
    #define BUF_SIZE  (512*1024)
    
    #define DMA0_BASE_ADDR  0x4B000000
    #define DMA1_BASE_ADDR  0x4B000040
    #define DMA2_BASE_ADDR  0x4B000080
    #define DMA3_BASE_ADDR  0x4B0000C0
    
    struct s3c_dma_regs {
    	unsigned long disrc;
    	unsigned long disrcc;
    	unsigned long didst;
    	unsigned long didstc;
    	unsigned long dcon;
    	unsigned long dstat;
    	unsigned long dcsrc;
    	unsigned long dcdst;
    	unsigned long dmasktrig;
    };
    
    
    static int major = 0;
    
    static char *src;
    static u32 src_phys;
    
    static char *dst;
    static u32 dst_phys;
    
    static struct class *cls;
    
    static volatile struct s3c_dma_regs *dma_regs;
    
    static DECLARE_WAIT_QUEUE_HEAD(dma_waitq);
    /* �ж��¼���־, �жϷ����������1��ioctl������0 */
    static volatile int ev_dma = 0;
    
    static int s3c_dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
    {
    	int i;
    
    	memset(src, 0xAA, BUF_SIZE);
    	memset(dst, 0x55, BUF_SIZE);
    	
    	switch (cmd)
    	{
    		case MEM_CPY_NO_DMA :
    		{
    			for (i = 0; i < BUF_SIZE; i++)
    				dst[i] = src[i];
    			if (memcmp(src, dst, BUF_SIZE) == 0)
    			{
    				printk("MEM_CPY_NO_DMA OK\n");
    			}
    			else
    			{
    				printk("MEM_CPY_DMA ERROR\n");
    			}
    			break;
    		}
    
    		case MEM_CPY_DMA :
    		{
    			ev_dma = 0;
    			
    			/* ��Դ,Ŀ��,���ȸ���DMA */
    			dma_regs->disrc      = src_phys;        /* Դ�������ַ */
    			dma_regs->disrcc     = (0<<1) | (0<<0); /* Դλ��AHB����, Դ��ַ���� */
    			dma_regs->didst      = dst_phys;        /* Ŀ�ĵ������ַ */
    			dma_regs->didstc     = (0<<2) | (0<<1) | (0<<0); /* Ŀ��λ��AHB����, Ŀ�ĵ�ַ���� */
    			dma_regs->dcon       = (1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(0<<20)|(BUF_SIZE<<0);  /* ʹ���ж�,��������,�������, */
    
    			/* ���DMA */
    			dma_regs->dmasktrig  = (1<<1) | (1<<0);
    
    			/* ���֪��DMAʲôʱ�����? */
    			/* ���� */
    			wait_event_interruptible(dma_waitq, ev_dma);
    
    			if (memcmp(src, dst, BUF_SIZE) == 0)
    			{
    				printk("MEM_CPY_DMA OK\n");
    			}
    			else
    			{
    				printk("MEM_CPY_DMA ERROR\n");
    			}
    			
    			break;
    		}
    	}
    
    	return 0;
    }
    
    static struct file_operations dma_fops = {
    	.owner  = THIS_MODULE,
    	.ioctl  = s3c_dma_ioctl,
    };
    
    static irqreturn_t s3c_dma_irq(int irq, void *devid)
    {
    	/* ���� */
    	ev_dma = 1;
        wake_up_interruptible(&dma_waitq);   /* �������ߵĽ��� */
    	return IRQ_HANDLED;
    }
    
    static int s3c_dma_init(void)
    {
    	if (request_irq(IRQ_DMA3, s3c_dma_irq, 0, "s3c_dma", 1))
    	{
    		printk("can't request_irq for DMA\n");
    		return -EBUSY;
    	}
    	
    	/* ����SRC, DST��Ӧ�Ļ����� */
    	src = dma_alloc_writecombine(NULL, BUF_SIZE, &src_phys, GFP_KERNEL);
    	if (NULL == src)
    	{
    		printk("can't alloc buffer for src\n");
    		free_irq(IRQ_DMA3, 1);
    		return -ENOMEM;
    	}
    	
    	dst = dma_alloc_writecombine(NULL, BUF_SIZE, &dst_phys, GFP_KERNEL);
    	if (NULL == dst)
    	{
    		free_irq(IRQ_DMA3, 1);
    		dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
    		printk("can't alloc buffer for dst\n");
    		return -ENOMEM;
    	}
    
    	major = register_chrdev(0, "s3c_dma", &dma_fops);
    
    	/* Ϊ���Զ������豸�ڵ� */
    	cls = class_create(THIS_MODULE, "s3c_dma");
    	class_device_create(cls, NULL, MKDEV(major, 0), NULL, "dma"); /* /dev/dma */
    
    	dma_regs = ioremap(DMA3_BASE_ADDR, sizeof(struct s3c_dma_regs));
    		
    	return 0;
    }
    
    static void s3c_dma_exit(void)
    {
    	iounmap(dma_regs);
    	class_device_destroy(cls, MKDEV(major, 0));
    	class_destroy(cls);
    	unregister_chrdev(major, "s3c_dma");
    	dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
    	dma_free_writecombine(NULL, BUF_SIZE, dst, dst_phys);	
    	free_irq(IRQ_DMA3, 1);
    }
    
    module_init(s3c_dma_init);
    module_exit(s3c_dma_exit);
    
    MODULE_LICENSE("GPL");

    从s3c_dma_init函数看起:

    1、申请中断,中断号为dma3的中断号,为什么使用dma3通道,因为别的通道被占用了。中断处理函数是s3c_dma_irq,

    2、分配dma源和目的的buffer。使用的函数是dma_alloc_writecombine,

    3、申请主设备号,并和dma_fops联系起来。创建类,创建设备。设备为/dev/dma,类为s3c_dma

    4、对dma控制器的寄存器地址进行映射。dma_regs = ioremap(DMA3_BASE_ADDR, sizeof(struct s3c_dma_regs));

    下面看这个文件操作指针,其中只有一个ioctl函数。

    5、这个函数,根据测试程序传来的值,进行数据搬运。

    如果不使用dma,则直接按字节去搬运,完成后再使用memcmp函数比较搬运长度的空间。

    如果使用dma,则先对dma进行初始化。

    随后启动dma——dma_regs->dmasktrig  = (1<<1) | (1<<0);

    之后,进行比较,看是否完成搬运。

     

    感觉程序不难,但是真正的难点在于读懂一个芯片手册,了解使用dma的步骤。

     

     

     

     

     

     

     

     

    展开全文
  • TIM+DMA的串口发送实现

    2019-04-03 12:25:24
    朋友最近在做一个东西,上面要用到两个串口,一个只管发送一个只管接收,但是波特率的乱七八糟配置不一样,芯片用的STM32F030F4P6,这颗芯片只有一个串口,于是问我有没有什么办法,于是便想下面办法。...
  • FROM:http://blog.csdn.net/waterhawk/article/details/50723677 转载时请标明作者 waterhawk, 原文地址:... 先简单说一下DMA的CACHE一致性问题。 复制: CPU在访问内存时,首先判断所要访问的内容是否在...
  • 经过几天的浴血奋战,终于把Mini2440的IIS音频输出和DMA控制看懂了个大概,现在写下来,怕以后自己忘记,也顺便给大伙瞧瞧,哪里有错误还请大家指正.......  首先说说IIS(全称Inter--IC Sound Bus)吧,这由SONY...
  • 手把手教你如何配置DMA[共享]

    千次阅读 2006-10-25 23:24:00
    如果你还没有看过《嵌入式内功.葵花宝典》,那么在阅读本这篇推荐的文章之前有必要先去看看吧,你会有新的体会的。Direct Memory Access DMA...que? /*到底啥是DMA*/ DMA registers /*DMA寄存器*/ Some DMA rou
  • 本文主要描述使用STM32F1 USART2的DMA方式来实现Modbus主机程序。 首先简单了解下Modbus协议,在https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf(不知道为网站有时候打不开)MODBUS官网上下载到了...
  • dma中断定长发送本来很简单的一个问题让hal搞的头大,调来调去的,说好的彻底封装呢,确实很彻底啊,不废话了...那么这个函数里面样的。 函数主体: HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleType
  • 1、支持差分输入方式,测量结果为两输入端口电压差的转换的有符号数值,这个功能对于桥式传感器的数据采集真是太爽了,可以省一个电平平移放大电路 2、原始分辨率最高提升到12位,14位那个过采样方式实现的,使用...
  • 最近辗转出差中,一直也没抽出空来写上几篇(虽然俺的“素材库”已经积累不少了),今天又坐上高铁了,顿时满血复活,赶紧趁此机会码上几篇(?不只一篇?,嘿嘿,必须的,欠的债早晚要还的…),我都快成为高铁上...
  • 我哥给我打电话说电脑总是用着用着就变慢了,那个电脑我的老笔记本,退役后换了个硬盘给我哥了,已经快6年了,刚开始怀疑系统的问题,就让我...原来硬盘的传速模式从DMA模式编程PIO模式。 下面摘抄网上的解决...
  • stm32F4 多路ADC 之七路ADC(双重ADC 多通道)...这也不算,如果6或8(偶数),一般人看到这应该就能解决大多数问题了。然而这个7(我用的ADC1的三个和ADC2的四个),然后DMA循环模式传输,最开始自己定义了一个
  • STM32F103 UCOSIII UART串口空闲DMA接收 以及 实际产品中的应用方式(标准库3.5版本) 1. 修订记录 日期 修订版本 描述 修订人 2021-5-4 v1 原理和产品应用讲解 微信: pingdanv3314 有完整的产品上用的...
  • 近日实验室那台机器无故变的狂慢,启动一下要5分钟,开个程序也要等半天,用Winamp放个歌仿佛听鬼叫忍无可忍以为中毒了,进程里和启动项看了一圈,没可疑的东东。任务管理器监视了一下似乎也没有哪个程序特耗CPU...
  • kafka为这么快?

    2021-01-27 17:06:05
    1. 前言 我们知道网络和IO(Input Output)最基本的...如果没有内核随即向磁盘控制器发出命令,要求从磁盘读取数据,磁盘控制器把数据直接写入内核 read 缓冲区,这一步通过 DMA完成。 接下来就是内核将数据 ...
  • DMA单元学习

    2019-10-06 20:31:07
     bram ctrl的映射地址edit addr的那个,但是不能直接使,要用宏定义的那个数(后面多了一个U,我也不知道为)。找自己的bram ctrl的base宏定义什么名字要去xparameters.h找,看名字找,好像没有表格。。。 ...
  • 其实零拷贝含义:不使用 CPU 来进行数据复制,不在用户态进行数据移动,使用 DMA 芯片代替 CPU 进行数据复制和移动。 知识储备 在了解零拷贝之前我们需要先了解上下文、用户态和内核态、DMA等知识点。 上下文 上...
  • 今天总结一下DMA(Direct Memory Access,直接存储器存储),在以往我们从串口读取数据到内存的流程是,cpu...DMA的作用是啥呢?从名字能看出来一二,它可以直接从串口读取数据存储在内存中,几乎不占用CPU的资源。...
  • 310719流水账

    2019-10-01 20:06:57
    我记得好像把之前屏蔽的DMA函数给放出来了,因为转换用的数从数组里取出来的,而我需要用DMA将数据从ADC的寄存器里送到数组里。我也不知道之前屏蔽了DMA的程序怎么好使的。 昨天下午说要换台式机,换了台式机...
  • 前言 看I2Cdemo之前,想起下游厂商的...看了官方提供的I2Cdemo, 一个2个,其中一个低功耗唤醒的,剩下一个I2C_EEPROM_fast_mode_plus, 确实DMA做的。 再看细节之前,习惯性的去试试效果。 结果跑不起来。...
  • 比赛感悟通过本次比赛,极大程度上熟悉了H7系列开发板,特别大量参考了安富莱提供的教程,了解了H7的多域设计,RAM的分布式设计以及指定存储位置,DMA通信只能用于特定的RAM区和特定的外设之间,若RAM区域使用最高...
  • keil RTE HAL库 STM32CubeMX 串口收发

    千次阅读 2021-04-04 18:38:42
    在研究keil RTE中,没有找到对应串口的例程,更奇怪的,选择USART库的时候依赖库竟然有DMA,记得正点原子的STM32串口例程里面没有用到DMA。感谢社会,有万能的度娘,由HAL库找到CubeMX。下载,安装。 二、STM32...
  • 关于wifi 的一招半式

    2010-10-19 11:20:00
    wifi 模块环隆电气的模块,支持SPI和SDIO 接口。  平台:三星REAL6410 and OK2440-III  嘿嘿,新的PDA...  后来,一个新员工采用简单的查询代码搞定,嘿嘿我至今不懂为这个DMA不行,主要
  • 最开始排查的时候也想到更新造成的,没有查看更新日志,更换了定位相关的的jar包:导致没变化,后来详细看了日志,才锁定解决。 在这期间高德做了改版,具体信息截图如下: 看到这里想到应该做了代码优化...
  • ERROR&WARNING 1.cannot open source input file"DMA.h":no such file or directory. 头文件的路径没添加啊,这...3.two many arguments(玩意我也忘了,后面的网上找的)in function call 旧程序:delay...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

dma是啥