中级会员
 
- 积分
- 263
- 金钱
- 263
- 注册时间
- 2024-12-9
- 在线时间
- 15 小时
|
前言
本使用指南描述了怎么使用DMA弹性映射请求,使得DMA请求配置更加灵活。此功能在AT32部分型号上支持,使用时需要注意是否可使用在当前型号.
支持型号列表:AT32F403A 系列AT32F407 系列AT32F413 系列AT32F415 系列AT32F425 系列AT32L021 系列AT32A403A 系列
备注说明:本文档仅供有需求的小伙伴参考,如需更详细资料,可访问雅特力官网获取:https://www.arterytek.com/downlo ... pping_ZH_V2.0.0.pdf
1. 概述
在使用 Artery 部分系列 MCU 时(如 AT32F413\ AT32F415\ AT32F403A\ AT32F407),可以使用DMA 弹性映射功能。此功能使得 DMA 的通道配置更加灵活,可以将某外设的 DMA 请求通道指定到DMA1 或者 DMA2 共 14 个通道中的任意一个通道。(如:可以将 SPI1 接受数据的 DMA 请求指定到DMA1 的通道 7)。
本指南将介绍如何使用 DMA 弹性映射请求,从而使得 DMA 传输变得更加灵活多变
2.配置及使用方法
2.1 常规 DMA 使用(DMA 固定映射)
常规的 DMA 使用以及配置方式为:外设的 DMA 通道已经固定且不可改变,使用时配置好再使能固定通道即可。这就意味着如果想开启某个外设的 DMA 功能,那么通道是不可改变的,例如想使用SPI1 的 RX DMA 功能,那么就要查看 RM 的手册,如下:
2.2 DMA 弹性映射使用
DMA 弹性映射请求功能提供了一种更灵活的使用方式,即外设的 DMA 通道不固定,可选择 DMA1和 DMA2 中,共 14 个通道的任意一个通道。想要使用此功能,需要通过以下几步的设定
1) 开启 DMA 弹性映射功能将 DMA 的通道来源寄存器 1 的第 24bit 写 1,即 DMA_SRC_SEL1 寄存器的 DMA_FLEX_EN 位。向通道设置对应的寄存器中写入相应的硬件 ID 号每个外设的 DMA 请求都分配了一个硬件 ID 号,只要将这个 ID 号写进通道来源寄存器中即可。ID 号可查看 RM 中的表格,以 403A 为例,如下:
上表中的 CHx_SRC 设定值就是硬件 ID 号,将这个 ID 号写进通道来源寄存器中的对应通道 bit 位就可以了。例如:要将 SPI1 的 RX 的 DMA 请求映射到 DMA1 的通道 7,那么就要将 0x09 写入到DMA_SRC_SEL1 寄存器的 CH7_SRC[23:16]。其他配置与常规 DMA 配置相同通过以上 3 步的配置,弹性映射功能即可使用。
注:DMA1/2 的 DMA_FLEX_EN 必须要同时设定为 1 或 0 时,DMA1/2 的映像模式必须一致。无法 DMA1 是固定式映像,DMA2 是弹性式映像。
2) DMA 弹性映射库函数使用以上的配置在BSP中的dma.h\dma.c的库文件中有提供相应的库函数,使用者只需调用库函数即可完成DMA弹性映射模式的配置。库函数说明如下
此函数只需在配置好DMA常规功能后调用即可,如下
3.例程说明
DMA弹性映射功能在BSP中例程,路径为:AT32F403A_407_Firmware_Library_V2.x.x\project\at_start_f403a\examples\dma\data_to_gpio_flexible(以403A路径为例)下面将对这两个例程做一个使用说明。
 data_to_gpio_flexible
DMA相关的配置代码
- int main(void)
- {
- system_clock_config();
- at32_board_init();
- /* 使能dma2/gpioc/tmr2 时钟*/
- crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE);
- crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
- crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
- /* 初始化GPIO口 */
- gpio_init_struct.gpio_pins = GPIO_PINS_ALL;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init(GPIOC, &gpio_init_struct);
- /* 初始化TMR2 */
- tmr_base_init(TMR2, 0xFF, 0);
- tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
- /* 打开TMR2溢出DMA请求 */
- tmr_dma_request_enable(TMR2, TMR_OVERFLOW_DMA_REQUEST, TRUE);
- /* 配置DMA2通道1作为数据传输*/
- dma_reset(DMA2_CHANNEL1);
- dma_init_struct.buffer_size = BUFFER_SIZE;
- dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
- dma_init_struct.memory_base_addr = (uint32_t)src_buffer;
- dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
- dma_init_struct.memory_inc_enable = TRUE;
- dma_init_struct.peripheral_base_addr = (uint32_t)0x4001100C;
- dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
- dma_init_struct.peripheral_inc_enable = FALSE;
- dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
- dma_init_struct.loop_mode_enable = FALSE;
- dma_init(DMA2_CHANNEL1, &dma_init_struct);
- /* enable transfer full data intterrupt */
- dma_interrupt_enable(DMA2_CHANNEL1, DMA_FDT_INT, TRUE);
- /* dma2 channel1 interrupt nvic init */
- nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
- nvic_irq_enable(DMA2_Channel1_IRQn, 1, 0);
- /* 配置DMA弹性功能 */
- dma_flexible_config(DMA2, FLEX_CHANNEL1, DMA_FLEXIBLE_TMR2_OVERFLOW);
- /* 使能DMA通道 */
- dma_channel_enable(DMA2_CHANNEL1, TRUE);
- /* 使能tmr2 */
- tmr_counter_enable(TMR2, TRUE);
- while(1)
- {
- }
- }
复制代码
|
|