打印
[Atmel]

用SAM-BA或JLINK跑ATSAM4E16的程序(6)寄存器方式DMA传输

[复制链接]
771|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 ddllxxrr 于 2015-11-4 06:18 编辑

这个程序其实是书上的例子,我用JLINK跑了起来,但我的JLINK好像有点哪里不对,选SWD两线制可以跑起来,而选JTAG接口确跑不起来。

这个个程序提把两个数组里边的内容连接成一个完整的数组。由于本程序没有用库,所以建工程时选不带库的工程:

程序如下:
#include "sam.h"




/* 使用DMA通道0*/
#define DMAC_CH 0

// LLI 结构
typedef struct _lli{
        uint32_t SADDR;
        uint32_t DADDR;
        uint32_t CTRLA;
        uint32_t CTRLB;
        uint32_t DSCR;
}LLI;

/*[子函数]*/
// 初始化LLI
//lli:需要初始化的LLI的地址
//saddr:源地址
//btsize:传输次数
//next_lli:下一个LLI的地址。如果是最后一个LLI,该参数为NULL即可
void InitLLI(LLI* lli, void* saddr, uint16_t btsize, LLI* next_lli)
{
        lli->SADDR = (uint32_t)saddr;
        lli->DADDR = 0;                // DADDR 不会被使用,初始化为0即可。
        lli->DSCR = DMAC_DSCR_DSCR_Msk & (uint32_t)next_lli;
        lli->CTRLA =  DMAC_CTRLA_BTSIZE(btsize)
        | DMAC_CTRLA_SRC_WIDTH_WORD
        | DMAC_CTRLA_DST_WIDTH_WORD;
        lli->CTRLB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM
        | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE
        | DMAC_CTRLB_FC_MEM2MEM_DMA_FC
        | DMAC_CTRLB_SRC_INCR_INCREMENTING
        | DMAC_CTRLB_DST_INCR_INCREMENTING;
}
/*[主程序]*/
int main (void)
{
        // 定义源缓冲区src
        uint32_t src1[2];
        uint32_t src2[3];
        // 定义目的缓冲区dst
        uint32_t dst[5];
        // 在源缓冲区中填入数据50,51,52,53,54
        src1[0] = 50;
        src1[1] = 51;
        src2[0] = 52;
        src2[1] = 53;
        src2[2] = 54;
        
        SystemInit();
        // 定义缓冲区描述符
        /*注意,要确保LLI的实例在整个程序的运行过程中都是有效的。比如如果LLI是储存在函数的栈中的话,那么函数退出后,该LLI即无效了。所以可以选择在堆中分配LLI实例的空间,或是将其定义为全局变量,也可以在main函数中定义实例。*/
        LLI first_lli;
        LLI last_lli;
        InitLLI(&first_lli, (void*)src1, 2, &last_lli);
        InitLLI(&last_lli, (void*)src2, 3, 0);
        // 使能和初始化DMAC
        PMC->PMC_PCER0 = 1 << ID_DMAC;
        DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_ROUND_ROBIN;        // 轮转优先级
        DMAC->DMAC_EN = DMAC_EN_ENABLE;
        // 配置 DMAC通道
        // 使DSCR指向first_lli
        DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_DSCR = (uint32_t)(void*)(&first_lli);
        // 设置目标地址
        DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_DADDR = (uint32_t)(void*) dst;
        // 设置CTRLB,使通道从LLI中更新源地址
        DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM
        | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE;
        // 配置CFG寄存器
        DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_CFG = DMAC_CFG_SOD_DISABLE
        | DMAC_CFG_FIFOCFG_ALAP_CFG;
        // 使能通道
        DMAC->DMAC_CHER = DMAC_CHER_ENA0 << DMAC_CH;
        // 等待通道关闭,即传输结束
        const uint32_t check_bit = DMAC_CHSR_ENA0 << DMAC_CH;
        while( (DMAC->DMAC_CHSR & check_bit) != 0);
        while(1)
        {
        }
}



程序运行后:
观查数组3则里边数据完整运行成功:




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6950

帖子

67

粉丝