本帖最后由 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则里边数据完整运行成功:
|