利用DMA进行数据传输的例子

时间:2022-06-11 21:26:58
在用DMA进行数据操作时,无非就是对DMA进行相关的控制和一些寄存器的配置,下面是一个比较经典的DMA进行传输的例子:
#include <stdio.h>
#include <alt_types.h>
#include <io.h>
#include <system.h>
#include <string.h>
#include "system.h"
#include "sys/alt_dma.h"
//#include "altear_avalon_dma.h"
#include "altera_avalon_dma_regs.h"
#include "sys/alt_irq.h"
//static volatile unsigned int *P_read_RAM=
// (unsigned int *)(SRAM25616_0_BASE+0x100000);
unsigned int *P_read_RAM;
static volatile unsigned int *P_write_RAM=
(unsigned int *)(SRAM25616_0_BASE+0x500000);

void DMA_interrupts(void* context, alt_u32 id);
void init_dma(void);
void write_data(void);
/******************************************************************
* Function: main
*
* Purpose: Continually prints the menu and performs the actions
* requested by the user.
*
******************************************************************/
int main(void)
{
init_dma();
write_data();
alt_irq_register(DMA_0_IRQ,0,DMA_interrupts);
while(1)
{
;
}
return (0);
}
//DMA传输设置
void init_dma(void)
{
alt_irq_register(DMA_0_IRQ,0,DMA_interrupts); //注册DMA中断服务程序
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE, 0);//清控制寄存器
IOWR_ALTERA_AVALON_DMA_STATUS (DMA_0_BASE, 0);//清状态寄存器
IOWR_ALTERA_AVALON_DMA_LENGTH (DMA_0_BASE, 200);//写入一次DMA传输的总数据长度
IOWR_ALTERA_AVALON_DMA_RADDRESS (DMA_0_BASE,(int)P_read_RAM);//DMA传输的目标地址
IOWR_ALTERA_AVALON_DMA_WADDRESS (DMA_0_BASE,(int)P_write_RAM);//DMA传输的源地址
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE,
ALTERA_AVALON_DMA_CONTROL_HW_MSK | //半字传输
ALTERA_AVALON_DMA_CONTROL_GO_MSK |//启动DMA
ALTERA_AVALON_DMA_CONTROL_I_EN_MSK |//开中断
// ALTERA_AVALON_DMA_CONTROL_WCON_MSK |
// ALTERA_AVALON_DMA_CONTROL_WEEN_MSK |
ALTERA_AVALON_DMA_CONTROL_LEEN_MSK
);
}

//DMA中断服务程序
void DMA_interrupts(void* context, alt_u32 id)
{
// int i;
// for(i=0;i<300;i++);
int si=IORD_ALTERA_AVALON_DMA_STATUS (DMA_0_BASE);//读取状态寄存器
if(si&0x1)//判断是否传输完成,如果传输完成,重新设置DMA。
{
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE, 0);
IOWR_ALTERA_AVALON_DMA_STATUS (DMA_0_BASE, 0);
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE, 0);
IOWR_ALTERA_AVALON_DMA_LENGTH (DMA_0_BASE, 200);
IOWR_ALTERA_AVALON_DMA_RADDRESS (DMA_0_BASE,(int)P_read_RAM);
IOWR_ALTERA_AVALON_DMA_WADDRESS (DMA_0_BASE,(int)P_write_RAM);
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE,
ALTERA_AVALON_DMA_CONTROL_HW_MSK |
ALTERA_AVALON_DMA_CONTROL_GO_MSK |
ALTERA_AVALON_DMA_CONTROL_I_EN_MSK |
ALTERA_AVALON_DMA_CONTROL_WCON_MSK |
// ALTERA_AVALON_DMA_CONTROL_WEEN_MSK |
ALTERA_AVALON_DMA_CONTROL_LEEN_MSK
);
}
}
/////////////////
void write_data(void)
{
unsigned int i;
for(i=0;i<200;i++)
{
if(i<100)
{
P_read_RAM[i]=0xaaaaaaaa;
}
else
{
P_read_RAM[i]=0x55555555;
}
}
}