S3C2440-DMA

哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/01/15/6142721.aspx

S3c2440A 支持位于系统总线和外设总线之间的4 个通道的控制器。每个DMA 控制器通道
无限制地执行系统总线上的设备或外设总线上的设备之间数据搬移。换句话说,就是每个
通道都操作一下四种情况:
(1)源和目的设备都在系统总线上
(2)源设备在系统总线上,目的设备在外设总线上
(3)源设备在外设总线上,目的设备在系统总线上
(4)源设备和目的设备都在外设总线上
DMA 的主要有点就是其传输数据不需要CPU 的干涉。DMA 操作可由软件或来自内设或外
部请求引脚来初始化。
DMA每次传送2个字节,放到FIFO中,IIS就播放,FIFO空,导致DMA被再次触发,直到传输计数器为0,产生DMA中断,CPU进入中断处理程序。在DMA传送的时候,CPU可以处理其他事情。提高了系统效率。

下面的程序使用IIS播放声音同时跑流水灯。如果不用DMA,直接用上一篇的IIS程序,会发现声音断断续续,因为IIS和流水灯一起分CPU的时间。如果使用DMA,则IIS需要的数据由DMA负责传送,而CPU可以执行流水灯程序,互相不耽误。当传输计数器为0时,产生DMA中断,CPU进入中断处理程序。其他时候,CPU可以执行流水灯。这样就实现了流水灯和IIS放音同时执行。

#include "2440addr.h" #include "music.h" #define L3MODE 1<<2 #define L3DATA 1<<3 #define L3CLOCK 1<<4 #define _ISR_STARTADDRESS 0x33ffff00 #define U32 unsigned int U32 flag, result, remain; void Delay(){ int i, j, k; for(i = 0; i < 0xff; i++) for(j = 0; j < 0xff; j++) for(k = 0; k < 0xff; k++) ; } void Led(){ int i; for(i = 3; i < 7; i++){ rGPFDAT &= ~(1<<i); Delay(); rGPFDAT = 0xff; } } void WriteL3(unsigned char data, unsigned int mode){ //mode = 0,地址模式;mode = 1,数据传输模式 int i, k; if(mode == 0){ rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK )|L3CLOCK; } else{ rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); } for(k = 0; k < 5; k++) ; for(i = 0; i < 8; i++){ if(data & 0x1){ rGPBDAT &= ~L3CLOCK; rGPBDAT |= L3DATA; for(k = 0; k < 5; k++) ; rGPBDAT |= L3CLOCK; rGPBDAT |= L3DATA; for(k = 0; k < 5; k++) ; } else{ rGPBDAT &= ~L3CLOCK; rGPBDAT &= ~L3DATA; for(k = 0; k < 5; k++) ; rGPBDAT |= L3CLOCK; rGPBDAT &= ~L3DATA; for(k = 0; k < 5; k++) ; } data >>= 1; } rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); } void PlayMusic(unsigned char buffer[], unsigned int length){ result = (length>>1)/0x100000; remain = (length>>1)&0xfffff; //UDA1341 //STATUS模式 rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); WriteL3(0x14+2,0); //复位 WriteL3(0x60,1); WriteL3(0x14+2,0); //00010000 系统时钟频率384fs WriteL3(0x10,1); WriteL3(0x14+2,0); //11000001 输出增益,ADC关,DAC开 WriteL3(0xc1,1); //IIS //DMA开启,在接受空闲状态,不产生IISLRCK信号,IIS预分频使能 rIISCON = (1<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1); //主设备时钟PCLK,主设备模式,发送模式,串行数据16位,主时钟是384fs,串行位时钟32fs rIISMOD = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0); //预分频都是N=3 rIISPSR = (3<<5)|3; //发送FIFO用DMA模式,发送FIFO使能 rIISFCON = (1<<15)|(1<<13); //DMA rDISRC2 = (U32)buffer; //DMA2初始源地址 rDISRCC2 = (0<<1)|(0<<0); //源在系统总线上,地址增加 rDIDST2 = (U32)IISFIFO; //DMA2初始目的地址 rDIDSTC2 = (0<<2)|(1<<1)|(1<<0); //当TC为0时,中断发生,源在外围总线上,地址固定,一直为IISFIFO的0x55000010(小端) if(result == 0){ flag = 0; //握手模式,与APB时钟同步,当所有的传输结束,中断请求生成,单元传送,单服务模式,当传输计数器为0时,DMA通道关闭 rDCON2 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(0<<24)|(1<<23)|(1<<22)|(1<<20)|(remain<<0); } else{ flag = 1; rDCON2 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(0<<24)|(1<<23)|(1<<22)|(1<<20)|(0xfffff<<0); } rDMASKTRIG2 = (0<<2)|(1<<1)|(0<<0); //DMA通道开启 rIISCON |= 0x1; //IIS开启 } void __irq DMA2_ISR(void){ rSRCPND |= 1<<19; rINTPND |= 1<<19; if(flag == 0){ rIISCON = 0x0; //关闭IIS rIISFCON = 0x0; //关闭IISFIFO的DMA模式 rDMASKTRIG2 = 1<<2; //关闭DMA } else{ result--; rDISRC2 += 0x200000; //因为是半字 if(result == 0){ flag = 0; rDCON2 = (rDCON2 & (~0xfffff)) | (remain); } rDMASKTRIG2 = (0<<2)|(1<<1)|(0<<0); } } int Main(){ rGPBUP = rGPBUP & ~(0x7<<2) | (0x7<<2); //The pull up function is disabled GPB[4:2] 1 1100 rGPBCON = rGPBCON & ~(0x3f<<4) | (0x15<<4); //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE) rGPBDAT = 0x1ec; rGPEUP = rGPEUP & ~(0x1f) | 0x1f; //The pull up function is disabled GPE[4:0] 1 1111 rGPECON = rGPECON & ~(0x3ff) | 0x2aa; //GPE[4:0]=I2SSDO:I2SSDI:CDCLK:I2SSCLK:I2SLRCK rMPLLCON = (150<<12)|(5<<4)|(0<<0); rSRCPND |= 1<<19; rINTPND |= 1<<19; rINTMSK &= ~(1<<19); rGPFCON = 0xd57f; rGPFUP = 0x87; pISR_DMA2 = (U32)DMA2_ISR; PlayMusic(music, sizeof(music)); while(1){ Led(); //占用CPU } return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值