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 個回答

撰寫答案

請登錄後再發布答案,點擊登錄

發布
問題

分享
好友

手機
浏覽

掃碼手機浏覽