1504|0

3836

帖子

19

TA的资源

纯净的硅(中级)

楼主
 

MSP430+DMA [复制链接]

单字或者单字节传输:DMA 通道被定义为单字或者单字节传输模式,每个字或者字节的传输都要触发信号触发。设置DMADTx=0 就定义了单字或者单字节传输模式,规定的传输完毕后DMAEN 位自动清除,如果需要再次传输,必须重新置位DMAEN。如果设置DMADTx=4 为重复单字或者单字节传输模式,DMAEN 位一直保持置位,每次触发伴随一次传输。DMAxSZ 寄存器保存传输的单元个数,如果该寄存器为0,则没有传输。传输之前DMAxSZ 寄存器的值写入到一个临时的寄存器中,每次操作之后DMAxSZ 做减操作。当DMAxSZ减为零的时候,它所对应的临时寄存器将原来的值重新置入DMAxSZ,同时相应的DMAIFG标志置位。 块传输模式:在块传输模式,每次触发可以传输一个数据块。设置DMADTx=1 为块传输模式,每个数据块传输完毕,DMAEN 位自动清除,在触发传输下一个数据块之前,该位要被重新置位。在传输某个数据块期间,其他的传输请求将被忽略。设置DMADTx=5 为重复块传输模式,某个数据块传输完毕,DMAEN 位仍然保持置位,之后,新的触发可以引起又一次数据块传送。DMAxSZ 寄存器保存数据块所包含的单元个数。DMASRCINCR 和DMADSTINCR 反映在数据块传输过程中的目的地址和源地址的变化情况。在块传输或者重复块传输过程中,DMAxSA,DMAxDA,DMAxSZ 寄存器的值写入到对应的临时寄存器中,DMAxSA,DMAxDA寄存器所对应的临时值在块传输过程中增加或者减少,而DMAxSZ 在块传输过程中减计数,始终反映当前数据块还有多少单元没有传输完毕,当DMAxSZ 减为0,它所对应的临时寄存器将原来的值重新置入DMAxSZ,同时相应的DMAIFG被置位。在块传输过程中,CPU 暂停工作,不参与数据的传输。数据块需要2×MCLK×DMAxSZ 个时钟周期。当每个数据块传输完毕,CPU 按照暂停前的状态重新开始执行。 突发块传输模式:这个和块传输模式类似,只不过每传输4个字或字节,DMA释放内部总线,CPU运行2个MCLK周期;在传输过程中CPU有20%的执行时间,而块传输需要等DMA完全传送完之后,CPU方能运行。 DMA触发源:每个通道的触发源有DMAxTSELx位进行控制的,这些位必须在DMAEN位为0是进行设置,否则可能出现不可预料的DMA触发。 DMAxTSELx Operation 0000 DMAREQ bit (software trigger) 0001 TACCR2 CCIFG bit 0010 TBCCR2 CCIFG bit 0011 URXIFG0 (UART/SPI mode), USART0 data received (I2C mode) 0100 UTXIFG0 (UART/SPI mode), USART0 transmit ready (I2C mode) 0101 DAC12_0CTL DAC12IFG bit 0110 ADC12 ADC12IFGx bit 0111 TACCR0 CCIFG bit 1000 TBCCR0 CCIFG bit 1001 URXIFG1 bit 1010 UTXIFG1 bit 1011 Multiplier ready 1100 No action 1101 No action 1110 DMA0IFG bit triggers DMA channel 1 DMA1IFG bit triggers DMA channel 2 DMA2IFG bit triggers DMA channel 0 1111 External trigger DMAE0 另外,单片机的中断程序不影响DMA的传输,当DMA传输过程中,单片机不响应中外部NMI中断(必须DMA的控制位ENNMI位为1时响应NMI中断,否则不予处理)外的所有中断;必须等待DMA数据传送结束之后才运行系统的中断处理程序。 DMA的中断:数据传送过程中,DMAxSZ寄存器值减为0时,DMA置位DMAIFG,DMA的中断和DAC12模块共享中断向量,使用中断时需要软件判断具体是那个中断。中断响应后DMAIFG不会自动复位,使用时必须软件清零DMAIFG位。 DMA的寄存器如下: Register Short Form Register Type Address Initial State DMA control 0 DMACTL0 Read/write 0122h Reset with POR DMA control 1 DMACTL1 Read/write 0124h Reset with POR DMA channel 0 control DMA0CTL Read/write 01E0h Reset with POR DMA channel 0 source address DMA0SA Read/write 01E2h Unchanged DMA channel 0 destination address DMA0DA Read/write 01E4h Unchanged DMA channel 0 transfer size DMA0SZ Read/write 01E6h Unchanged DMA channel 1 control DMA1CTL Read/write 01E8h Reset with POR DMA channel 1 source address DMA1SA Read/write 01EAh Unchanged DMA channel 1 destination address DMA1DA Read/write 01ECh Unchanged DMA channel 1 transfer size DMA1SZ Read/write 01EEh Unchanged DMA channel 2 control DMA2CTL Read/write 01F0h Reset with POR DMA channel 2 source address DMA2SA Read/write 01F2h Unchanged DMA channel 2 destination address DMA2DA Read/write 01F4h Unchanged DMA channel 2 transfer size DMA2SZ Read/write 01F6h Unchanged 有关每个寄存器的详细内容参考ti提供的用户指南。 程序实现: DMA的使用主要是DMA寄存器的初始设置,设置完成后,DMA接到触发信号即可自动传输数据。 设置函数如下: void DMAInit(char channel,char trigger,char transMode,char srcMode,char dstMode, unsigned int src,unsigned int dst,unsigned int size) { unsigned int *DMAxCTL,*DMAxSA,*DMAxDA,*DMAxSZ; DMACTL0 = trigger << (channel << 2); DMACTL1 = 0x04; //DMA收到触发请求时,等待当前指令执行完成后 switch (channel) //选择当前设置哪个DMA通道 { case 0: DMAxCTL = (unsigned int *)&DMA0CTL; DMAxSA = (unsigned int *)&DMA0SA; DMAxDA = (unsigned int *)&DMA0DA; DMAxSZ = (unsigned int *)&DMA0SZ; break; //指针 = 0通道控制 case 1: DMAxCTL = (unsigned int *)&DMA1CTL; DMAxSA = (unsigned int *)&DMA1SA; DMAxDA = (unsigned int *)&DMA1DA; DMAxSZ = (unsigned int *)&DMA1SZ; break; //指针 = 1通道控制 case 2: DMAxCTL = (unsigned int *)&DMA2CTL; DMAxSA = (unsigned int *)&DMA2SA; DMAxDA = (unsigned int *)&DMA2DA; DMAxSZ = (unsigned int *)&DMA2SZ; break; //指针 = 2通道控制 } switch (transMode) //设置DMA通道的传输模式 { case 'S': *DMAxCTL = DMADT_0; break; //单次传输 case 's': *DMAxCTL = DMADT_4; break; //重复单次传输 case 'B': *DMAxCTL = DMADT_1; break; //块传输 case 'b': *DMAxCTL = DMADT_5; break; //重复块传输 case 'I': *DMAxCTL = DMADT_2; break; //突发块传输 交错 case 'i': *DMAxCTL = DMADT_6; break; //重复突发块传输 交错 } *DMAxCTL |= (srcMode & 0x04) << 2; //源 字或字节 *DMAxCTL |= (srcMode & 0x03) << 8; //源 地址改变方式 *DMAxCTL |= (dstMode & 0x04) << 3; //目的 字或字节 *DMAxCTL |= (dstMode & 0x03) << 10; //目的 地址改变方式 *DMAxSA = src; *DMAxDA = dst; *DMAxSZ = size; *DMAxCTL |= DMAEN; //DMA使能 } 函数比较麻烦,函数内容按参数设置每个寄存器。DMACTL0 = trigger << (channel << 2); 这个是设置对应channel通道的的参考源,不大明白的可以看下DMACTL0的寄存器内容;switch (channel)语句则根据通道设置对应指针指向的寄存器;然后对应设置参数即可。
 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表