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

[复制链接]
 楼主| ddllxxrr 发表于 2015-11-3 22:12 | 显示全部楼层 |阅读模式
本帖最后由 ddllxxrr 于 2015-11-4 06:18 编辑

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

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

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




  2. /* 使用DMA通道0*/
  3. #define DMAC_CH 0

  4. // LLI 结构
  5. typedef struct _lli{
  6.         uint32_t SADDR;
  7.         uint32_t DADDR;
  8.         uint32_t CTRLA;
  9.         uint32_t CTRLB;
  10.         uint32_t DSCR;
  11. }LLI;

  12. /*[子函数]*/
  13. // 初始化LLI
  14. //lli:需要初始化的LLI的地址
  15. //saddr:源地址
  16. //btsize:传输次数
  17. //next_lli:下一个LLI的地址。如果是最后一个LLI,该参数为NULL即可
  18. void InitLLI(LLI* lli, void* saddr, uint16_t btsize, LLI* next_lli)
  19. {
  20.         lli->SADDR = (uint32_t)saddr;
  21.         lli->DADDR = 0;                // DADDR 不会被使用,初始化为0即可。
  22.         lli->DSCR = DMAC_DSCR_DSCR_Msk & (uint32_t)next_lli;
  23.         lli->CTRLA =  DMAC_CTRLA_BTSIZE(btsize)
  24.         | DMAC_CTRLA_SRC_WIDTH_WORD
  25.         | DMAC_CTRLA_DST_WIDTH_WORD;
  26.         lli->CTRLB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM
  27.         | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE
  28.         | DMAC_CTRLB_FC_MEM2MEM_DMA_FC
  29.         | DMAC_CTRLB_SRC_INCR_INCREMENTING
  30.         | DMAC_CTRLB_DST_INCR_INCREMENTING;
  31. }
  32. /*[主程序]*/
  33. int main (void)
  34. {
  35.         // 定义源缓冲区src
  36.         uint32_t src1[2];
  37.         uint32_t src2[3];
  38.         // 定义目的缓冲区dst
  39.         uint32_t dst[5];
  40.         // 在源缓冲区中填入数据50,51,52,53,54
  41.         src1[0] = 50;
  42.         src1[1] = 51;
  43.         src2[0] = 52;
  44.         src2[1] = 53;
  45.         src2[2] = 54;
  46.         
  47.         SystemInit();
  48.         // 定义缓冲区描述符
  49.         /*注意,要确保LLI的实例在整个程序的运行过程中都是有效的。比如如果LLI是储存在函数的栈中的话,那么函数退出后,该LLI即无效了。所以可以选择在堆中分配LLI实例的空间,或是将其定义为全局变量,也可以在main函数中定义实例。*/
  50.         LLI first_lli;
  51.         LLI last_lli;
  52.         InitLLI(&first_lli, (void*)src1, 2, &last_lli);
  53.         InitLLI(&last_lli, (void*)src2, 3, 0);
  54.         // 使能和初始化DMAC
  55.         PMC->PMC_PCER0 = 1 << ID_DMAC;
  56.         DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_ROUND_ROBIN;        // 轮转优先级
  57.         DMAC->DMAC_EN = DMAC_EN_ENABLE;
  58.         // 配置 DMAC通道
  59.         // 使DSCR指向first_lli
  60.         DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_DSCR = (uint32_t)(void*)(&first_lli);
  61.         // 设置目标地址
  62.         DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_DADDR = (uint32_t)(void*) dst;
  63.         // 设置CTRLB,使通道从LLI中更新源地址
  64.         DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM
  65.         | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE;
  66.         // 配置CFG寄存器
  67.         DMAC->DMAC_CH_NUM[DMAC_CH].DMAC_CFG = DMAC_CFG_SOD_DISABLE
  68.         | DMAC_CFG_FIFOCFG_ALAP_CFG;
  69.         // 使能通道
  70.         DMAC->DMAC_CHER = DMAC_CHER_ENA0 << DMAC_CH;
  71.         // 等待通道关闭,即传输结束
  72.         const uint32_t check_bit = DMAC_CHSR_ENA0 << DMAC_CH;
  73.         while( (DMAC->DMAC_CHSR & check_bit) != 0);
  74.         while(1)
  75.         {
  76.         }
  77. }



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




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2403

主题

6994

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2403

主题

6994

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部