电子说
手头项目也需要加入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();
。。。
}
全部0条评论
快来发表一下你的评论吧 !