航班网站开发设计说明书,网络营销论文题目,如何注销公司流程及费用,如何设置网站域名目录 概述#xff1a;
端口设置#xff1a;
代码分析#xff1a;
运行现象#xff1a; 概述#xff1a;
DMA#xff08;Direct Memory Access#xff09;是一种计算机系统中的数据传输技术#xff0c;它允许数据在不经过中央处理器#xff08;CPU#xff09;的直…目录 概述
端口设置
代码分析
运行现象 概述
DMADirect Memory Access是一种计算机系统中的数据传输技术它允许数据在不经过中央处理器CPU的直接控制下在内存和外设之间传输。UARTUniversal Asynchronous Receiver/Transmitter是一种串行通信协议用于在设备之间传输数据。
在DMA接收和发送数据的情况下DMA可以用于管理UART通信中的数据传输。具体来说 DMA接收数据 当UART接收到数据时通常会触发中断来通知CPU。使用DMA时DMA控制器可以直接从UART接收缓冲区中读取数据并将其存储到内存中而无需CPU的干预。这允许在数据到达时实现高效的数据传输减轻了CPU的负担。 DMA发送数据 当需要通过UART发送数据时通常需要将数据写入UART的发送缓冲区并等待发送完成。使用DMA时DMA控制器可以直接从内存中获取要发送的数据并将其传输到UART发送缓冲区而无需CPU的干预。这提高了数据传输的效率因为CPU可以继续执行其他任务而无需等待数据发送完成。
总的来说DMA在UART通信中的应用可以提高数据传输的效率减少对CPU的依赖使系统能够更有效地处理数据。
端口设置
波特率115200 1位停止位 无奇偶校验
代码分析
包含了一些头文件包含了与底层硬件和外设驱动相关的定义和函数声明
义了一些与UART相关的宏如UART的基地址、时钟名、DMA请求等
声明了两个全局变量 uart_tx_dma_done 和 uart_rx_dma_done用于表示UART的发送和接收DMA是否完成
#include board.h
#include hpm_clock_drv.h
#include hpm_uart_drv.h
#ifdef CONFIG_HAS_HPMSDK_DMAV2
#include hpm_dmav2_drv.h
#else
#include hpm_dma_drv.h
#endif
#include hpm_dmamux_drv.h
#include hpm_l1c_drv.h
#include hpm_common.h#define TEST_UART BOARD_APP_UART_BASE
#define TEST_UART_CLK_NAME BOARD_APP_UART_CLK_NAME
#define TEST_UART_TX_DMA_REQ BOARD_APP_UART_TX_DMA_REQ
#define TEST_UART_RX_DMA_REQ BOARD_APP_UART_RX_DMA_REQ#define TEST_UART_DMA_CONTROLLER BOARD_APP_HDMA
#define TEST_UART_DMAMUX_CONTROLLER BOARD_APP_DMAMUX
#define TEST_UART_TX_DMA_CHN (0U)
#define TEST_UART_RX_DMA_CHN (1U)
#define TEST_UART_TX_DMAMUX_CHN DMA_SOC_CHN_TO_DMAMUX_CHN(TEST_UART_DMA_CONTROLLER, TEST_UART_TX_DMA_CHN)
#define TEST_UART_RX_DMAMUX_CHN DMA_SOC_CHN_TO_DMAMUX_CHN(TEST_UART_DMA_CONTROLLER, TEST_UART_RX_DMA_CHN)
#define TEST_UART_DMA_IRQ BOARD_APP_HDMA_IRQ#define TEST_BUFFER_SIZE (16U)
ATTR_PLACE_AT_NONCACHEABLE uint8_t uart_buff[TEST_BUFFER_SIZE];volatile bool uart_tx_dma_done;
volatile bool uart_rx_dma_done; hpm_stat_t uart_tx_trigger_dma(DMA_Type *dma_ptr,uint8_t ch_num,UART_Type *uart_ptr,uint32_t src,uint32_t size)
{dma_handshake_config_t config;dma_default_handshake_config(dma_ptr, config);config.ch_index ch_num;config.dst (uint32_t)uart_ptr-THR;config.dst_fixed true;config.src src;config.src_fixed false;config.data_width DMA_TRANSFER_WIDTH_BYTE;config.size_in_byte size;return dma_setup_handshake(dma_ptr, config, true);
} 参数说明 dma_ptr: DMA控制器的指针指向用于配置和控制DMA的硬件寄存器。ch_num: DMA通道号表示要配置的DMA通道。uart_ptr: UART控制器的指针指向用于配置和控制UART的硬件寄存器。src: 数据源的地址这是UART发送数据的来源。size: 要传输的数据大小以字节为单位。 函数逻辑 创建一个 dma_handshake_config_t 类型的结构体变量 config用于配置DMA的握手参数。调用 dma_default_handshake_config 函数初始化 config 结构体设置了一些默认的DMA握手参数。设置 config 结构体的各个成员 ch_index: DMA通道号。dst: 目的地地址这里是UART的传输保持寄存器THR - Transmitter Holding Register的地址。dst_fixed: 目的地地址是否固定这里设置为 true表示目的地地址不变。src: 数据源地址即要发送的数据的地址。src_fixed: 数据源地址是否固定这里设置为 false表示数据源地址可能变化。data_width: 数据传输宽度这里设置为字节宽度。size_in_byte: 要传输的数据大小。 返回值 调用 dma_setup_handshake 函数根据配置好的参数设置DMA握手并返回相应的状态。 注意事项 该函数通过设置DMA的握手参数将UART的发送数据配置到DMA通道中并返回相应的状态用于后续判断是否配置成功。
这个函数的作用是通过DMA实现UART的发送数据配置了DMA握手参数确保数据正确地传输到UART传输保持寄存器中。 hpm_stat_t uart_rx_trigger_dma(DMA_Type *dma_ptr,uint8_t ch_num,UART_Type *uart_ptr,uint32_t dst,uint32_t size)
{dma_handshake_config_t config;dma_default_handshake_config(dma_ptr, config);config.ch_index ch_num;config.dst dst;config.dst_fixed false;config.src (uint32_t)uart_ptr-RBR;config.src_fixed true;config.data_width DMA_TRANSFER_WIDTH_BYTE;config.size_in_byte size;return dma_setup_handshake(dma_ptr, config, true);
} 参数说明 dma_ptr: DMA控制器的指针指向用于配置和控制DMA的硬件寄存器。ch_num: DMA通道号表示要配置的DMA通道。uart_ptr: UART控制器的指针指向用于配置和控制UART的硬件寄存器。dst: 数据目的地的地址这是用于存储UART接收数据的缓冲区的地址。size: 要传输的数据大小以字节为单位。 函数逻辑 创建一个 dma_handshake_config_t 类型的结构体变量 config用于配置DMA的握手参数。调用 dma_default_handshake_config 函数初始化 config 结构体设置了一些默认的DMA握手参数。设置 config 结构体的各个成员 ch_index: DMA通道号。dst: 目的地地址即UART接收数据的缓冲区地址。dst_fixed: 目的地地址是否固定这里设置为 false表示目的地地址可能变化。src: 数据源地址这里是UART的接收保持寄存器RBR - Receiver Buffer Register的地址。src_fixed: 数据源地址是否固定这里设置为 true表示数据源地址不变。data_width: 数据传输宽度这里设置为字节宽度。size_in_byte: 要传输的数据大小。 返回值 调用 dma_setup_handshake 函数根据配置好的参数设置DMA握手并返回相应的状态。 注意事项 该函数通过设置DMA的握手参数将UART的接收数据配置到DMA通道中并返回相应的状态用于后续判断是否配置成功。
这个函数的作用是通过DMA实现UART的接收数据配置了DMA握手参数确保UART接收到的数据传输到指定的缓冲区中。 void dma_isr(void)
{volatile hpm_stat_t stat_rx_chn, stat_tx_chn;stat_rx_chn dma_check_transfer_status(TEST_UART_DMA_CONTROLLER, TEST_UART_RX_DMA_CHN);if (stat_rx_chn DMA_CHANNEL_STATUS_TC) {uart_rx_dma_done true;}stat_tx_chn dma_check_transfer_status(TEST_UART_DMA_CONTROLLER, TEST_UART_TX_DMA_CHN);if (stat_tx_chn DMA_CHANNEL_STATUS_TC) {uart_tx_dma_done true;}
}
SDK_DECLARE_EXT_ISR_M(TEST_UART_DMA_IRQ, dma_isr) 函数逻辑 定义两个局部变量 stat_rx_chn 和 stat_tx_chn用于保存DMA通道的传输状态。调用 dma_check_transfer_status 函数检查UART接收和发送的DMA通道的传输状态。如果接收通道的传输状态中包含 DMA_CHANNEL_STATUS_TC传输完成则将 uart_rx_dma_done 置为 true表示UART接收DMA完成。如果发送通道的传输状态中包含 DMA_CHANNEL_STATUS_TC则将 uart_tx_dma_done 置为 true表示UART发送DMA完成。 注意事项 volatile 修饰 stat_rx_chn 和 stat_tx_chn表示这两个变量可能在中断服务例程之外被修改确保编译器不会对它们进行优化。中断处理函数通过检查DMA通道的传输状态来确定DMA是否完成从而设置相应的标志位。 宏 SDK_DECLARE_EXT_ISR_M 该宏用于声明外部中断服务例程。在这里使用该宏声明了中断服务例程 dma_isr 并关联到 TEST_UART_DMA_IRQ 所指定的中断。
这个中断服务例程的作用是在DMA传输完成时被调用检查相应的DMA通道状态并设置标志位以通知主程序相应的DMA传输已完成。 int main(void)
{hpm_stat_t stat;uart_config_t config {0};board_init();printf(UART DMA \n);printf(UART will send back received characters, echo every %d bytes\n, TEST_BUFFER_SIZE);/* if TEST_UART is same as BOARD_CONSOLE_BASE, it has been initialized in board_init(); */board_init_uart(TEST_UART);uart_default_config(TEST_UART, config);config.fifo_enable true;config.dma_enable true;config.src_freq_in_hz clock_get_frequency(TEST_UART_CLK_NAME);config.tx_fifo_level uart_tx_fifo_trg_not_full;config.rx_fifo_level uart_rx_fifo_trg_not_empty;stat uart_init(TEST_UART, config);if (stat ! status_success) {printf(failed to initialize uart\n);while (1) {}}intc_m_enable_irq_with_priority(TEST_UART_DMA_IRQ, 1);dmamux_config(TEST_UART_DMAMUX_CONTROLLER, TEST_UART_RX_DMAMUX_CHN, TEST_UART_RX_DMA_REQ, true);dmamux_config(TEST_UART_DMAMUX_CONTROLLER, TEST_UART_TX_DMAMUX_CHN, TEST_UART_TX_DMA_REQ, true);while (1) {/* config rx dma transfer */stat uart_rx_trigger_dma(TEST_UART_DMA_CONTROLLER,TEST_UART_RX_DMA_CHN,TEST_UART,core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_buff),TEST_BUFFER_SIZE);if (stat ! status_success) {printf(uart rx trigger dma failed\n);break;}while (!uart_rx_dma_done) {__asm(nop);}uart_rx_dma_done false;/* config tx dma transfer */stat uart_tx_trigger_dma(TEST_UART_DMA_CONTROLLER,TEST_UART_TX_DMA_CHN,TEST_UART,core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_buff),TEST_BUFFER_SIZE);if (stat ! status_success) {printf(uart tx trigger dma failed\n);break;}while (!uart_tx_dma_done) {__asm(nop);}uart_tx_dma_done false;}while (1) {__asm(nop);}return 0;
}代码逻辑 调用 board_init 初始化板子。输出一些提示信息包括 UART DMA 和 UART 将返回接收到的字符每次回显的字节数。如果 TEST_UART 与 BOARD_CONSOLE_BASE 相同说明UART已在 board_init 中初始化。调用 board_init_uart 初始化UART。初始化UART配置包括使能FIFO、DMA设置传输频率等。调用 uart_init 初始化UART检查初始化是否成功。启用DMA中断并配置UART的DMA传输请求。进入主循环循环中 配置UART接收的DMA传输。等待UART接收DMA完成。配置UART发送的DMA传输。等待UART发送DMA完成。如果在DMA配置过程中发生错误输出相应的错误信息并跳出主循环。主循环最后有一个空操作用于保持程序运行。
该主函数的主要任务是配置并执行UART的DMA传输实现了UART接收到的数据的回显。 以下是上述代码的主要运行流程 初始化 初始化嵌入式系统板。打印一些信息包括 UART DMA 和一条关于将接收到的字符发送回去的消息。初始化 UART 模块包括配置 UART 的基本参数和启用 DMA。 设置中断和DMA多路复用 启用 UART DMA 中断并设置中断优先级。配置 DMA 多路复用将 RX 和 TX DMA 通道与 UART 的相应请求关联。 主循环 进入一个无限循环该循环执行以下操作 配置 RX DMA 传输设置 UART 接收的 DMA 传输将接收到的数据存储在 uart_buff 缓冲区中。等待 RX DMA 传输完成通过轮询等待 uart_rx_dma_done 标志。在数据前添加 send 前缀将 send 字符串复制到 uart_buff 的开头。配置 TX DMA 传输设置 UART 发送的 DMA 传输发送整个 uart_buff 缓冲区的数据。等待 TX DMA 传输完成通过轮询等待 uart_tx_dma_done 标志。 结束 由于主循环是一个无限循环因此在实际应用中可能需要添加适当的终止条件。在实际应用中可能还需要在主循环中添加对接收到的数据的处理逻辑。
总体而言该代码通过 DMA 实现了 UART 数据的异步传输。接收到的数据被存储在 uart_buff 缓冲区中并在发送之前添加了 send 前缀。此过程一直在一个无限循环中进行确保持续接收和发送数据。 运行现象
当工程正确运行后通过串口手动输入字符串如 ‘1234567887654321’则串口终端会收到如下信息 UART DMA example
UART will send back received characters, echo every 16 bytes
1234567887654321