DMA数据传输(源代码分享)

电子说

1.3w人已加入

描述

手头项目也需要加入DMA数据传输,以最大限度地提升CPU效率,于是测试了一下XMEGA的DMA模块,把一块内存中的数据DMA传输到另外一块内存,DMA传输完成后,在中断函数中显示“DMA Finished”,提示DMA成功完成数据传输,另外DMA使用更多的情况是大量数据到USART、SPI等 ,本文只是小试牛刀。

效果如下,

源代码:

#define DMA_BUFFER_SIZE 1024

#define DMA_CHANNEL 0

uint8_t source[DMA_BUFFER_SIZE],destination[DMA_BUFFER_SIZE];

static void fill_pattern(uint8_t *buffer, size_t len)

{

int i;

for (i = 0; i 《 len; i++) {

buffer = 42 ^ (i & 0xff) ^ (i 》》 8);

}

}

static bool verify_pattern(uint8_t *buffer, size_t len)

{

for (size_t i = 0; i 《 len; i++) {

if (buffer != (42 ^ (i & 0xff) ^ (i 》》 8))) {

return false;

}

}

return true;

}

void dma_test(void)

{

struct dma_channel_config config;

fill_pattern(source, DMA_BUFFER_SIZE);

memset(destination, 0, DMA_BUFFER_SIZE);

dma_enable();

memset(&config, 0, sizeof(config));

/*

* This example will configure a DMA channel with the following

* settings:

* - Low interrupt priority

* - 1 byte burst length

* - DMA_BUFFER_SIZE bytes for each transfer

* - Reload source and destination address at end of each transfer

* - Increment source and destination address during transfer

* - Source address is set to ef source

* - Destination address is set to ef destination

*/

dma_channel_set_interrupt_level(&config, DMA_INT_LVL_LO);

dma_channel_set_burst_length(&config, DMA_CH_BURSTLEN_1BYTE_gc);

dma_channel_set_transfer_count(&config, DMA_BUFFER_SIZE);

dma_channel_set_src_reload_mode(&config,

DMA_CH_SRCRELOAD_TRANSACTION_gc);

dma_channel_set_dest_reload_mode(&config,

DMA_CH_DESTRELOAD_TRANSACTION_gc);

dma_channel_set_src_dir_mode(&config, DMA_CH_SRCDIR_INC_gc);

dma_channel_set_dest_dir_mode(&config, DMA_CH_DESTDIR_INC_gc);

dma_channel_set_source_address(&config, (uint16_t)(uintptr_t)source);

dma_channel_set_destination_address(&config,

(uint16_t)(uintptr_t)destination);

dma_channel_write_config(DMA_CHANNEL, &config);

/* Use the configuration above by enabling the DMA channel in use. */

dma_channel_enable(DMA_CHANNEL);

/*

* Enable interrupts as the example is now configured to handle them

* properly.

*/

cpu_irq_enable();

/*

* Trigger a manual start since there is no trigger sources used in

* this example.

*/

dma_channel_trigger_block_transfer(DMA_CHANNEL);

pmic_init();

cpu_irq_enable();

while(1);

}

ISR(DMA_CH0_vect)

{

gfx_mono_draw_string(“DMA Finished”,0,0,&sysfont);

}

int main(void)

{

。。。

dma_test();

。。。

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分