CC2530使用DMA直接将RFD接收到的数据传送至U0DBUF,但是每次只能收到两个字节,不知道怎么回事,求大神看看。
*****************************************/
#include <ioCC2530.h>
#include "string.h"
#include <stdio.h>
#define uint8 unsigned char
#define uint16 unsigned int
/******************************************************************/
#define LED1 P1_0
#define LED2 P1_1
char rf_rx_buf[128];
extern int i=0;
static uint8 rf_rx_len;
void rf_init()
{
FRMFILT0 = 0x0C; // 静止接收过滤,即接收所有数据包
TXPOWER = 0xb5; // 发射功率为1dBm
FREQCTRL = 0x0B; // 选择通道11
CCACTRL0 = 0xF8; // 推荐值 smartRF软件生成
FSCAL1 = 0x00;
TXFILTCFG = 0x09;
AGCCTRL1 = 0x15;
AGCCTRL2 = 0xFE;
TXFILTCFG = 0x09;
RFIRQM0 |= (1<<6); // 使能RF数据包接收中断
IEN2 |= (1<<0); // 使能RF中断
MDMTEST1&= 0xff;
RFST = 0xED; // 清除RF接收缓冲区 ISFLUSHRX
RFST = 0xE3; // RF接收使能 ISRXON
}
/******************************************************************/
#pragma bitfields=reversed
typedef struct {
uint8 SRCADDRH; //源地址高字节
uint8 SRCADDRL; //源地址低字节
uint8 DESTADDRH; //目的地址高字节
uint8 DESTADDRL; //目的地址低字节
uint8 VLEN :3; //变长传输模式
uint8 LENH :5; //传输长度高字节
uint8 LENL :8; //传输长度低字节
uint8 WORDSIZE :1; //字节传输或字传输
uint8 TMODE :2; //传输模式
uint8 TRIG :5; //触发时间选择
uint8 SRCINC :2; //源地址增量方式选择
uint8 DESTINC :2; //目的地址增量方式选择
uint8 IRQMASK :1; //中断屏蔽位
uint8 M8 :1; //字节传输模式时用,8或7bit传输,仅仅适合在字节传输模式下
uint8 PRIORITY :2; //优先级选择
}DMA_DESC;
#pragma bitfields=default
DMA_DESC dmaConfig0;
DMA_DESC dmaConfig1;
#define DATA_AMOUNT 10
/*****************************************************
* CC2530数据手册中对DMA数据结构的介绍,对以下常量赋值
****************************************************/
#define DMA_VLEN_USE_LEN 0x00 // Use LEN for transfer count
#define DMA_WORDSIZE_BYTE 0x00 // Transfer a byte at a time
#define DMA_WORDSIZE_WORD 0x01 // Transfer a 16-bit word at a time
#define DMA_TMODE_SINGLE 0x00 // Transfer a single byte/word after each DMA trigger 单个传输模式
#define DMA_TMODE_BLOCK 0x01 // Transfer block of data (length len) after each DMA trigger 块传输模式
#define DMA_TMODE_SINGLE_REPEATED 0x02 // Transfer single byte/word (after len transfers, rearm DMA) 重复单个传输模式
#define DMA_TMODE_BLOCK_REPEATED 0x03 // Transfer block of data (after len transfers, rearm DMA) 重复块传输模式
#define DMA_TRIG_NONE 0 // No trigger, setting DMAREQ.DMAREQx bit starts transfer 无触发
#define DMA_SRCINC_0 0x00 // Increment source pointer by 0 bytes/words after each transfer源地址递增0字节/字
#define DMA_SRCINC_1 0x01 // Increment source pointer by 1 bytes/words after each transfer源地址递增1字节/字
#define DMA_DESTINC_1 0x01 // Increment destination pointer by 1 bytes/words after each transfer目标地址递增1字节/字
#define DMA_DESTINC_0 0x00 // Increment destination pointer by 1 bytes/words after each transfer目标地址递增0字节/字
#define DMA_IRQMASK_DISABLE 0x00 // Disable interrupt generation 通道的中断屏蔽
#define DMA_IRQMASK_ENABLE 0x01 // Enable interrupt generation upon DMA channel done 通道的中断使能
#define DMA_M8_USE_8_BITS 0x00 // Use all 8 bits for transfer count 采用所有8位作为传输长度
#define DMA_M8_USE_7_BITS 0x01 // Use 7 LSB for transfer count 采用字节地7位作为传输长度
#define DMA_PRI_LOW 0x00 // Low, CPU has priority 低优先级,CPU优先
#define DMA_PRI_GUARANTEED 0x01 // Guaranteed, DMA at least every second try 保证级,DMA至少在每秒一次的尝试中优先
#define DMA_PRI_HIGH 0x02 // High, DMA has priority 高优先级,DMA优先
#define DMA_PRI_ABSOLUTE 0x03 // Highest, DMA has priority. Reserved for DMA port access.
#define DMAARM_DMAARM0 0x01
#define DMAARM_DMAARM1 0x02
#define DMAREQ_DMAREQ0 0x01
#define DMAREQ_DMAREQ1 0x02
#define DMAIRQ_DMAIF0 0x01
#define DMAIRQ_DMAIF1 0x02
#define NOP() asm("NOP")
char data[DATA_AMOUNT];
char copy[DATA_AMOUNT];
//数据长度
void clock_init()
{
SLEEPCMD &= ~0x04; // 设置系统时钟为32MHz
while( !(SLEEPSTA & 0x40) );
CLKCONCMD &= ~0x47;
SLEEPCMD |= 0x04;
}
void UartInit(void)
{
EA=0;
PERCFG = 0x00;
P0SEL = 0x0c;
P2DIR &= ~0xc0;
P1DIR |= ( 1<< 0) | (1<<1 ); // P1.0 输出
U0CSR |= 0xc0;
U0GCR |= 11;
U0BAUD |= 216;
UTX0IF = 1;
URX0IE= 1;
EA=1;
}
void UartSendString(char *Data, uint16 len)
{
uint16 j;
for (j = 0; j < len; j++)
{
U0DBUF = *Data++;
for (; 0 == UTX0IF;);
UTX0IF = 0;
}
}
void Delay_ms(uint16 ms)
{
uint16 i,j;
for(i = 0; i < ms; i++)
{
for(j = 0;j < 1774; j++);
}
}
void rx_init()
{
dmaConfig0.SRCADDRH = 0X70; //获取到data地址(源地址)的高8位地址
dmaConfig0.SRCADDRL = 0XC1; //获取到data地址(源地址)的低8位地址
dmaConfig0.VLEN = DMA_VLEN_USE_LEN; //设置可变长度为0
dmaConfig0.WORDSIZE = DMA_WORDSIZE_BYTE; //设置为字节传输模式,赋值0
dmaConfig0.TMODE = DMA_TMODE_SINGLE;
dmaConfig0.TRIG = 14; //USART 0接收完成
dmaConfig0.SRCINC = DMA_SRCINC_0; //源地址1个字节/字递增
dmaConfig0.DESTINC = DMA_DESTINC_1; //目的地址1个字节/字递增
dmaConfig0.IRQMASK = DMA_IRQMASK_DISABLE; //通道的中断屏蔽
dmaConfig0.M8 = DMA_M8_USE_8_BITS; //采用所有8位作为传输长度
dmaConfig0.PRIORITY = DMA_PRI_HIGH; //高优先级,DMA优先
}
void tx_init()
{
dmaConfig1.DESTADDRH = 0x70; //获取到copy地址(目的地址)的高8位地址
dmaConfig1.DESTADDRL = 0xc1; //获取到copy地址(目的地址)的低8位地址
dmaConfig1.VLEN = DMA_VLEN_USE_LEN; //设置可变长度为0
dmaConfig1.WORDSIZE = DMA_WORDSIZE_BYTE; //设置为字节传输模式,赋值0
dmaConfig1.TMODE = DMA_TMODE_BLOCK; //块传输模式
// dmaConfig1.TMODE = DMA_TMODE_SINGLE;
dmaConfig1.TRIG = 0; //RFD接收完成
dmaConfig1.SRCINC = DMA_SRCINC_0; //源地址1个字节/字递增
dmaConfig1.DESTINC = DMA_DESTINC_0; //目的地址1个字节/字递增
dmaConfig1.IRQMASK = DMA_IRQMASK_DISABLE; //通道的中断屏蔽
dmaConfig1.M8 = DMA_M8_USE_8_BITS; //采用所有8位作为传输长度
dmaConfig1.PRIORITY = DMA_PRI_HIGH; //高优先级,DMA优先
}
void tx()
{
dmaConfig1.SRCADDRH = 0X70; //获取到data地址(源地址)的高8位地址
dmaConfig1.SRCADDRL = 0XD9; //获取到data地址(源地址)的低8位地址
dmaConfig1.LENH = 0X00; //获取传输长度的高5位
//dmaConfig1.LENL = rf_rx_len; //获取传输长度的低8位
dmaConfig1.LENL = 3;
DMA1CFGH = ((uint16)&dmaConfig1 >> 8) & 0x00FF; //DMA通道1配置地址高8位地址
DMA1CFGL = ((uint16)&dmaConfig1) & 0x00FF; //DMA通道1配置地址低8位地址
/*DMA进入工作模式通道1*/
DMAARM |= DMAARM_DMAARM1;//为了任何DMA传输能够在该通道上发生,该位必须置1,对于非重复传输模式,一旦完成传送,该位自动清0
/*一个通道准备工作(即获得配置数据)的时间需要9个系统时钟*/
/*清除中断标志*/
// DMAIRQ =0x00;
NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP(); // 9 NOPs
/*DMA通道0传送请求,即触发DMA传送*/
DMAREQ |= DMAREQ_DMAREQ1;//设置为1,激活DMA通道1(与一个触发事件具有相同的效果),当DMA传输开始清除该位
/*等待DMA通道0传送完毕*/
for (; !(DMAIRQ & DMAIRQ_DMAIF1););//当DMA通道1传送完成,DMAIRQ:DMAIF0位置1,与上DMAIRQ_DMAIF0(0x01),取非后为0退出循环
}
void main(void)
{ LED1 = 0; LED2 = 0;
rx_init();
tx_init();
clock_init();
rf_init();
UartInit();
while(1)
{
}
}
#pragma vector=RF_VECTOR
__interrupt void rf_isr(void)
{
// LED1 ^= 1; // LED1翻转 提示作用
// 接收到一个完整的数据包
if (RFIRQF0 & ( 1<<6 ))
{
LED1 ^= 1;
rf_rx_len = RFD - 2; // 长度去除两字节附加结果
tx();
RFST = 0xED;
S1CON = 0; // 清除RF中断标志
RFIRQF0 &= ~(1<<6); // 清除RF接收完成数据包中断
}
}
|
|