第二部分 基础篇-第10章 CC2530 DMA

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013162035/article/details/78999299

1 理论分析

1.1 CC2530 的 DMA 介绍

直接存取访问(DMA)控制器可以用来减轻 8051CPU 内核传送数据操作的负担,从而实现在高效利用电源的条件下的高性能。只需要 CPU 极少的干预,DMA 控制器就可以将数据从诸如 ADC 或 RF 收发器的外设单元传送到存储器。
DMA 控制器协调所有的 DMA 传送,确保 DMA 请求和 CPU 存储器访问之间按照优先等级协调、合理地进行。DMA 控制器含有若干可编程的 DMA 通道,用来实现存储器-存储器的数据传送。
DMA 控制器控制整个 XDATA 存储空间的数据传送。由于大多数 SFR 寄存器映射到 DMA 存储器空间,这些灵活的 DMA 通道的操作能够以创新的方式减轻 CPU 的负担,例如,从存储器传送数据到 USART,或定期在 ADC 和存储器之间传送数据样本,等等。使用 DMA 还可以保持 CPU 在低功耗模式下与外设单元之间传送数据,不需要唤醒,这就降低了整个系统的功耗。
DMA 控制器的主要功能如下:
 5 个独立的 DMA 通道
 3 个可以配置的 DMA 通道优先级
 32 个可以配置的传送触发事件
 源地址和目标地址的独立控制
 单独传送、数据块传送和重复传送模式
 支持传输数据的长域域,设置可变传输长度
 既可以工作在字模式,又可以工作在字节模式。

1.2 CC2530 的 DMA 操作

为了使用 DMA 通道,必须进行以下两步操作:
(1) DMA 配置数据结构;
(2) DMA 寄存器配置。
当 DMA 通道配置完毕后,在允许任何传输发起之前,必须进入工作状态。DMA通道通过将 DMA 通道工作状态寄存器 DMAARM 中指定位置 1, 就可以进入工作状态。一旦 DMA 通道进入工作状态,当配置的 DMA 触发事件发生时,传送就开始了。注意一个通道准备工作状态(即获得配置数据)的时间需要 9 个系统时钟,因此如果相的 DMAARM 位设置,触发在需要配置通道的时间内出现,期望的触发将丢失。如果多于一个 DMA 通道同时进入工作状态,所有通道配置的的时间将长一些(按顺序读取内存) 。如果所有 5 个通道都进入工作状态,需要 45 个系统时钟,通道 1 首先准备好,然后是通道 2,最后是通道 0(所有都在最后 8 个系统时钟内) 。可能的 DMA 触发事件有 32 个,例如 UART 传输、定时器溢出等。DMA 通道要使用的触发事件由 DMA 通道配置设置,因此直到配置被读取之后,才能知道。
补充一点,为了通过 DMA 触发事件开始 DMA 传送,用户软件可以设置对应的 DMAREQ 位,强制使一个 DMA 传送开始。

这里写图片描述

图1

1.3 DMA配置参数

DMA运行的安装和控制由用户软件完成。本节描述了DMA通道能够使用之前,必须配置的参数。
这五个DMA通道每一个的行为通过下列参数配置:
源地址:DMA通道要读的数据的首地址。
目标地址:DMA通道从源地址读出的要写数据的首地址。用户必须确认该目标地址可写。
传送长度:在DMA通道重新进入工作状态或者解除工作状态之前,以及警告CPU即将有中断请求到来之前,要传送的长度。长度可以在配置中定义,或可以如下所述定义为VLEN设置。
可变长度 ( VLEN) 设置: DMA通道可以利用源数据中的第一个字节或字作为传送长度进行可变长度传输。使用可变长度传输时,要给出关于如何计算要传输的字节数的各种选项。
优先级别: DMA通道的DMA传送的优先级别与CPU、其它DMA通道和访问端口相关。
触发事件:所有DMA传输通过所谓的 DMA触发事件来发起。这个触发可以启动一个 DMA块传输或单个DMA传输。 除了已经配置的触发,DMA通道总是可以通过设置它的指定DMAREQ.DMAREQx标志来触发。
源地址和目标地址增量:源地址和目标地址可以控制为增量或减少,或不改变。
传送模式:传送模式确定传送是否是单个传输,或块传输,或是它们的重复传输。
字节传送或字传送:确定每个DMA传输应该是8位(字节)或是16位(字)。
中断屏蔽:在完成DMA通道传送时,产生一个中断请求。这个中断屏蔽位控制中断产生是使能还是禁用。
M8:这个域的值,决定是否采用7位还是8位长的字节来传送数据。此模式仅仅适用于字节传送。

1.4 DMA存储访

DMA数据传输被端约定影响。注意DMA描述符遵循大端约定,而其他描述符遵循小端约定。这必须在编译器中说明。

表1 DMA触发

这里写图片描述这里写图片描述

表2 DMA配置数据结构

这里写图片描述这里写图片描述

1.5 DMA 测试流程图

下面是本实验的流程图,大家可以结合这个图来学习编写程序。

这里写图片描述

图2流程图

2 实验详解

2.1 实验目的

1)、了解 CC2530 的 DMA 的功能;
2)、掌握 CC2530 的 DMA 的简单测试。

2.2实验设备

硬件:PC 机一台,ZB2530(底板、核心板、仿真器、USB 线)一套;
软件:2000/XP/win7 系统,IAR 8.20 集成开发环境。

2.3实验相关电路图

这里写图片描述

图3 按键电路图

2.4实验分析

本节描述了与DMA控制器相关的SFR寄存器。

表3

这里写图片描述

表4

这里写图片描述

表5

这里写图片描述

表6

这里写图片描述

表7

这里写图片描述

表8

这里写图片描述

表9

这里写图片描述

2.5参考代码(部分代码)

/**Includes*********************************************************************/
#include <ioCC2530.h>
#include "Uart.h"
#include "hal.h"

/**宏定义***********************************************************************/
#define KEY1 P0_1 
#define KEY2 P2_0

#define LED1 P1_0
#define LED2 P1_1
#define LED3 P1_4

/**函数声明*********************************************************************/
void Configure_DMADataStruct(void);
void DMA_Configure(void);
void Start_DMA(void);
void Data_Check(void);

/**全局变量*********************************************************************/
DMA_DESC DMAConfigure;
char sourceString[] = "This is a test string used to demonstrate DMA transfer.";
char destString[ sizeof(sourceString) ];
uchar Flag=0;

/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main(void)
{    
    SetSysClock();

    InitUART();

    memset(destString, 0, sizeof(destString) );//Clearing the destination

    Configure_DMADataStruct();/*1、DMA使用步骤一:DMA 配置数据结构*/

    DMA_Configure();/*2、DMA使用步骤二:DMA 寄存器配置*/

    Start_DMA();

    Data_Check();

    while(1);
}

/**
  * @brief     DMA 配置数据结构
  * @param     None
  * @retval    None
  */
void Configure_DMADataStruct(void)
{
    SET_WORD(DMAConfigure.SRCADDRH, DMAConfigure.SRCADDRL,   &sourceString); // 1、DMA通道源地址
    SET_WORD(DMAConfigure.DESTADDRH, DMAConfigure.DESTADDRL, &destString);   // 2、DMA通道目的地址
    SET_WORD(DMAConfigure.LENH, DMAConfigure.LENL, sizeof(sourceString));    // 3、DMA的通道传送长度
    DMAConfigure.VLEN      = VLEN_USE_LEN;  // 4、可变长度传输模式
    DMAConfigure.WORDSIZE  = WORDSIZE_BYTE; // 5、选择每个DMA传送是采用8位(0) 还是16位(1)
    DMAConfigure.TMODE     = TMODE_BLOCK;   // 6、DMA通道传送模式
    DMAConfigure.TRIG      = DMATRIG_NONE;  // 7、选择要使用的DMA触发(本例程选择由用户强制开始传送)
    DMAConfigure.SRCINC    = SRCINC_1;      // 8、源地址递增模式(每次传送之后)
    DMAConfigure.DESTINC   = DESTINC_1;     // 9、目的地址递增模式(每次传送之后)
    DMAConfigure.IRQMASK   = FALSE;         // 10、该通道的中断屏蔽    
    DMAConfigure.M8        = M8_USE_8_BITS; // 11、采用VLEN的第8位模式作为传送单位长度;仅应用在WORDSIZE=0且VLEN从000到111时
    DMAConfigure.PRIORITY  = PRI_HIGH;      // 12、DMA通道的优先级别    
}    

/**
  * @brief     DMA 寄存器配置(本实验用DMA通道0)
  * @param     None
  * @retval    None
  */
void DMA_Configure(void)
{
  DMA_SET_ADDR_DESC0(&DMAConfigure);//1、DMA 通道进入工作状态(DMA0CFGH、DMA0CFGL)
  DMA_ABORT_CHANNEL(0);//2、停止所有通道,并选择通道0(DMAARM)
  DMA_ARM_CHANNEL(0);//3、选择通道0(DMAARM)
}

/**
  * @brief      启动DMA并等待数据传输完成
  * @param     None
  * @retval    None
  */
void Start_DMA(void)
{
    UartSend_String("Start DMA.\n",sizeof("Start DMA.\n"));  //发送数据
    Delayms(100); 

    while(KEY1) //检测到按键KEY1,设定DMA从RAM里转出数据

    Delayms(100);

    DMAIRQ = 0x00;//清中断标志
    DMA_START_CHANNEL(0);//DMAREQ0置位---启动DMA
    while(!(DMAIRQ & DMA_CHANNEL_0));//等待传输完毕,中断标志置位
}

/**
  * @brief     比较源数据与目标数据是否一致
  * @param     None
  * @retval    None
  */
void Data_Check(void)
{
    uchar i;
    uchar errors = 0;

    for(i=0;i<sizeof(sourceString);i++)
    {
        if(sourceString[i] != destString[i])
        errors++; //记录错误的数据个数
    }

    if(errors == 0)
    {
        UartSend_String("The test of DMA is successful.\n",sizeof("The test of DMA is successful.\n"));  //发送数据
        LED3=1;//用作指示

    }
    else
    {
        UartSend_String("The test of DMA is failed.\n",sizeof("The test of DMA is failed.\n"));  //发送数据
    }    
}

2.6实验现象

编译下载程序到开发板上,接着打开串口调试助手,并配置它的相关参数,按下复位按键,然后再按下 BUT1,即可看到下面的实验现象。

2.7实验总结

通过本实验,大家需要掌握以下 3 点:
 DMA 控制器的主要功能如下:
(1) 5 个独立的 DMA 通道
(2)3 个可以配置的 DMA 通道优先级
(3) 32 个可以配置的传送触发事件
(4) 源地址和目标地址的独立控制
(5) 单独传送、数据块传送和重复传送模式
(6) 支持传输数据的长域域,设置可变传输长度
(7) 既可以工作在字模式,又可以工作在字节模式
 为了使用 DMA 通道,必须进行以下两步操作:
(1) DMA 配置数据结构;
(2) DMA 寄存器配置。
 只需要 CPU 极少的干预,DMA 控制器就可以将数据从诸如 ADC 或 RF 收发器的外设单元传送到存储器。

本章参考代码

点击进入

阅读更多
换一批

没有更多推荐了,返回首页