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发送字符串
}
}
}
}