ZigBee-CC2530单片机 - DMA方式复制数据

ZigBee-CC2530单片机 - DMA方式复制数据

程序源码

#include "ioCC2530.h"
#include "stdio.h"

#define LED1 P1_0     // P1_0定义为P1_0
#define LED2 P1_1     // P1_0定义为P1_1
#define SW1  P1_2     //SW1端口宏定义

enum SYSCLK_SRC
{
    RC_16MHz,XOSC_32MHz
};

/**************************************************************/
#pragma bitfields = reversed     //使用大端格式
typedef struct 
{
  unsigned char SRCADDRH;          // 源地址高字节
  unsigned char SRCADDRL;          // 源地址低字节
  unsigned char DESTADDRH;         // 目标地址高字节
  unsigned char DESTADDRL;         // 目标地址低字节
  unsigned char VLEN      : 3;     // 可变长度传输模式选择
  unsigned char LENH      : 5;     // 传输长度高字节
  unsigned char LENL      : 8;     // 传输长度低字节
  unsigned char WORDSIZE  : 1;     // 字节/字传输
  unsigned char TMODE     : 2;     // 传输模式选择
  unsigned char TRIG      : 5;     // 触发事件选择
  unsigned char SRCINC    : 2;     // 源地址增量
  unsigned char DESTINC   : 2;     // 目标地址增量
  unsigned char IRQMASK   : 1;     // 中断使能
  unsigned char M8        : 1;     // 7/8 bits 字节(只用于字节传输模式)
  unsigned char PRIORITY  : 2;     // 优先级
} DMA_CONFIGURATIONPARAMETERS;

#pragma bitfields = default    //恢复成小端格式

/**************************************************************
函数名称:delay
功    能:软件延时
入口参数:time--延时循环执行次数
出口参数:无
返 回 值:无
**************************************************************/
void delay(unsigned int time)
{
    unsigned int i;
    unsigned char j;
    for(i = 0;i < time;i++)
        for(j = 0;j < 240;j++)
        {
            asm("NOP");//asm用来在C代码中嵌入汇编语言操作,汇
            asm("NOP");//编命令nop是空操作,消耗1个指令周期。
            asm("NOP");
        }
}

/**************************************************************
函数名称:SystemClockSourceSelect
功能:选择系统时钟源(主时钟源)
入口参数:source
          XOSC_32MHz  32MHz晶体振荡器
          RC_16MHz    16MHz RC振荡器
出口参数:无
返回值:无
**************************************************************/
void SystemClockSourceSelect(enum SYSCLK_SRC source)
{
   unsigned char clkconcmd,clkconsta;
   if(source == RC_16MHz)
  {             
    CLKCONCMD &= 0x80;
    CLKCONCMD |= 0x49;       
  }
  else if(source == XOSC_32MHz)
  {
    CLKCONCMD &= 0x80;
  }  
    /* 等待所选择的系统时钟源(主时钟源)稳定 */
  clkconcmd = CLKCONCMD;           // 读取时钟控制寄存器CLKCONCMD
  do
  {
    clkconsta = CLKCONSTA;         // 读取时钟状态寄存器CLKCONSTA
  } while(clkconsta != clkconcmd); // 直到选择的系统时钟源(主时钟源)已经稳定 
}

/**************************************************************
函数名称:init
功能:初始化系统IO
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void initIO(void)
{   P1SEL &= ~0x05;     // 设置LED1、SW1为普通IO口
    P1DIR |= 0x01 ;     // 设置LED1在P1.0为输出    
    P1DIR &= ~0X04;	//sw1按键在 P1.2,设定为输入    
    LED1= 0;            // LED灭
}

/**************************************************************
函数名称:InitUART0
功能:UART0初始化
      P0.2  RX      
      P0.3  TX
      波特率:57600
      数据位:8
      停止位:1
      奇偶校验:无
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void initUART0(void)
{
    PERCFG = 0x00;	//位置 1 P0 口     
    P0SEL = 0x3c;	//P0 用作串口, P0.2、P0.3、P0.4、P0.5作为片内外设I/O  
    /* UART0波特率设置,波特率:57600 */
    U0BAUD = 216;
    U0GCR = 10;
    /* USART模式选择 */
    U0CSR |= 0x80;     // UART模式
    U0UCR |= 0x80;     // 进行USART清除
    UTX0IF = 0;        // 清零UART0 TX中断标志
    EA = 1;            //使能全局中断
}

/**************************************************************
函数名称:UART0SendByte
功能:UART0发送一个字节
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void UART0SendByte(unsigned char c)
{
    U0DBUF = c;       // 将要发送的1字节数据写入U0DBUF(串口 0 收发缓冲器)  
    while (!UTX0IF);  // 等待TX中断标志,即U0DBUF就绪
    UTX0IF = 0;       // 清零TX中断标志 
}

/**************************************************************
函数名称:UART0SendString
功能:UART0发送一个字符串
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void UART0SendString(unsigned char *str)
{
    while(1)
    {
        if(*str == '\0') break;  // 遇到结束符,退出
        UART0SendByte(*str++);   // 发送一字节
    } 
}

/**************************************************************
函数名称:main
功能:程序主函数
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void main(void)
{
    SystemClockSourceSelect(XOSC_32MHz);
    initIO();  // IO端口初始化
    initUART0();  //初始化端口 
    /* 定义DMA源地址空间并初始化为将被DMA传输的字符串数据 */
    unsigned char srcStr[]="块传送数据:DMA transfer.";  
    /* 定义DMA目标地址空间 */
    unsigned char destStr[sizeof(srcStr)];
    
    /* 定义DMA配置数据结构体变量 */
    DMA_CONFIGURATIONPARAMETERS dmaCH;
    
    /* 设置DMA配置参数 */
    /* 源地址 */
    dmaCH.SRCADDRH = (unsigned char)(((unsigned short)(&srcStr)) >> 8);
    dmaCH.SRCADDRL = (unsigned char)(((unsigned short)(&srcStr)) & 0x00FF);
    /* 目标地址 */
    dmaCH.DESTADDRH = (unsigned char)(((unsigned short)(&destStr)) >> 8);
    dmaCH.DESTADDRL = (unsigned char)(((unsigned short)(&destStr)) & 0x00FF);  
    /* 可变长度模式选择 */
    dmaCH.VLEN = 0x00;      // 使用DMA传输长度
    /* 传输长度 */
    dmaCH.LENH = (unsigned char)(((unsigned short)(sizeof(srcStr))) >> 8);
    dmaCH.LENL = (unsigned char)(((unsigned short)(sizeof(srcStr))) & 0x00FF);  
    /* 字节/字模式选择 */
    dmaCH.WORDSIZE = 0x00;  // 字节传输
    /* 传输模式选择 */
    dmaCH.TMODE = 0x01;     // 块传输模式  
    /* 触发源选择 */
    dmaCH.TRIG = 0x00;      // 通过写DMAREQ来触发
    /* 源地址增量 */
    dmaCH.SRCINC = 0x01;    // 每次传输完成后源地址加1字节/字 
    /* 目标地址增量 */
    dmaCH.DESTINC = 0x01;   // 每次传输完成后目标地址加1字节/字  
    /* 中断使能 */
    dmaCH.IRQMASK = 0x00;   // 禁止DMA产生中断
    /* M8 */
    dmaCH.M8 = 0x00;        // 1个字节为8比特  
    /* 优先级设置 */
    dmaCH.PRIORITY = 0x02;  // 高级
    
    /* 使用DMA通道0 */
    DMA0CFGH = (unsigned char)(((unsigned short)(&dmaCH)) >> 8);
    DMA0CFGL = (unsigned char)(((unsigned short)(&dmaCH)) & 0x00FF); 
   while(1)
  {
    /***************给srcStr赋值**************/
    sprintf(srcStr,"块传送数据:DMA transfer.");  
    
    /* 在PC串口助手上显示DMA传输的源地址和目标地址 */
    unsigned char s[31];
    sprintf(s,"数据源地址: 0x%04X, ",(unsigned short)(&srcStr));  //格式化字符串   
    UART0SendString(s);   
   
    sprintf(s,"目标地址: 0x%04X;",(unsigned short)(&destStr));
    UART0SendString(s);
    memset(destStr, 0, sizeof(destStr));  // 清除DMA目标地址空间的内容
   
    UART0SendString("按SW1开始DMA传送...\r\n\r\n");  // 从UART0发送字符串
    
    /* 清除DMA中断标志 */
    DMAIRQ = 0x00;    
    
    /* 使DMA通道0进入工作状态 */
    DMAARM |= 0x01;  
    
    LED1=0;
    
    /* 等待用户按下任意键(除复位键外)*/
    while(SW1 == 1);
    
    if(SW1 == 0)	//低电平有效
        {     while(SW1 == 0); //等待用户松开按键              
               /* 触发DMA传输 */
               DMAREQ |= 0x01;
               LED1=1;
  
               /* 等待DMA传输完成 */
               while((DMAIRQ & 0x01) == 0);
  
              /* 验证DMA传输数据的正确性 */
              unsigned char i,errors = 0;
              for(i=0;i<sizeof(srcStr);i++)
                {
                    if(srcStr[i] != destStr[i]) errors++;     
                }
  
              /* 在PC串口助手上显示DMA传输结果 */
              if(errors)
               {
                  LED1 = 1;
                  UART0SendString("传输错误!\r\n\r\n\r\n");  // 从UART0发送字符串
               }
              else
                {
                  LED1 =0;
                  sprintf(s,"%s  传输成功!\r\n\r\n\r\n",destStr);  //格式化字符串
                  UART0SendString(s);  // 从UART0发送字符串
                }           
           } 
      }
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WW......

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值