FPGA的DMA实现

这篇博客详细介绍了如何在FPGA中使用DMA实现三种传输方式:存储器到存储器、存储器到外设以及外设到存储器。实验基于Quartus II 9.0和Nios II 9.0,利用Altium Designer的DMA模块和Nios II程序。通过具体的实验步骤和示例代码展示了如何配置DMA通道,包括设置传输模式、源目标地址和中断处理。最后给出了几个关键注意事项,如关闭UART中断、设置正确的发送地址和清除中断标志。
摘要由CSDN通过智能技术生成

一、摘要

本篇博文实现了DMA的3种传输方式。

 

二、实验平台

1、Quartus II9.0 + Nios II9.0

2、USB_Board

 

三、实验内容

1、存储器到存储器

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

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

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

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

dma_res = alt_dma_rxchan_prepare(rx, rx_buf, 32, dma_done, NULL); // rx_buf是目标地址,dma_done()是DMA完成后被调用的回调函数。

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, 32, 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, 32, dma_done, NULL);  // rx_buf是目标地址

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

 

四、实验步骤

  1、建立一个sopc系统

 

      其中dma模块、uart模块、jtag_uart都是默认设置,有时添加设置(如dma的突发传输)可能实验就会出现异常。onchip_memery,设置为8位1024字节,sdram是一个添加的存储器接口模块,这个用于运行程序,也可以使用自己板上其他的存储器如sram、flash等。

2、建立原理图

 

3、Nios II 程序

依次在Nios II下建立3个工程,分别是:mem_to_mem、mem_to_uart和uart_to_mem

(1)第一个工程:存储器到存储器mem_to_mem

  这里用dma将buff中的数据传输到mem_1中,通过观察dma工作前mem_1中的数据和工作后mem_1中的数据就可看出实验的结果。试验中使用了dma_tx_done标志,以便检查中断是否成功,因为有时数据传输正确了,中断上可能还有问题,而实际中高效率往往需要中断。

 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/alt_dma.h>
  4. #include "altera_avalon_uart_regs.h"
  5. #include "sys/alt_irq.h"
  6. #include "system.h"
  7. #include "altera_avalon_dma_regs.h"
  8.  
  9. static volatile int tx_done = 0;
  10.  
  11. static char buff[16];
  12.  
  13. /*这里是在SDRAM中开辟了一个buff,也可以直接用FPGA内部的RAM
  14. 例如
  15. void* source = (void*) 0x01002000; //假设0x01002000为另外一个onchip-memory的地址
  16. */
  17.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值