DMA方式的难点我觉得就是在配置DMA的上面,不但要使能DMA还要指定DMA的源地址和目地地址。
从上边可见,是以一个string数组为源,以USART数据寄存器为目地的DMA传输。
具体的打开快速指导,并按内容形成程序。
具体程序如下:
- <P>#include <asf.h>
- struct usart_module usart_instance;
- struct dma_resource usart_dma_resource_rx;
- struct dma_resource usart_dma_resource_tx;</P>
- <P>#define BUFFER_LEN 8
- static uint16_t string[BUFFER_LEN];
- COMPILER_ALIGNED(16)
- DmacDescriptor example_descriptor_rx;
- DmacDescriptor example_descriptor_tx;</P>
- <P>
- static void transfer_done_rx(struct dma_resource* const resource )
- { dma_start_transfer_job(&usart_dma_resource_tx);}
- static void transfer_done_tx(struct dma_resource* const resource )
- { dma_start_transfer_job(&usart_dma_resource_rx);}
- static void configure_dma_resource_rx(struct dma_resource *resource)
- {
- struct dma_resource_config config;
- dma_get_config_defaults(&config);
- config.peripheral_trigger = EDBG_CDC_SERCOM_DMAC_ID_RX;
- config.trigger_action = DMA_TRIGGER_ACTON_BEAT;
- dma_allocate(resource, &config);}
- static void setup_transfer_descriptor_rx(DmacDescriptor *descriptor)
- { struct dma_descriptor_config descriptor_config;
- dma_descriptor_get_config_defaults(&descriptor_config);
- descriptor_config.beat_size = DMA_BEAT_SIZE_HWORD;
- descriptor_config.src_increment_enable = false;
- descriptor_config.block_transfer_count = BUFFER_LEN;
- descriptor_config.destination_address = (uint32_t)string + sizeof(string);
- descriptor_config.source_address = (uint32_t)(&usart_instance.hw->USART.DATA.reg);
- dma_descriptor_create(descriptor, &descriptor_config);}
- static void configure_dma_resource_tx(struct dma_resource *resource)
- { struct dma_resource_config config;
- dma_get_config_defaults(&config);
- config.peripheral_trigger = EDBG_CDC_SERCOM_DMAC_ID_TX;
- config.trigger_action = DMA_TRIGGER_ACTON_BEAT;
- dma_allocate(resource, &config);}
- static void setup_transfer_descriptor_tx(DmacDescriptor *descriptor)
- { struct dma_descriptor_config descriptor_config;
- dma_descriptor_get_config_defaults(&descriptor_config);
- descriptor_config.beat_size = DMA_BEAT_SIZE_HWORD;
- descriptor_config.dst_increment_enable = false;
- descriptor_config.block_transfer_count = BUFFER_LEN;
- descriptor_config.source_address = (uint32_t)string + sizeof(string);
- descriptor_config.destination_address = (uint32_t)(&usart_instance.hw->USART.DATA.reg);
- dma_descriptor_create(descriptor, &descriptor_config);}
- static void configure_usart(void)
- { struct usart_config config_usart;
- usart_get_config_defaults(&config_usart);
- config_usart.baudrate = 9600;
- config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
- config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
- config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
- config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
- config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
- while (usart_init(&usart_instance, EDBG_CDC_MODULE, &config_usart) != STATUS_OK) { }
- usart_enable(&usart_instance);}
-
- int main (void)
- {
-
-
- /* Initialize the system and console*/
- system_init();
- configure_usart();
- configure_dma_resource_rx(&usart_dma_resource_rx);
- configure_dma_resource_tx(&usart_dma_resource_tx);
- setup_transfer_descriptor_rx(&example_descriptor_rx);
- setup_transfer_descriptor_tx(&example_descriptor_tx);
- dma_add_descriptor(&usart_dma_resource_rx, &example_descriptor_rx);
- dma_add_descriptor(&usart_dma_resource_tx, &example_descriptor_tx);
- dma_register_callback(&usart_dma_resource_rx, transfer_done_rx, DMA_CALLBACK_TRANSFER_DONE);
- dma_register_callback(&usart_dma_resource_tx, transfer_done_tx, DMA_CALLBACK_TRANSFER_DONE);
- dma_enable_callback(&usart_dma_resource_rx, DMA_CALLBACK_TRANSFER_DONE);
- dma_enable_callback(&usart_dma_resource_tx, DMA_CALLBACK_TRANSFER_DONE);
-
- dma_start_transfer_job(&usart_dma_resource_rx); while (true) { }</P>
- <P>}
- </P>
以下是运行结果:
每当我键入8个字符后,就通过串口输出:
|