大家好,關於W801的DMA使用,我是用DMA捕獲輸入PWM信號的占空比,根據手冊上升沿下降沿均會捕獲當前計數值到捕獲寄存器,使用DMA關聯PWM捕獲可以減少中斷次數,有幾個問題諮詢一下:
1、因為一直要進行捕獲,所以想把DMA設置成一直捕獲,接收緩沖區循環存儲捕獲值,存滿了從頭再開始存儲,請問如何設置?
2、手冊中“DMA數據流控制寄存器”有一個auto_reload標志,這個標志是什麼含義?沒有設置為循環模式時,該位置為1是不是DMA就可以一直循環發送下去?該位置一的時候DMA發送完成中斷會每發完一次重複發生嗎?
3、DMA循環長度寄存器,裡面有兩個長度,一個是目的地址循環長度,一個是源地址循環長度,這個長度單位是字節還是字?比如DMA捕獲輸入PWM信號的占空比存到內部緩沖區,按WORD方式傳送,burst 1,緩沖區長度100字節,這兩個長度參數如何設置?另外這種循環模式下,DMA傳輸完成中斷是什麼時候發生?我試了多種可能都沒跑起來。
提前感謝各位大佬熱心幫忙!
不知道這個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);
}
@isme 非常感謝,這段代碼可以實現DMA傳送,但是好像不能循環發送。我的應用是捕獲來自PWM的占空比,捕獲後通過DMA傳送到RAM緩沖區。我對這個占空比的計算不必實時處理,需要的時候處理一下就可以。這個PWM頻率比較高,為了節約RAM以及減少中斷(PWM中斷和DMA中斷最好都不用),我設定一個固定長度的緩沖區,DMA填滿以後自動從頭再填,循環往複。我需要用的時候直接讀最近的一批緩沖區數據就可以。