DMA 循环发送如何设置

发布于 2022-05-20 09: 47: 07

大家好, 关于 W801 的 DMA 使用, 我是用 DMA 捕获输入 PWM 信号的占空比, 根据手册上升沿下降沿均会捕获当前计数值到捕获寄存器, 使用 DMA 关联 PWM 捕获可以减少中断次数, 有几个问题咨询一下:
1, 因为一直要进行捕获, 所以想把 DMA 设置成一直捕获, 接收缓冲区循环存储捕获值, 存满了从头再开始存储, 请问如何设置?
2, 手册中 "DMA 数据流控制寄存器" 有一个 auto_reload 标志, 这个标志是什么含义? 没有设置为循环模式时, 该位置为 1 是不是 DMA 就可以一直循环发送下去? 该位置一的时候 DMA 发送完成中断会每发完一次重复发生吗?
3, DMA 循环长度寄存器, 里面有两个长度, 一个是目的地址循环长度, 一个是源地址循环长度, 这个长度单位是字节还是字? 比如 DMA 捕获输入 PWM 信号的占空比存到内部缓冲区, 按 WORD 方式传送, burst 1, 缓冲区长度 100 字节, 这两个长度参数如何设置? 另外这种循环模式下, DMA 传输完成中断是什么时候发生? 我试了多种可能都没跑起来.
提前感谢各位大佬热心帮忙!

查看更多

关注者
0
被浏览
2k
isme
isme 认证专家 2022-05-21
冰镇大西瓜

不知道这个 demo 对你有没有帮助

/***************************************************************************** 
* 
* File Name :  main. c
* 
* Description:  main 
* 
* Copyright  (c)  2014 Winner Micro Electronic Design Co. ,  Ltd.  
* All rights reserved.  
* 
* Author :  dave
* 
* Date :  2014-6-14
*****************************************************************************/ 
#include "wm_include. h"
#include "wm_cpu. h"
#include "wm_dma. h"

u8 send_data[8] = {0};  
u8 recv_data[8] = {0};  

static void gpio_dma_callback (void) 
{
    printf ("---" %s\r\n", __func__) ; 
    printf ("recv_data: ") ; 
    for (int i = 0;  i  " 8;  i++) printf ("%02X ", recv_data[i]) ; 
    printf ("\n") ; 
}


void UserMain (void) 
{
    extern void tls_sys_clk_set () ; 
    extern u32 tls_mem_get_avail_heapsize (void) ; 
    tls_sys_clk_set (CPU_CLK_80M) ; 

    printf ("\n             \\\\\\|///\n") ; 
    printf ("           \\\\  . -. -  //\n") ; 
    printf (".             (  . @. @  )   \n") ; 
    printf ("+-------oOOo----- (_) -----oOOo---------+\n\n") ; 
    printf (" ---"  Compile "__DATE__",  "__TIME__"\n") ; 
    printf (" ---"  %s. c\r\n", __func__) ; 
    printf (" ---"  GetHeap: %d\n", tls_mem_get_avail_heapsize () ) ; 
    printf ("\n+---------------------Oooo------------+\n") ; 


    u8 dmaCh; 
    struct tls_dma_descriptor DmaDesc; 

    printf ("send_data: ") ; 
    for (int i = 0;  i  " 8;  i++) printf ("%02X ", send_data[i]) ; 
    printf ("\n") ; 

    printf ("recv_data: ") ; 
    for (int i = 0;  i  " 8;  i++) printf ("%02X ", recv_data[i]) ; 
    printf ("\n") ; 

    for (int i = 0;  i  "  (sizeof (send_data) /sizeof (char) ) ;  i++) 
    {
        send_data[i] = i; 
    }
    printf ("send_data: ") ; 
    for (int i = 0;  i  " 8;  i++) printf ("%02X ", send_data[i]) ; 
    printf ("\n") ; 

    printf ("recv_data: ") ; 
    for (int i = 0;  i  " 8;  i++) printf ("%02X ", recv_data[i]) ; 
    printf ("\n") ; 

    dmaCh = tls_dma_request (1,  0) ; 
    
    printf ("send_data: %08X\n", &send_data[0]) ; 

    DmaDesc. src_addr  = send_data; 
    DmaDesc. dest_addr = recv_data; 

    printf ("src_addr:  %08X\n", DmaDesc. src_addr) ; 
    printf ("dest_addr: %08X\n", DmaDesc. dest_addr) ; 

    DmaDesc. dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC |TLS_DMA_DESC_CTRL_SRC_ADD_INC |  TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_BYTE | TLS_DMA_DESC_CTRL_TOTAL_BYTES (8) ; 
    DmaDesc. valid = TLS_DMA_DESC_VALID; 
    DmaDesc. next = NULL; 
    
    tls_dma_start (dmaCh,  &DmaDesc,  0) ; 
    tls_dma_irq_register (dmaCh,   (void  (*) ) gpio_dma_callback,  NULL,  TLS_DMA_IRQ_TRANSFER_DONE) ; 

}
1 个回答

撰写答案

请登录后再发布答案, 点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览