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

最新更新时间:2022-10-09来源: csdn关键字: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 == '') 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传送...rnrn");  // 从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                {

                    if(srcStr[i] != destStr[i]) errors++;     

                }

[1] [2]
关键字:ZigBee  CC2530  单片机  DMA方式 编辑:什么鱼 引用地址:ZigBee-CC2530单片机 - DMA方式复制数据

上一篇:ZigBee-CC2530单片机 - 低功耗运行
下一篇:ZigBee-CC2530单片机 - 按键控制LED

推荐阅读

5V供电CAN器件和3.3V供电MCU之间的通讯连接
目前市场上最常用的CAN通讯接口器件大多都是采用5V供电,而大部分的MCU供电电压却从5V降低到了3.3V供电,这样就会造成5VCAN通讯接口器件和3.3VMCU进行通讯时的接口电平不一致问题,本文针对这种应用提出几种5V供电CAN器件和3.3V供电MCU之间的连接方式,并给出了川土微电子产品的具体应用案例。CAN器件概述和MCU之间的连接CAN器件和MCU之间是通过RXD和TXD进行连接的,MCU发送的数据到CAN器件TXD后,由CAN收发器转换成CAN的隐性和显性电平发送到CAN总线,在接收数据时,CAN总线上的隐性和显性电平通过CAN收发器转换成逻辑电平由RXD输出到MCU。以川土微电子的CA-IF1051S/HS为例,对于5
发表于 2023-01-19
5V供电CAN器件和3.3V供电<font color='red'>MCU</font>之间的通讯连接
用汇编语言做一个看门狗测试
用STC的MCU的IO方式控制74HC595驱动8位数码管。; 用户可以修改宏来选择时钟频率.; 显示效果为: 显示秒计数, 5秒后不喂狗, 等复位.Fosc_KHZ EQU 22118 ;22118KHZSTACK_POIRTER EQU 0D0H ; 堆栈开始地址DIS_DOT EQU 020HDIS_BLACK EQU 010HDIS_ EQU 011HAUXR DATA 08EHP4 DATA 0C0HP5 DATA 0C8HP0M1 DATA 0x93 ;P0M0 DATA 0x94 ;P1M1 DATA 0x91 ;P1M0 DATA 0x92 ;P2M1 DATA 0x95 ;P2M0 DATA 0x96 ;P3M1
发表于 2023-01-13
用AT89C51单片机显示倒计时程序
;可设定时间的倒计时定时器,可选择5/15/20/30/35/45/50分钟倒计时;倒计时时间由四位拨码开关的2/3/4位来控制,;第2位表示5分钟,第3位表示15分钟,第4位表示30分钟,;通过不同的组合可以产生5/15/20/30/35/45/50分钟倒计时;P1.0口的外接的发光二极管为状态LED,定时未开始时LED常亮,定时过程中LED闪烁;K1为开始按钮,K2为停止按钮适用STM8S/STM8L/STM8A N76E003 脱机编程器/烧录器/下载器/SP_00【包邮】m.tb.cn/h.UlXVKiOa_bit equ 20h ;数码管个位数存放内存位置b_bit equ 21h ;数码管十位数存放内存位置temp eq
发表于 2023-01-13
基于S3C2440芯片和单片机设计压装数据采集系统的设计
引言随着经济和社会的发展,我国的工业水平和信息技术水平也得到了飞速发展。其中工业中最为常见的零部件组装和装备压装监测设备也得到了不断的改进。压装的过程其实就是按规定的技术要求将零部件进行组培和连接,使之成为半成品或者成品的工艺过程。如图1所示,就是将两个零部件进行过盈无键组装配合,使之牢固结合在一起。工业中很多机械设备都是通过这种压装方式组合到一起的,包括火车轮对、轴承、汽车发动机、变速器、底盘等关键部件。压装的质量决定了以后产品的使用质量和人民的生命财产都息息相关。我们知道压装质量的评判标准,主要是根据压装过程中压力和位移的变化曲线来确定的。而压力位移曲线的获取这就需要由良好的运行稳定的数据采集系统来提供。基于此,本文提出一种基于
发表于 2023-01-13
基于S3C2440芯片和<font color='red'>单片机</font>设计压装<font color='red'>数据</font>采集系统的设计
八位单片机的程序优化12项注意事项
1、采用短变量一个提高代码效率的最基本的方式就是减小变量的长度。使用 C 编程时,我们都习惯于对循环控制变量使用 int 类型,这对 8 位的单片机来说是一种极大的浪费,你应该仔细考虑你所声明的变量值可能的范围,然后选择合适的变量类型,很明显,经常使用的变量应该是unsigned char,只占用一个字节。2、使用无符号类型为什么要使用无符号类型呢?原因是8051不支持符号运算,程序中也不要使用含有带符号变量的外部代码,除了根据变量长度来选择变量类型外,你还要考虑是否变量是否会用于负数的场合。如果你的程序中可以不需要负数那么把变量都定义成无符号类型的。3、避免使用浮点指针在 8 位操作系统上使用 32 位浮点数是得不偿失的。你可以这
发表于 2023-01-13
单片机程序该如何优化?
对程序进行优化,通常是指优化程序代码或程序执行速度。优化代码和优化速度实际上是一个予盾的统一。一般是优化了代码的尺寸,就会带来执行时间的增加;如果优化了程序的执行速度,通常会带来代码增加的副作用。很难鱼与熊掌兼得,只能在设计时掌握一个平衡点。一、程序结构的优化1、程序的书写结构虽然书写格式并不会影响生成的代码质量,但是在实际编写程序时还是应该尊循一定的书写规则,一个书写清晰、明了的程序,有利于以后的维护。在书写程序时,特别是对于While、for、do…while、if…else、switch…case 等语句或这些语句嵌套组合时,应采用“缩格”的书写形式。2、标识符程序中使用的用户标识符除要遵循标识符的命名规则以外,一般不要用代数
发表于 2023-01-13
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2023 EEWORLD.com.cn, Inc. All rights reserved