ZigBee入门-CC2530-实验(六)-DMA-串口通信代码

DMA俗称CPU的“好基友”,是最好的数据搬运工,在没有DMA时,任何数据的读写都要通过CPU,这样很浪费CPU的资源,使CPU的运行效率降低,当有DMA时,一些数据的搬移根本不用CPU去干预,比如:串口通信、ADC采集…大大节省了CPU的资源,使之变的更高效!~
接下来就是一个简单的DMA应用,使用DMA将字符串值通过串口传输至PC端,在串口调试助手中打印出来。

结合之前的串口通信实验,增加的DMA模块,DMA看起来是一大堆,让人望而却步,应用DMA其实就是这样的一个模板,对着手册多看多连,就对DMA不陌生啦~

/*话不多说,直接上代码~*/
#include <ioCC2530.h>

#define uint unsigned int
#define uchar unsigned char

/******************************************************** 
* IAR编译环境中位域字段默认取向采用小端模式,
* 配置结构体声明前使用#pragma bitfields=reversed取反向, 
* 声明结束后恢复IAR默认方式
********************************************************/
#pragma bitfields=reversed
typedef struct 
{
  uchar SRCADDRH;        // 源地址高8位
  uchar SRCADDRL;        // 源地址低8位
  uchar DESTADDRH;       // 目标地址高8位
  uchar DESTADDRL;       // 目标地址低8位
  uchar VLEN          :3;// 长度域模式选择
  uchar LENH          :5;// 传输长度高字节
  uchar LENL          :8;// 传输长度低字节
  uchar WORDSIZE      :1;// 字节或字传输
  uchar TMODE         :2;// 传输模式选择
  uchar TRIG          :5;// 触发事件选择
  uchar SRCINC        :2;// 源地址增量   :-1/0/1/2
  uchar DESTINC       :2;// 目的地址增量 :-1/0/1/2
  uchar IRQMASK       :1;// 中断屏蔽
  uchar M8            :1;// 7或8bit传输长度,仅在字节传输模式下适用 
  uchar PRIORITY      :2;// 优先级
}DMA_DESC;
#pragma bitfields = default

uchar a[]=" Hello zigbee ";
uchar string[]="IM A USART";

DMA_DESC dmaConfig;      //DMA配置参数 结构体变量

void Init_DMA();         //声明DMA初始化函数
void Init_Cfg_32M();     //声明32M时钟初始化函数
void Init_Uart0();       //声明串口0初始化函数
void UR0SendByte(unsigned char Byte);  //声明发送一个字节初始化函数
void UR0SendString(unsigned char *str);//声明发送字符串初始化函数

void main()
{
  Init_DMA();
  Init_Cfg_32M();
  Init_Uart0();
  
  while(1)
  {
    UR0SendString(string);
        
    DMAARM=0x80;              //停止DMA所有通道进行传输
    DMAARM=0x01;              //启用DMA通道0进行传输                    
    DMAIRQ=0x00;              //清中断标志    
    DMAREQ=0x01;              //DMA通道0传送请求
    
    while(!(DMAIRQ&0x01));    //等待传输结束
  } 
}
/*=======================DMA初始化函数============================*/
void Init_DMA()
{
  /*配置源地址*/    
  dmaConfig.SRCADDRH=(uchar)((uint)&a >> 8);    
  dmaConfig.SRCADDRL=(uchar)((uint)&a & 0x00ff );
  //&0X00FF 防止警告 变量赋值超出了变量类型的最大值

  /*配置目的地址*/      
  dmaConfig.DESTADDRH=(uchar)((uint)&X_U0DBUF >> 8);    
  dmaConfig.DESTADDRL=(uchar)((uint)&X_U0DBUF); 
  
  /*选择LEN作为传送长度*/
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  /*设置传输长度*/
  dmaConfig.LENH=(uchar)((uint)sizeof(a) >> 8);  
  dmaConfig.LENL=(uchar)((uint)sizeof(a));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=15;           //USART0发送触发
  
  dmaConfig.SRCINC=0x01;       //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //清除DMA中断
    
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  
  /*将配置结构体的首地址赋予相关SFR*/
  DMA0CFGH=(uchar)((uint)&dmaConfig >> 8);   
  DMA0CFGL=(uchar)((uint)&dmaConfig & 0x00ff);
  
  asm("nop");  
}
/*=======================串口0发送一个字节函数=======================*/
void UR0SendByte(unsigned char Byte)
{
  U0DBUF = Byte;        //将要发送的一个字节数据写入U0DBUF
  while(!UTX0IF);       //等待TX中断标志,即数据发送完成
  UTX0IF = 0;           //清除TX中断标志,准备下一次发送
}
/*=======================串口0发送字符串函数=========================*/
void UR0SendString(unsigned char *str)
{
  while(*str != '\0')     
  {
    UR0SendByte(*str++);  //逐个发送字符串中的字节
  }
}
/*=======================32M晶振初始化函数==========================*/
void Init_Cfg_32M()
{
  CLKCONCMD &= ~0x40;       //系统时钟源选择:外部32MHz 。
  while(!(SLEEPSTA & 0x40));//等待晶振稳定
  CLKCONCMD &= ~0x47;       //128分频 CLKSPD不发分频
  SLEEPCMD |= 0x04;         //关闭不用的RC振荡器
}
/*=======================串口0初始化函数============================*/
void Init_Uart0()
{
  PERCFG = 0X00;        //外设控制寄存器USART 0 的IO位置:
  P0SEL  = 0X0C;        //设置P0_2,P_3为外设功能
  P2DIR &=~0XC0;        //设置P0口优先为UART0,即串口0优先级最高
  
  U0CSR |= 0XC0;        //设置为UART模式
  
  U0GCR |= 10;          //查表
  U0BAUD|= 216;         //设置波特率为57600
  
  U0UCR |= 0x80;        //无流控,8位数据位,清空缓冲区
  
  UTX0IF = 0;           //串口0TX发送中断标志位清0
  URX0IF = 0;           //串口0RX接收中断标志位清0
  
  URX0IE = 1;           //开串口0接收中断
  EA = 1;               //开总中断
}
如果大家觉得实验中一些寄存器的配置不是很明白,大家就拿出咱们吃饭的家伙CC2530的数据手册来把实验中出现的寄存器在手册中查找,去理解,数据手册网上多的是。

啃骨头,要好好啃,使劲啃,啃到底,才能啃到精髓嘛~~

我会每天更新一篇ZigBee入门-CC2530-的基础实验,让大家学习Zigbee技术不在是从入门到“入土”,而是从入门到巅峰~!!!
欢迎大家的留言和评论我会在看到的第一时间内答复。
看完后感觉得到帮助的小伙伴,要点点赞哦~
给笔者一些动力嘛!谢谢啦~
原创文章 13 获赞 10 访问量 546

猜你喜欢

转载自blog.csdn.net/weixin_45636395/article/details/105850243