结构:
AppDemo /* 读写器及标签应用功能实现 */
的2.4G读写器应用程序
的2.4G标签应用程序
READER /* 读写器及标签硬件驱动 */
的2.4G读写器硬件层驱动
的2.4G标签硬件层驱动
SYSCLK /* 系统时钟 */
时钟选择
UART0 /* 串口通讯UART0驱动 */
的UART0驱动
/*******************************************************************************
* 文件名称:RFID_2.4GHz_Reader_Demo.c
* 功 能:RFID基础实验工程 --- 2.4GHz RFID 读卡器演示
* 将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
* 作 者:
* 公 司:
******************************************************************************/
#if !defined ( TAG_FLAG )
/* 包含头文件 */
/*************************************************************/
#include "hal_2.4GHz_Reader.h" // RFID-2.4GHz-Reader硬件抽象层头文件
#include "UART0.h" // CC2530的UART0驱动的头文件
#include "SYSCLK.h" // CC2530的时钟选择头文件
#include "stdlib.h" // C语言标准库文件
#include "stdio.h" // C语言标准输入/输出库文件
/*************************************************************/
/* RFID Reader的数据管道0接收地址为"READR" */
/*************************************************************/
unsigned char RFID_READER_ADDR_P0[] = {'R', 'D', 'A', 'E', 'R'};
/*************************************************************/
/* XXTEA加密块数量 */
/*************************************************************/
#define TEA_ENCRYPTION_BLOCK_COUNT 4
/*************************************************************/
/* XXTEA密钥 */
/*************************************************************/
const long XXTEA_KEY[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
/*************************************************************/
/* XXTEA算法相关变量和宏定义 */
/*************************************************************/
unsigned long z, y, sum, tmp, mx;
unsigned char e;
#define TEA_ROUNDS_COUNT (6+52/4)
#define MX ((((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(XXTEA_KEY[(p&3)^e]^z)))
#define DELTA 0x9E3779B9
/*************************************************************/
/* 数据包结构体类型 */
/*************************************************************/
typedef struct
{
unsigned char len; // 数据包的长度字段(单位:字节)
unsigned char protocol; // 数据包的协议类型字段
unsigned char flags; // 数据包的标志字段(按下Tag上的按键,flag为0x02;否则为0x00)
unsigned char txpower; // 数据包的发送功率字段
unsigned long seq; // 数据包的序号字段
unsigned long oid; // 数据包的对象标识符字段
unsigned short reserved; // 数据包的保留字段
unsigned short crc; // 数据包的CRC字段
}PKT;
/*************************************************************/
/* 加密数据包结构体类型 */
/*************************************************************/
typedef union
{
PKT pkt;
unsigned long dataUL[TEA_ENCRYPTION_BLOCK_COUNT];
unsigned char dataB[TEA_ENCRYPTION_BLOCK_COUNT * sizeof (unsigned long)];
}ENCRYPTED_PKT;
/*************************************************************/
/* 用于Tag的加密数据包结构体变量 */
/*************************************************************/
static ENCRYPTED_PKT g_Tag;
/*************************************************************/
/* "打乱"功能宏 — SHUFFLE */
/*************************************************************/
#define SHUFFLE(a,b) tmp = g_Tag.dataB[a];\
g_Tag.dataB[a] = g_Tag.dataB[b];\
g_Tag.dataB[b] = tmp;
/*************************************************************/
/*********************************************************************
* 函数名称:htonl
* 功 能:将主机字节顺序表达的32位无符号长整形数转换成网络字节顺序
* 表达的32位无符号长整形数
* 入口参数:hostlong 主机字节顺序表达的32位无符号长整形数
* 出口参数:无
* 返 回 值:网络字节顺序表达的32位无符号长整形数
********************************************************************/
static unsigned long htonl (unsigned long hostlong)
{
unsigned long res;
((unsigned char *) &res)[0] = ((unsigned char *) &hostlong)[3];
((unsigned char *) &res)[1] = ((unsigned char *) &hostlong)[2];
((unsigned char *) &res)[2] = ((unsigned char *) &hostlong)[1];
((unsigned char *) &res)[3] = ((unsigned char *) &hostlong)[0];
return res;
}
/*********************************************************************
* 函数名称:htons
* 功 能:将主机字节顺序表达的16位无符号短整形数转换成网络字节顺序
* 表达的16位无符号短整形数
* 入口参数:hostlong 主机字节顺序表达的16位无符号短整形数
* 出口参数:无
* 返 回 值:网络字节顺序表达的16位无符号短整形数
********************************************************************/
static unsigned short htons (unsigned short hostshort)
{
unsigned short res;
((unsigned char *) &res)[0] = ((unsigned char *) &hostshort)[1];
((unsigned char *) &res)[1] = ((unsigned char *) &hostshort)[0];
return res;
}
/*********************************************************************
* 函数名称:Shuffle_TX_ByteOrder
* 功 能:"打乱"待发送数据的字节顺序
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
static void Shuffle_TX_ByteOrder (void)
{
unsigned char tmp;
SHUFFLE (0 + 0, 3 + 0);
SHUFFLE (1 + 0, 2 + 0);
SHUFFLE (0 + 4, 3 + 4);
SHUFFLE (1 + 4, 2 + 4);
SHUFFLE (0 + 8, 3 + 8);
SHUFFLE (1 + 8, 2 + 8);
SHUFFLE (0 + 12, 3 + 12);
SHUFFLE (1 + 12, 2 + 12);
}
/*********************************************************************
* 函数名称:CRC16
* 功 能:CRC16计算
* 入口参数:buffer 指向存储待进行CRC16计算的数据的缓冲区的指针
* size 待进行CRC16计算的数据的长度
* 出口参数:无
* 返 回 值:CRC16计算结果
* 注 意:CC2530自身带有CRC计算功能,但为了提高代码的可移植性,我们
* 不使用CC2530自身带有的CRC计算功能,而使用该函数。
********************************************************************/
static unsigned short CRC16 (const unsigned char *buffer, unsigned char size)
{
unsigned short crc = 0xFFFF;
if(buffer)
{
while(size--)
{
crc = (crc >> 8) | (crc << 8);
crc ^= *buffer++;
crc ^= ((unsigned char) crc) >> 4;
crc ^= crc << 12;
crc ^= (crc & 0xFF) << 5;
}
}
return crc;
}
/*********************************************************************
* 函数名称:MX_Update
* 功 能:XXTEA算法的MX更新
* 入口参数:p
* 出口参数:无
* 返 回 值:无
********************************************************************/
static void MX_Update (unsigned char p)
{
mx = MX;
}
/*********************************************************************
* 函数名称:MX_Decode
* 功 能:XXTEA算法的MX解码
* 入口参数:p
* 出口参数:无
* 返 回 值:无
********************************************************************/
static void MX_Decode (unsigned char p)
{
MX_Update (p);
y = tmp - mx;
}
/*********************************************************************
* 函数名称:MX_Decode
* 功 能:XXTEA解码
* 入口参数:p
* 出口参数:无
* 返 回 值:无
********************************************************************/
void XXTEA_Decode (void)
{
y = g_Tag.dataUL[0];
sum = DELTA * TEA_ROUNDS_COUNT;
while (sum != 0)
{
e = sum >> 2 & 3;
z = g_Tag.dataUL[2];
tmp = g_Tag.dataUL[3];
MX_Decode (3);
g_Tag.dataUL[3] = y;
z = g_Tag.dataUL[1];
tmp = g_Tag.dataUL[2];
MX_Decode (2);
g_Tag.dataUL[2] = y;
z = g_Tag.dataUL[0];
tmp = g_Tag.dataUL[1];
MX_Decode (1);
g_Tag.dataUL[1] = y;
z = g_Tag.dataUL[3];
tmp = g_Tag.dataUL[0];
MX_Decode (0);
g_Tag.dataUL[0] = y;
sum -= DELTA;
}
}
void changeToAscii (unsigned char *pUString, unsigned char teData)
{
unsigned char temp8i;
temp8i = teData >> 4;
if ( temp8i < 0x0a)
*pUString = temp8i + 0x30;
else
*pUString = temp8i + 0x37;
pUString++;
temp8i = teData & 0x0f;
if ( temp8i < 0x0a)
*pUString = temp8i + 0x30;
else
*pUString = temp8i + 0x37;
}
/*********************************************************************
* 函数名称:InitNRF4Reader
* 功 能:针对RFID Reader功能初始化nRF24L01+
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void InitNRF4Reader(void)
{
hal_nrf_nop();
hal_nrf_write_reg(CONFIG, 0x00);
hal_nrf_write_reg(EN_AA, 0x00);
hal_nrf_write_reg(SETUP_AW, 0x03);
hal_nrf_set_address(HAL_NRF_PIPE0, RFID_READER_ADDR_P0);
hal_nrf_write_reg(EN_RXADDR, 0x01);
hal_nrf_write_reg(RX_PW_P0, 16);
hal_nrf_write_reg(RF_CH, 81);
hal_nrf_write_reg(STATUS, 0x70);
hal_nrf_write_reg(CONFIG, 0x01);
}
/*********************************************************************
* 函数名称:calcFCS
* 功 能:该函数用来验证GPS数据FCS校验和。
* 入口参数:pBuf 指向被校验的数据
* len 数据长度
* 出口参数:无
* 返 回 值:无
********************************************************************/
unsigned char calcFCS(unsigned char *pBuf, unsigned char len)
{
unsigned char rtrn = 0;
while (len--)
{
rtrn ^= *pBuf++;
}
return rtrn;
}
/*********************************************************************
* 函数名称:main
* 功 能:2.4GHz RFID 读卡器演示
* 将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
int main(void)
{
/* 定义相关变量 */
unsigned char i;
unsigned short crc;
unsigned long oid;
unsigned char uartString[64];
/* 选择32MHz晶体振荡器作为系统时钟源(主时钟源) */
SystemClockSourceSelect(XOSC_32MHz);
/* RFID-2.4GHz-Reader硬件抽象层初始化 */
hal_2G4Hz_Reader_Init();
/* UART0初始化 */
InitUART0();
/* LED1和LED2闪烁指定次数 */
for(i = 0; i <= 20; i++)
{
if(i & 1)
{
HAL_2G4Hz_LED1_TURN_ON();
HAL_2G4Hz_LED2_TURN_ON();
}
else
{
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED2_TURN_OFF();
}
CC2530SleepTimer_Delay(100);
}
/* 针对RFID Reader功能初始化nRF24L01+ */
InitNRF4Reader();
/* 永久循环 */
while(1)
{
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
HAL_2G4Hz_CE = 1;
SetCC2530PowerMode(2);
/* 点亮LED1 */
HAL_2G4Hz_LED1_TURN_ON();
/* 读取接收到的数据 */
for(i = 0; i < 16; i++)
{
g_Tag.dataB[i] = Radio_Get_Pload_Byte(i);
}
/* 解码接收到的数据 */
Shuffle_TX_ByteOrder();
XXTEA_Decode();
Shuffle_TX_ByteOrder();
/* 校验接收到的数据 */
crc = CRC16(g_Tag.dataB, sizeof(g_Tag.pkt) - sizeof (g_Tag.pkt.crc));
/* 接收到的g_Tag数据包CRC16校验错误 */
if(htons(g_Tag.pkt.crc) != crc)
{
/* 用户自行处理 */
}
/* 接收到的g_Tag数据包CRC16校验正确 */
else
{ /* 点亮LED2 */
HAL_2G4Hz_LED2_TURN_ON();
/* 从CC2530的UART0输出接收到来自Tag的信息 */
oid = htonl(g_Tag.pkt.oid);
// sprintf(uartString,"OID:%08lx\nTX power:%d\nButton push:%d\n\n", oid, g_Tag.pkt.txpower, g_Tag.pkt.flags);
uartString[0] = 0x5a;
uartString[1] = 14;
uartString[2] = 0;//g_Tag.dataB[7];
uartString[3] = 0x01;
uartString[4] = 0x0a;
changeToAscii (&uartString[5], g_Tag.dataB[8]);
changeToAscii (&uartString[7], g_Tag.dataB[9]);
changeToAscii (&uartString[9], g_Tag.dataB[10]);
changeToAscii (&uartString[11], g_Tag.dataB[11]);
uartString[13] = g_Tag.dataB[2];
uartString[14] = calcFCS(&uartString[1], 13);
uartString[15] = 0xa5;
uartString[16] = 0;
UART0SendString((unsigned char *)uartString, 16);
}
/* 设置nrf24L01+的RF为IDLE */
Radio_Set_Status(RF_IDLE);
/* 熄灭LED1和LED2 */
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED2_TURN_OFF();
}
}
#endif
/*******************************************************************************
* 文件名称:RFID_2.4GHz_Tag_Demo.c
* 功 能:RFID基础实验工程 --- 2.4GHz RFID 的Tag
* 作 者:
* 公 司:
******************************************************************************/
#if defined ( TAG_FLAG )
/* 包含头文件 */
/*************************************************************/
#include "hal_2.4GHz_Tag.h" // RFID-2.4GHz-Tag硬件抽象层头文件
#include "SYSCLK.h" // CC2530的时钟选择头文件
#include "stdlib.h" // C语言标准库文件
#include "stdio.h" // C语言标准输入/输出库文件
/*************************************************************/
unsigned char keyFlag;
unsigned int txNumber;
/* RFID Reader的数据管道0接收地址为"READR" */
/*************************************************************/
unsigned char RFID_READER_ADDR_P0[] = {'R', 'D', 'A', 'E', 'R'};
/*************************************************************/
/* XXTEA加密块数量 */
/*************************************************************/
#define TEA_ENCRYPTION_BLOCK_COUNT 4
/*************************************************************/
#define DATA_LONG 0x10
#define DATA_PROTOCOL 0x01
/* XXTEA密钥 */
/*************************************************************/
const long XXTEA_KEY[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
/*************************************************************/
/* XXTEA算法相关变量和宏定义 */
/*************************************************************/
unsigned long z, y, sum, tmp, mx;
unsigned char e;
#define TEA_ROUNDS_COUNT (6+52/4)
#define MX ((((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(XXTEA_KEY[(p&3)^e]^z)))
#define DELTA 0x9E3779B9
/*************************************************************/
#define KEYDELAY 80
/* 数据包结构体类型 */
/*************************************************************/
typedef struct
{
unsigned char len; // 数据包的长度字段(单位:字节)
unsigned char protocol; // 数据包的协议类型字段
unsigned char flags; // 数据包的标志字段(按下Tag上的按键,flag为0x02;否则为0x00)
unsigned char txpower; // 数据包的发送功率字段
unsigned long seq; // 数据包的序号字段
unsigned long oid; // 数据包的对象标识符字段
unsigned short reserved; // 数据包的保留字段
unsigned short crc; // 数据包的CRC字段
}PKT;
/*************************************************************/
/* 加密数据包结构体类型 */
/*************************************************************/
typedef union
{
PKT pkt;
unsigned long dataUL[TEA_ENCRYPTION_BLOCK_COUNT];
unsigned char dataB[TEA_ENCRYPTION_BLOCK_COUNT * sizeof (unsigned long)];
}ENCRYPTED_PKT;
/*************************************************************/
/* 用于Tag的加密数据包结构体变量 */
/*************************************************************/
static ENCRYPTED_PKT g_Tag;
/*************************************************************/
/* "打乱"功能宏 — SHUFFLE */
/*************************************************************/
#define SHUFFLE(a,b) tmp = g_Tag.dataB[a];\
g_Tag.dataB[a] = g_Tag.dataB[b];\
g_Tag.dataB[b] = tmp;
/*************************************************************/
/*********************************************************************
* 函数名称:Shuffle_TX_ByteOrder
* 功 能:"打乱"待发送数据的字节顺序
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
static void Shuffle_TX_ByteOrder (void)
{
unsigned char tmp;
SHUFFLE (0 + 0, 3 + 0);
SHUFFLE (1 + 0, 2 + 0);
SHUFFLE (0 + 4, 3 + 4);
SHUFFLE (1 + 4, 2 + 4);
SHUFFLE (0 + 8, 3 + 8);
SHUFFLE (1 + 8, 2 + 8);
SHUFFLE (0 + 12, 3 + 12);
SHUFFLE (1 + 12, 2 + 12);
}
/*********************************************************************
* 函数名称:CRC16
* 功 能:CRC16计算
* 入口参数:buffer 指向存储待进行CRC16计算的数据的缓冲区的指针
* size 待进行CRC16计算的数据的长度
* 出口参数:无
* 返 回 值:CRC16计算结果
* 注 意:CC2530自身带有CRC计算功能,但为了提高代码的可移植性,我们
* 不使用CC2530自身带有的CRC计算功能,而使用该函数。
********************************************************************/
static unsigned short CRC16 (const unsigned char *buffer, unsigned char size)
{
unsigned short crc = 0xFFFF;
if(buffer)
{
while(size--)
{
crc = (crc >> 8) | (crc << 8);
crc ^= *buffer++;
crc ^= ((unsigned char) crc) >> 4;
crc ^= crc << 12;
crc ^= (crc & 0xFF) << 5;
}
}
return crc;
}
/*********************************************************************
* 函数名称:XXTEA_Encode
* 功 能:XXTEA编码
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void XXTEA_Encode (void)
{
long n = 4;
long p, q ;
z=g_Tag.dataUL[n-1], y=g_Tag.dataUL[0], sum=0;
q = 6 + 52/n;
while (q-- > 0)
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
y = g_Tag.dataUL[p+1], z = g_Tag.dataUL[p] += MX;
y = g_Tag.dataUL[0];
z = g_Tag.dataUL[n-1] += MX;
}
}
/*********************************************************************
* 函数名称:InitNRF4Reader
* 功 能:针对RFID Reader功能初始化nRF24L01+
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void InitNRF4Reader(void)
{
hal_nrf_nop();
hal_nrf_write_reg(CONFIG, 0x20); //使用与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 相同的CRC 配置
//设置PRIM_RX 位为0
hal_nrf_write_reg(EN_AA, 0x00);
hal_nrf_write_reg(SETUP_RETR, 0); //设置自动重发计数器为0 禁止自动重发功能
hal_nrf_write_reg(SETUP_AW, 0x03);//与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 使用相同的地址宽度
hal_nrf_set_address(HAL_NRF_PIPE0, RFID_READER_ADDR_P0);
hal_nrf_set_address(HAL_NRF_TX, RFID_READER_ADDR_P0);
hal_nrf_write_reg(RF_CH, 81); //与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 使用相同的频道
hal_nrf_write_reg(EN_RXADDR, 0x00);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);//设置PWR_UP 为高
}
void delay65ms(unsigned int microSecs)
{
while(microSecs--)
{
/* 32 NOPs == 1 usecs */
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop");
}
}
void keyScan ()
{
unsigned char keyCount,temp8i;
keyCount = 0;
temp8i = 0;
while ( temp8i < KEYDELAY )
{
delay65ms(500);
if ( P2_0 == 1 )
keyCount++;
else
keyCount = 0;
temp8i++;
}
if ( keyCount >= KEYDELAY)
keyFlag = 0x31;
else
keyFlag = 0x30;
}
unsigned char secondAddr[8];
void HalFlashRead()
{
// Calculate the offset into the containing flash bank as it gets mapped into XDATA.
unsigned char memctr = MEMCTR; // Save to restore.
unsigned char i;
// Calculate and map the containing flash bank into XDATA.
MEMCTR = (MEMCTR & 0xF8) | 7;
asm("push DPH");
asm("push DPL");
asm("push A");
asm("push B");
asm("mov DPH,#0xff");
asm("mov DPL,#0xe8");
i = 0;
while (i < 8)
{
asm("movx A,@DPTR");
asm("mov B,A");
secondAddr[i] = B;
asm("inc DPTR");
i++;
}
asm("pop B");
asm("pop A");
asm("pop DPL");
asm("pop DPH");
MEMCTR = memctr;
}
/*********************************************************************
* 函数名称:main
* 功 能:2.4GHz RFID 读卡器演示
* 将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
int main(void)
{
/* 定义相关变量 */
unsigned char i;
unsigned short crc;
/* 选择32MHz晶体振荡器作为系统时钟源(主时钟源) */
SystemClockSourceSelect(XOSC_32MHz);
/* RFID-2.4GHz-Reader硬件抽象层初始化 */
hal_2G4Hz_Tag_Init();
/* 使能P2.0为通用I/O,且为输入 */
P2SEL = P2SEL & 0xfe;
P2DIR = P2DIR & 0xfe;
/* P2.0为下拉模式 */
P2INP = P2INP & 0xfe;
P2INP = P2INP | 0x80;
/* LED1和LED2闪烁指定次数 */
for(i = 0; i <= 20; i++)
{
if(i & 1)
{
HAL_2G4Hz_LED1_TURN_ON();
HAL_2G4Hz_LED2_TURN_ON();
}
else
{
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED2_TURN_OFF();
}
CC2530SleepTimer_Delay(100);
}
/* 针对RFID Tag功能初始化nRF24L01+ */
InitNRF4Reader();
do
{
HalFlashRead ();
delay65ms(60000);
P1_1 = !P1_1;
}while ( (secondAddr[0] == 0xff) && (secondAddr[1] == 0xff) && (secondAddr[2] == 0xff) && (secondAddr[3] == 0xff) );
P1_1 = 0;
/* 永久循环 */
while(1)
{
g_Tag.dataB[0] = DATA_LONG;
g_Tag.dataB[1] = DATA_PROTOCOL;
g_Tag.dataB[4] = 0x00;
g_Tag.dataB[5] = 0x3a;
g_Tag.dataB[8] = secondAddr[3];//0x08;
g_Tag.dataB[9] = secondAddr[2];//0x86;
g_Tag.dataB[10] = secondAddr[1];//0x00;
g_Tag.dataB[11] = secondAddr[0];//0x4d;
g_Tag.dataB[12] = 0x0;
g_Tag.dataB[13] = 0x0;
/* 点亮LED1 */
HAL_2G4Hz_LED1_TURN_ON();
g_Tag.dataB[2] = keyFlag;
g_Tag.dataB[3] = hal_nrf_get_output_power ();
g_Tag.dataB[3]++;
if ( g_Tag.dataB[3] >= 0x04 )
{
g_Tag.dataB[3] = 0;
txNumber++;
}
hal_nrf_set_output_power(g_Tag.dataB[3]);
g_Tag.dataB[6] = (char)(txNumber >> 8);
g_Tag.dataB[7] = (char)txNumber;
crc = CRC16(g_Tag.dataB, sizeof(g_Tag.pkt) - sizeof (g_Tag.pkt.crc));
g_Tag.dataB[14] = (char)(crc >> 8);
g_Tag.dataB[15] = (char)crc;
/* 编码接收到的数据 */
Shuffle_TX_ByteOrder();
XXTEA_Encode();
Shuffle_TX_ByteOrder();
hal_nrf_write_tx_pload(g_Tag.dataB, DATA_LONG);
/* RF发送 */
HAL_2G4Hz_CE_PULSE();
/* 熄灭LED1和LED2 */
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED2_TURN_OFF();
keyScan ();
}
}
#endif
/*******************************************************************************
* 文件名称:hal_2.4GHz_Tag.c
* 功 能:RFID-2.4GHz-Reader硬件抽象层
* 作 者:虫虫
* 公 司:
******************************************************************************/
#if !defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h" // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "hal_2.4GHz_Reader.h" // RFID-2.4GHz-Reader硬件抽象层头文件
/********************************************************************/
/*
通过RF发送的数据载荷。也包含接收数据。
使用Radio_Get_Pload_Byte()函数读取
*/
/********************************************************************/
static unsigned char pload[16];
/********************************************************************/
/*
RF的当前状态
使用Radio_Set_Status函数来设置该变量;
使用Radio_Get_Status函数来读取该变量。
*/
/********************************************************************/
static radio_status_t status;
/********************************************************************/
/*********************************************************************
* 函数名称:SetCC2530SleepTime
* 功 能:设置CC2530睡眠时间,即设置CC2530的睡眠定时器的比较值。
* 入口参数:ms 处于功耗模式IDLE、PM0、PM1或PM2的时间。
* 出口参数:无
* 返 回 值:无
* 注 意:使用外部32.768KHz晶体
********************************************************************/
static void
SetCC2530SleepTime(unsigned short ms)
{
unsigned long sleeptime = 0;
/* 读取睡眠定时器的当前计数值 */
sleeptime |= ST0;
sleeptime |= (unsigned long)ST1 << 8;
sleeptime |= (unsigned long)ST2 << 16;
/* 根据指定的睡眠时间计算出应设置的比较值 */
sleeptime += (ms * (unsigned long)(32768 / 1000));
/* 设置比较值 */
while((STLOAD & 0x01) == 0); // 等待允许加载新的比较值
ST2 = (unsigned char)(sleeptime >> 16);
ST1 = (unsigned char)(sleeptime >> 8);
ST0 = (unsigned char) sleeptime;
}
/*********************************************************************
* 函数名称:SetCC2530PowerMode
* 功 能:设置CC2530功耗模式
* 入口参数:pm : 0 空闲模式
* 1 功耗模式PM1
* 2 功耗模式PM2
* 3 功耗模式PM3
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
SetCC2530PowerMode(unsigned char pm)
{
if(pm == 0)
{
SLEEPCMD &= ~0x03;
}
else if(pm == 3)
{
SLEEPCMD |= ~0x03;
}
else
{
SLEEPCMD &= ~0x03;
SLEEPCMD |= pm;
}
/* 进入所选择的功耗模式 */
PCON |= 0x01;
asm("NOP");
}
/*********************************************************************
* 函数名称:CC2530SleepTimer_Delay
* 功 能:延时函数,延时过程中CC2530处于PM2模式。
* 入口参数:nMs 延时时长
* 出口参数:无
* 返 回 值:无
********************************************************************/
void CC2530SleepTimer_Delay(unsigned nMs)
{
SetCC2530SleepTime(nMs);
IRCON &= ~0x80;
IEN0 |= (0x01 << 5);
SetCC2530PowerMode(2);
}
/*********************************************************************
* 函数名称:ST_ISR
* 功 能:CC2530睡眠定时器中断服务函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
#pragma vector=ST_VECTOR
__interrupt void ST_ISR(void)
{
/* 清除CC2530睡眠定时器中断标志 */
IRCON &= ~0x80;
/* 禁止CC2530睡眠定时器中断 */
IEN0 &= ~(0x01 << 5);
}
/*********************************************************************
* 函数名称:SW_SPI_RW
* 功 能:CC2530模拟SPI总线发送1字节数据并从SPI总线读取1字节数据。
* 入口参数:value 待发送的1字节数据
* 出口参数:无
* 返 回 值:读回的1字节数据
********************************************************************/
unsigned char
SW_SPI_RW(unsigned char value)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
HAL_2G4Hz_MOSI = (value & 0x80)? 1 : 0;
value <<= 1;
HAL_2G4Hz_SCK = 1;
value |= HAL_2G4Hz_MISO;
HAL_2G4Hz_SCK = 0;
}
HAL_2G4Hz_MOSI = 0;
return(value);
}
/*********************************************************************
* 函数名称:hal_nrf_set_irq_mode
* 功 能:使能或禁止nRF24L01+的指定中断源
* 入口参数:int_source nRF24L01+的指定中断源
* irq_state 使能或禁止
* 出口参数:无
* 返 回 值:无
********************************************************************/
void hal_nrf_set_irq_mode(hal_nrf_irq_source_t int_source, bool irq_state)
{
if(irq_state)
{
hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) & ~SET_BIT(int_source));
}
else
{
hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) | SET_BIT(int_source));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_clear_irq_flags
* 功 能:获取并清除nRF24L01+的中断标志
* 入口参数:无
* 出口参数:无
* 返 回 值:中断标志
* 0x10 最大重传次数中断
* 0x20 TX数据发送中断
* 0x40 RX数据接收中断
********************************************************************/
unsigned char
hal_nrf_get_clear_irq_flags(void)
{
return hal_nrf_write_reg(STATUS, (BIT_6|BIT_5|BIT_4)) & (BIT_6|BIT_5|BIT_4);
}
/*********************************************************************
* 函数名称:hal_nrf_clear_irq_flag
* 功 能:清除nRF24L01+的指定中断标志
* 入口参数:int_source 指定中断源
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_clear_irq_flag(hal_nrf_irq_source_t int_source)
{
hal_nrf_write_reg(STATUS, SET_BIT(int_source));
}
/*********************************************************************
* 函数名称:hal_nrf_get_irq_mode
* 功 能:获取指定中断的模式
* 入口参数:int_type 指定中断源
* 出口参数:无
* 返 回 值:FALSE 禁止
* TRUE 使能
********************************************************************/
bool
hal_nrf_get_irq_mode(unsigned char int_type)
{
if(hal_nrf_read_reg(CONFIG) & SET_BIT(int_type))
return false;
else
return true;
}
/*********************************************************************
* 函数名称:hal_nrf_nop
* 功 能:调用该函数接收nRF24L01+的状态寄存器
* 入口参数:无
* 出口参数:无
* 返 回 值:状态寄存器的值
********************************************************************/
unsigned char
hal_nrf_nop(void)
{
return hal_nrf_write_reg(NOP,0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_irq_flags
* 功 能:获取nRF24L01+的中断标志
* 入口参数:无
* 出口参数:无
* 返 回 值:中断标志
* 0x10 最大重传次数中断
* 0x20 TX数据发送中断
* 0x40 RX数据接收中断
********************************************************************/
unsigned char
hal_nrf_get_irq_flags(void)
{
return hal_nrf_nop() & (BIT_6|BIT_5|BIT_4);
}
/*********************************************************************
* 函数名称:hal_nrf_set_crc_mode
* 功 能:设置nRF24L01+的CRC模式
* 入口参数:crc_mode 禁止
* 1字节
* 2字节
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_crc_mode(hal_nrf_crc_mode_t crc_mode)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(BIT_3|BIT_2)) |
(UINT8(crc_mode)<<2));
}
/*********************************************************************
* 函数名称:hal_nrf_open_pipe
* 功 能:打开nRF24L01+的1个或所有管道,并设置带有/不带自动ACK特性。
* 入口参数:pipe_num 管道号
* auto_ack 自动ACK特性开/关
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_open_pipe(hal_nrf_address_t pipe_num, bool auto_ack)
{
switch(pipe_num)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) | SET_BIT(pipe_num));
if(auto_ack)
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) | SET_BIT(pipe_num));
else
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
break;
case HAL_NRF_ALL:
hal_nrf_write_reg(EN_RXADDR, ~(BIT_7|BIT_6));
if(auto_ack)
hal_nrf_write_reg(EN_AA, ~(BIT_7|BIT_6));
else
hal_nrf_write_reg(EN_AA, 0);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_close_pipe
* 功 能:关闭nRF24L01+的1个或所有管道
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_close_pipe(hal_nrf_address_t pipe_num)
{
switch(pipe_num)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) & ~SET_BIT(pipe_num));
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
break;
case HAL_NRF_ALL:
hal_nrf_write_reg(EN_RXADDR, 0);
hal_nrf_write_reg(EN_AA, 0);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_address
* 功 能:设置RX或TX地址
* 入口参数:address 设置哪个地址
* addr 指向保存地址值的缓冲区的指针
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_address(hal_nrf_address_t address, unsigned char *addr)
{
switch(address)
{
case HAL_NRF_TX:
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
hal_nrf_write_multibyte_reg((unsigned char) address, addr, 0);
break;
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(RX_ADDR_P0 + (unsigned char) address, *addr);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_auto_retr
* 功 能:设置重传次数和重传延时
* 入口参数:retr 重传次数
* delay 重传延时(单位:us)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_auto_retr(unsigned char retr, unsigned short delay)
{
hal_nrf_write_reg(SETUP_RETR, (((delay/250)-1)<<4) | retr);
}
/*********************************************************************
* 函数名称:hal_nrf_set_address_width
* 功 能:设置地址宽度
* 入口参数:address_width 地址宽度
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_address_width(hal_nrf_address_width_t address_width)
{
hal_nrf_write_reg(SETUP_AW, (UINT8(address_width) - 2));
}
/*********************************************************************
* 函数名称:hal_nrf_set_rx_pload_width
* 功 能:设置指定管道上期望接收的数据长度(单位:字节)
* 入口参数:pipe_num 管道
* pload_width 期望接收的字节数量
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_rx_pload_width(unsigned char pipe_num, unsigned char pload_width)
{
hal_nrf_write_reg(RX_PW_P0 + pipe_num, pload_width);
}
/*********************************************************************
* 函数名称:hal_nrf_get_crc_mode
* 功 能:获取所使用的CRC模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 无CRC
* 0x02 CRC-8
* 0x03 CRC-16
********************************************************************/
unsigned char
hal_nrf_get_crc_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (BIT_3|BIT_2)) >> CRCO;
}
/*********************************************************************
* 函数名称:hal_nrf_get_pipe_status
* 功 能:获取指定管道的状态
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:0x00 管道关闭,自动ACK禁止
* 0x01 管道打开,自动ACK禁止
* 0x03 管道打开,自动ACK打开
********************************************************************/
unsigned char
hal_nrf_get_pipe_status(unsigned char pipe_num)
{
unsigned char en_rx, en_aa;
en_rx = hal_nrf_read_reg(EN_RXADDR) & (1<<pipe_num);
en_aa = hal_nrf_read_reg(EN_AA) & (1<<pipe_num);
en_rx >>= pipe_num;
en_aa >>= pipe_num;
return (en_aa << 1) + en_rx;
}
/*********************************************************************
* 函数名称:hal_nrf_get_address
* 功 能:获取指定管道的地址
* 入口参数:address 要获取哪一种地址,PIPE或TX地址
* addr 获取到得地址数据将写入该指针指向的缓冲区
* 出口参数:无
* 返 回 值:地址宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_address(unsigned char address, unsigned char *addr)
{
switch(address)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
return hal_nrf_read_multibyte_reg(address, addr);
default:
*addr = hal_nrf_read_reg(RX_ADDR_P0 + address);
return hal_nrf_get_address_width();
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_auto_retr_status
* 功 能:获取自动重传参数,即重传次数和重传延时。
* 入口参数:无
* 出口参数:无
* 返 回 值:高4位 重传延时
* 低4位 重传次数
********************************************************************/
unsigned char
hal_nrf_get_auto_retr_status(void)
{
return hal_nrf_read_reg(OBSERVE_TX);
}
/*********************************************************************
* 函数名称:hal_nrf_get_packet_lost_ctr
* 功 能:获取丢包计数器的值
* 入口参数:无
* 出口参数:无
* 返 回 值:丢包计数器的值
********************************************************************/
unsigned char
hal_nrf_get_packet_lost_ctr(void)
{
return (hal_nrf_read_reg(OBSERVE_TX) & (BIT_7|BIT_6|BIT_5|BIT_4)) >> 4;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_pload_width
* 功 能:获取所指定管道上所期望接收的数据宽度(单位:字节)
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:数据宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_rx_pload_width(unsigned char pipe_num)
{
return hal_nrf_read_reg(RX_PW_P0 + pipe_num);
}
/*********************************************************************
* 函数名称:hal_nrf_set_operation_mode
* 功 能:进入 PTX (primary TX) 或 PRX (primary RX)模式
* 入口参数:op_mode 运行模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_operation_mode(hal_nrf_operation_mode_t op_mode)
{
if(op_mode == HAL_NRF_PRX)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PRIM_RX)));
}
else
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PRIM_RX)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_power_mode
* 功 能:上电或掉电RF
* 入口参数:pwr_mode POWER_UP 或 POWER_DOWN
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_power_mode(hal_nrf_pwr_mode_t pwr_mode)
{
if(pwr_mode == HAL_NRF_PWR_UP)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PWR_UP)));
}
else
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PWR_UP)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_rf_channel
* 功 能:选择所使用的RF信道
* 入口参数:channel RF信道
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_rf_channel(unsigned char channel)
{
hal_nrf_write_reg(RF_CH, channel);
}
/*********************************************************************
* 函数名称:hal_nrf_set_output_power
* 功 能:选择RF TX输出功率
* 入口参数:power RF TX输出功率
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_output_power(hal_nrf_output_power_t power)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) &
~((1<<RF_PWR1)|(1<<RF_PWR0))) | (UINT8(power)<<1));
}
/*********************************************************************
* 函数名称:hal_nrf_set_datarate
* 功 能:设置无线通信数据速率
* 入口参数:datarate 无线通信数据速率
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_datarate(hal_nrf_datarate_t datarate)
{
if(datarate == HAL_NRF_1MBPS)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<RF_DR)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<RF_DR)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_operation_mode
* 功 能:获取运行模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 Primary RX (PRX)
* 0x01 Primary TX (PTX)
********************************************************************/
unsigned char
hal_nrf_get_operation_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (1<<PRIM_RX)) >> PRIM_RX;
}
/*********************************************************************
* 函数名称:hal_nrf_get_power_mode
* 功 能:获取功耗模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 POWER_DOWN
* 0x01 POWER_UP
********************************************************************/
unsigned char
hal_nrf_get_power_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (1<<PWR_UP)) >> PWR_UP;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rf_channel
* 功 能:获取所使用的RF信道
* 入口参数:无
* 出口参数:无
* 返 回 值:RF信道
********************************************************************/
unsigned char
hal_nrf_get_rf_channel(void)
{
return hal_nrf_read_reg(RF_CH);
}
/*********************************************************************
* 函数名称:hal_nrf_get_output_power
* 功 能:获取所使用的RF TX输出功率
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 -18dBm
* 0x01 -12dBm
* 0x02 -6dBm
* 0x03 0dBm
********************************************************************/
unsigned char
hal_nrf_get_output_power(void)
{
return (hal_nrf_read_reg(RF_SETUP) & ((1<<RF_PWR1)|(1<<RF_PWR0))) >> RF_PWR0;
}
/*********************************************************************
* 函数名称:hal_nrf_get_datarate
* 功 能:获取所使用的无线通信数据速率
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 1Mbps
* 0x01 2Mbps
********************************************************************/
unsigned char
hal_nrf_get_datarate(void)
{
return (hal_nrf_read_reg(RF_SETUP) & (1<<RF_DR)) >> RF_DR;
}
/*********************************************************************
* 函数名称:hal_nrf_rx_fifo_empty
* 功 能:检查RX FIFO是否为空
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE RX FIFO 不空
* TRUE RX FIFO 空
********************************************************************/
bool
hal_nrf_rx_fifo_empty(void)
{
if(hal_nrf_get_rx_data_source()==7)
{
return true;
}
else
{
return false;
}
}
/*********************************************************************
* 函数名称:hal_nrf_rx_fifo_full
* 功 能:检查RX FIFO是否为满
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE RX FIFO 不满
* TRUE RX FIFO 满
********************************************************************/
bool
hal_nrf_rx_fifo_full(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> RX_EMPTY) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_tx_fifo_empty
* 功 能:检查TX FIFO是否为空
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE TX FIFO 不空
* TRUE TX FIFO 空
********************************************************************/
bool
hal_nrf_tx_fifo_empty(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_EMPTY) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_tx_fifo_full
* 功 能:检查TX FIFO是否为满
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE TX FIFO 不满
* TRUE TX FIFO 满
********************************************************************/
bool
hal_nrf_tx_fifo_full(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_FIFO_FULL) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_get_tx_fifo_status
* 功 能:检查TX FIFO的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 TX FIFO 不空, 也不满
* 0x01 TX FIFO 空
* 0x02 TX FIFO 满
********************************************************************/
unsigned char
hal_nrf_get_tx_fifo_status(void)
{
return ((hal_nrf_read_reg(FIFO_STATUS) &
((1<<TX_FIFO_FULL)|(1<<TX_EMPTY))) >> 4);
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_fifo_status
* 功 能:检查RX FIFO的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 RX FIFO 不空, 也不满
* 0x01 RX FIFO 空
* 0x02 RX FIFO 满
********************************************************************/
unsigned char
hal_nrf_get_rx_fifo_status(void)
{
return (hal_nrf_read_reg(FIFO_STATUS) & ((1<<RX_FULL)|(1<<RX_EMPTY)));
}
/*********************************************************************
* 函数名称:hal_nrf_get_fifo_status
* 功 能:检查FIFO状态
* 入口参数:无
* 出口参数:无
* 返 回 值:FIFO状态寄存器的值
********************************************************************/
unsigned char
hal_nrf_get_fifo_status(void)
{
return hal_nrf_read_reg(FIFO_STATUS);
}
/*********************************************************************
* 函数名称:hal_nrf_get_transmit_attempts
* 功 能:获取重传尝试的次数和丢包数量
* 入口参数:无
* 出口参数:无
* 返 回 值:重传尝试计数器的值
********************************************************************/
unsigned char
hal_nrf_get_transmit_attempts(void)
{
return hal_nrf_read_reg(OBSERVE_TX) & (BIT_3|BIT_2|BIT_1|BIT_0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_carrier_detect
* 功 能:获取载波检测标志
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE 未检测到载波
* TRUE 检测到载波
********************************************************************/
bool
hal_nrf_get_carrier_detect(void)
{
return hal_nrf_read_reg(CD) & 1;
}
/*********************************************************************
* 函数名称:hal_nrf_write_tx_pload
* 功 能:写数据包的数据载荷部分到RF
* 入口参数:tx_pload 指向存储数据载荷的缓冲区的指针
* length 数据载荷的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_tx_pload(unsigned char *tx_pload, unsigned char length)
{
hal_nrf_write_multibyte_reg(UINT8(HAL_NRF_TX_PLOAD), tx_pload, length);
}
/*********************************************************************
* 函数名称:hal_nrf_setup_dyn_pl
* 功 能:设置接收管道的动态数据负载特性。
* 入口参数:setup 管道特性位掩码
* 例如:bit0设置为1时,管道0使用ACK数据负载。
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_setup_dyn_pl(unsigned char setup)
{
hal_nrf_write_reg(DYNPD, setup & ~0xC0);
}
/*********************************************************************
* 函数名称:hal_nrf_enable_dynamic_pl
* 功 能:使能动态数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_dynamic_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x04));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_dynamic_pl
* 功 能:禁止动态数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_dynamic_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x04));
}
/*********************************************************************
* 函数名称:hal_nrf_enable_ack_pl
* 功 能:使能ACK数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_ack_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x02));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_ack_pl
* 功 能:禁止ACK数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_ack_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x02));
}
/*********************************************************************
* 函数名称:hal_nrf_enable_dynamic_ack
* 功 能:使能no-ack特性
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_dynamic_ack(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x01));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_dynamic_ack
* 功 能:禁止no-ack特性
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_dynamic_ack(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x01));
}
/*********************************************************************
* 函数名称:hal_nrf_write_ack_pload
* 功 能:给指定管道写入带ACK特性的数据负载。
* 入口参数:pipe 管道号
* tx_pload 指向存储待写入数据的缓冲区的指针
* length 待写入数据的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_ack_pload(unsigned char pipe, unsigned char *tx_pload,
unsigned char length)
{
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WR_ACK_PLOAD | pipe);
while(length--)
{
SW_SPI_RW(*tx_pload++);
}
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_nrf_read_rx_pl_w
* 功 能:读取接收到的ACK数据负载的宽度
* 入口参数:无
* 出口参数:无
* 返 回 值:接收到的ACK数据负载的宽度
********************************************************************/
unsigned char
hal_nrf_read_rx_pl_w()
{
unsigned char temp;
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RD_RX_PLOAD_W);
temp = SW_SPI_RW(0);
HAL_2G4Hz_CSN = 1;
return temp;
}
/*********************************************************************
* 函数名称:hal_nrf_lock_unlock
* 功 能:给nRF24L01+发送ACTIVATE命令
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_lock_unlock()
{
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(LOCK_UNLOCK);
SW_SPI_RW(0x73);
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_data_source
* 功 能:获取当前哪一个管道接收的数据包是当前最高级别数据包
* 入口参数:无
* 出口参数:无
* 返 回 值:管道号
********************************************************************/
unsigned char
hal_nrf_get_rx_data_source(void)
{
return ((hal_nrf_nop() & (BIT_3|BIT_2|BIT_1)) >> 1);
}
/*********************************************************************
* 函数名称:hal_nrf_read_reg
* 功 能:读取nRF24L01+的寄存器内容
* 入口参数:reg 要读取的寄存器
* 出口参数:无
* 返 回 值:读出的寄存器内容
********************************************************************/
unsigned char
hal_nrf_read_reg(unsigned char reg)
{
unsigned char temp;
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(reg);
temp = SW_SPI_RW(0);
HAL_2G4Hz_CSN = 1;
return temp;
}
/*********************************************************************
* 函数名称:hal_nrf_read_rx_pload
* 功 能:读取RX FIFO中可用的最高级别数据载荷
* 入口参数:rx_pload 指向存储读出数据的缓冲区的指针
* 出口参数:无
* 返 回 值:高8位 管道号
* 低8位 数据长度(单位:字节)
* 数据长度为0且管道号为7意味着FIFO为空
********************************************************************/
unsigned short
hal_nrf_read_rx_pload(unsigned char *rx_pload)
{
return hal_nrf_read_multibyte_reg(UINT8(HAL_NRF_RX_PLOAD), rx_pload);
}
/*********************************************************************
* 函数名称:hal_nrf_reuse_tx
* 功 能:设置RF使用最后一次发送的数据载荷作为下一个数据包
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_reuse_tx(void)
{
hal_nrf_write_reg(REUSE_TX_PL, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_reuse_tx_status
* 功 能:检查reuse_tx功能的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE 未激活
* TRUE 激活
********************************************************************/
bool
hal_nrf_get_reuse_tx_status(void)
{
return (bool)((hal_nrf_get_fifo_status() & (1<<TX_REUSE)) >> TX_REUSE);
}
/*********************************************************************
* 函数名称:hal_nrf_flush_rx
* 功 能:清空RX FIFO
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_flush_rx(void)
{
hal_nrf_write_reg(FLUSH_RX, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_flush_tx
* 功 能:清空TX FIFO
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_flush_tx(void)
{
hal_nrf_write_reg(FLUSH_TX, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_set_pll_mode
* 功 能:LOCK或UNLOCK RF PLL
* 入口参数:pll_mode PLL locked: TRUE 或 FALSE
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_pll_mode(hal_nrf_pll_mode_t pll_mode)
{
if(pll_mode == HAL_NRF_PLL_LOCK)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<PLL_LOCK)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<PLL_LOCK)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_pll_mode
* 功 能:获取 RF PLL的当前模式
* 入口参数:无
* 出口参数:无
* 返 回 值:RF PLL的当前模式
********************************************************************/
hal_nrf_pll_mode_t
hal_nrf_get_pll_mode(void)
{
return (hal_nrf_pll_mode_t)((hal_nrf_read_reg(RF_SETUP) &
(1<<PLL_LOCK)) >> PLL_LOCK);
}
/*********************************************************************
* 函数名称:hal_nrf_set_lna_gain
* 功 能:设置RF使用的LNA增益模式
* 入口参数:lna_gain LNA增益模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_lna_gain(hal_nrf_lna_mode_t lna_gain)
{
if(lna_gain == HAL_NRF_LNA_HCURR)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<LNA_HCURR)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<LNA_HCURR)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_lna_gain
* 功 能:获取RF当前使用的LNA增益模式
* 入口参数:lna_gain LNA增益模式
* 出口参数:无
* 返 回 值:0 LNA 低电流
* 1 LNA 高电流
********************************************************************/
hal_nrf_lna_mode_t
hal_nrf_get_lna_gain(void)
{
return (hal_nrf_lna_mode_t) ( (hal_nrf_read_reg(RF_SETUP) &
(1<<LNA_HCURR)) >> LNA_HCURR );
}
/*********************************************************************
* 函数名称:hal_nrf_read_multibyte_reg
* 功 能:从nRF24L01+的指定寄存器读取多字节数据
* 入口参数:reg nRF24L01+的指定寄存器
* pbuf 指向存储读出数据的缓冲区的指针
* 出口参数:无
* 返 回 值:高8位:接收数据的管道号(用于hal_nrf_read_rx_pload函数)
* 低8位:读取数据的长度(用于hal_nrf_read_rx_pload 或hal_nrf_get_address函数)
********************************************************************/
unsigned short
hal_nrf_read_multibyte_reg(unsigned char reg, unsigned char *pbuf)
{
unsigned char ctr, length;
switch(reg)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
length = ctr = hal_nrf_get_address_width();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RX_ADDR_P0 + reg);
break;
case HAL_NRF_RX_PLOAD:
if( (reg = hal_nrf_get_rx_data_source()) < 7)
{
length = ctr = hal_nrf_read_rx_pl_w();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RD_RX_PLOAD);
}
else
{
ctr = length = 0;
}
break;
default:
ctr = length = 0;
break;
}
while(ctr--)
{
*pbuf++ = SW_SPI_RW(0);
}
HAL_2G4Hz_CSN = 1;
return (((unsigned short) reg << 8) | length);
}
/*********************************************************************
* 函数名称:hal_nrf_write_reg
* 功 能:写一个新值到nRF24L01+的指定寄存器
* 入口参数:reg 待写入新值的寄存器
* value 待写入的新值
* 出口参数:无
* 返 回 值:1字节返回值
********************************************************************/
unsigned char
hal_nrf_write_reg(unsigned char reg, unsigned char value)
{
unsigned char retval;
HAL_2G4Hz_CSN = 0;
if(reg < WRITE_REG)
{
retval = SW_SPI_RW(WRITE_REG + reg);
SW_SPI_RW(value);
}
else
{
if(!(reg == FLUSH_TX) && !(reg == FLUSH_RX) && !(reg == REUSE_TX_PL) && !(reg == NOP))
{
retval = SW_SPI_RW(reg);
SW_SPI_RW(value);
}
else
{
retval = SW_SPI_RW(reg);
}
}
HAL_2G4Hz_CSN = 1;
return retval;
}
/*********************************************************************
* 函数名称:hal_nrf_get_address_width
* 功 能:获取nRF24L01+射频使用的地址宽度,包括RX和TX
* 入口参数:无
* 出口参数:无
* 返 回 值:地址宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_address_width(void)
{
return (hal_nrf_read_reg(SETUP_AW) + 2);
}
/*********************************************************************
* 函数名称:hal_nrf_write_multibyte_reg
* 功 能:写多个字节数据到nRF24L01+的指定寄存器
* 入口参数:reg 待写入数据的寄存器
* pbuf 指向保存待写入数据的缓冲区的指针
* length 待写入数据的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_multibyte_reg(unsigned char reg, unsigned char *pbuf,
unsigned char length)
{
switch(reg)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
length = hal_nrf_get_address_width();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WRITE_REG + RX_ADDR_P0 + reg);
break;
case HAL_NRF_TX_PLOAD:
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WR_TX_PLOAD);
break;
default:
break;
}
while(length--)
{
SW_SPI_RW(*pbuf++);
}
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_2G4Hz_Reader_Init
* 功 能:RFID-2.4GHz-Reader硬件抽象层初始化
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 注 意:本函数使能了CC2530的全局中断
********************************************************************/
void hal_2G4Hz_Reader_Init(void)
{
/* 使能CC2530的缓存预取模式 */
PREFETCH_ENABLE();
/* LED相关初始化 */
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED1_DDR |= HAL_2G4Hz_LED1_BV;
HAL_2G4Hz_LED2_TURN_OFF();
HAL_2G4Hz_LED2_DDR |= HAL_2G4Hz_LED2_BV;
/* CC2530与nRF24L01+相连引脚初始化 */
HAL_2G4Hz_CSN = 1;
HAL_2G4Hz_CE = 0;
HAL_2G4Hz_MOSI = 0;
HAL_2G4Hz_SCK = 0;
HAL_2G4Hz_CSN_DDR |= HAL_2G4Hz_CSN_BV;
HAL_2G4Hz_CE_DDR |= HAL_2G4Hz_CE_BV;
HAL_2G4Hz_SCK_DDR |= HAL_2G4Hz_SCK_BV;
HAL_2G4Hz_MOSI_DDR |= HAL_2G4Hz_MOSI_BV;
HAL_2G4Hz_MISO_DDR &= ~HAL_2G4Hz_MISO_BV;
HAL_2G4Hz_IRQ_DDR &= ~HAL_2G4Hz_IRQ_BV;
P0INP |= HAL_2G4Hz_BUTTON_BV;
PICTL |= 0x01;
P0IEN |= HAL_2G4Hz_IRQ_BV;
IEN1 |= (1 << 5);
EA = 1;
}
/*********************************************************************
* 函数名称:Radio_Set_Status
* 功 能:更新status全局变量
* 入口参数:new_status 新状态值
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_Set_Status (radio_status_t new_status)
{
status = new_status;
}
/*********************************************************************
* 函数名称:Radio_Get_Status
* 功 能:读取status全局变量
* 入口参数:无
* 出口参数:无
* 返 回 值:RF当前状态标志变量status的当前值
********************************************************************/
radio_status_t
Radio_Get_Status (void)
{
return status;
}
/*********************************************************************
* 函数名称:HAL_2G4Hz_CE_PULSE
* 功 能:脉动nRF24L01+的CE信号至少10us
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
HAL_2G4Hz_CE_PULSE(void)
{
unsigned char count;
count = 20;
HAL_2G4Hz_CE = 1;
while(count--);
HAL_2G4Hz_CE = 0;
}
/*********************************************************************
* 函数名称:Radio_SB_MODE_Init
* 功 能:nRF24L01+的ShockBurst(TM)模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_SB_MODE_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, false);
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_datarate(HAL_NRF_2MBPS);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_ESB_MODE_Init
* 功 能:nRF24L01+的Enhanced ShockBurst(TM)模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_ESB_MODE_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
/* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, true);
/* 使用CRC-16模式 */
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
/* 使能自动重传:重传次数为RF_RETRANSMITS,重传延时为RF_RETRANS_DELAY */
hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
/* 设置为PTX模式 */
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
/* 设置为RTX模式 */
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
/* 设置运行信道为 频率 = 2400 + RF_CHANNEL */
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
/* RF就绪 */
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_ESB_MODE_PL_Init
* 功 能:nRF24L01+的Enhanced ShockBurst(TM) with bidirectional Data模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_ESB_MODE_PL_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
/* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, true);
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
/*
以下部分与Radio_ESB_MODE_Init函数不同
使能ACK数据载荷
使能动态数据载荷宽度
使能动态ACK
*/
/****************************************************************************/
/* 使能ACK数据载荷特性 */
hal_nrf_enable_ack_pl();
if(hal_nrf_read_reg(FEATURE) == 0x00 && (hal_nrf_read_reg(DYNPD) == 0x00))
{
hal_nrf_lock_unlock ();
hal_nrf_enable_ack_pl();
}
/* 使能动态数据载荷特性 */
hal_nrf_enable_dynamic_pl();
/* 设置所有接收管道具有动态数据载荷特性 */
hal_nrf_setup_dyn_pl(ALL_PIPES);
/****************************************************************************/
/* 设置为PTX模式 */
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
/* 设置为RTX模式 */
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_Send_Packet
* 功 能:RF发送数据包
* 入口参数:packet 指向保存待发送数据包的缓冲区的指针
* length 待发送数据包的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_Send_Packet(unsigned char *packet, unsigned char length)
{
/* 加载数据包到RF */
hal_nrf_write_tx_pload(packet, length);
/* RF发送 */
HAL_2G4Hz_CE_PULSE();
/* 更新RF状态变量status 为RF_BUSY */
Radio_Set_Status (RF_BUSY);
}
/*********************************************************************
* 函数名称:Radio_Get_Pload_Byte
* 功 能:byte_index 数据载荷的字节索引
* 入口参数:无
* 出口参数:无
* 返 回 值:数据载荷字节索引所指定的1字节数据
********************************************************************/
unsigned char
Radio_Get_Pload_Byte (unsigned char byte_index)
{
return pload[byte_index];
}
/*********************************************************************
* 函数名称:Radio_IRQ
* 功 能:nRF24L01+的中断处理函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_IRQ(void)
{
/* 若nRF24L01+触发了CC2530的外部中断 */
if(RADIO_ACTIVITY())
{
hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN);
HAL_2G4Hz_CE = 0;
switch(hal_nrf_get_clear_irq_flags ())
{
/* 达到最大重传次数中断 */
case (1<<HAL_NRF_MAX_RT):
hal_nrf_flush_tx();
Radio_Set_Status (RF_MAX_RT);
break;
/* TX数据发送中断 */
case (1<<HAL_NRF_TX_DS):
Radio_Set_Status (RF_TX_DS);
break;
/* RX数据接收中断 */
case (1<<HAL_NRF_RX_DR):
while (!hal_nrf_rx_fifo_empty ())
{
hal_nrf_read_rx_pload(pload);
}
Radio_Set_Status (RF_RX_DR);
break;
/* 接收到ACK数据载荷中断 */
case ((1<<HAL_NRF_RX_DR)|(1<<HAL_NRF_TX_DS)):
while (!hal_nrf_rx_fifo_empty ())
{
hal_nrf_read_rx_pload(pload);
}
Radio_Set_Status (RF_TX_AP);
break;
default:
break;
}
RESET_RADIO_ACTIVITY();
}
}
/*********************************************************************
* 函数名称:P0INT_ISR
* 功 能:CC2530的P0口中断服务函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
#pragma vector=P0INT_VECTOR
__interrupt void P0INT_ISR(void)
{
Radio_IRQ();
}
#endif
/*******************************************************************************
* 文件名称:hal_2.4GHz_Tag.c
* 功 能:RFID-2.4GHz-Reader硬件抽象层
* 作 者:
* 公 司:
******************************************************************************/
#if defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h" // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "hal_2.4GHz_Tag.h" // RFID-2.4GHz-Tag硬件抽象层头文件
/********************************************************************/
/*
通过RF发送的数据载荷。也包含接收数据。
使用Radio_Get_Pload_Byte()函数读取
*/
/********************************************************************/
static unsigned char pload[16];
/********************************************************************/
/*
RF的当前状态
使用Radio_Set_Status函数来设置该变量;
使用Radio_Get_Status函数来读取该变量。
*/
/********************************************************************/
static radio_status_t status;
/********************************************************************/
/*********************************************************************
* 函数名称:SetCC2530SleepTime
* 功 能:设置CC2530睡眠时间,即设置CC2530的睡眠定时器的比较值。
* 入口参数:ms 处于功耗模式IDLE、PM0、PM1或PM2的时间。
* 出口参数:无
* 返 回 值:无
* 注 意:使用外部32.768KHz晶体
********************************************************************/
static void
SetCC2530SleepTime(unsigned short ms)
{
unsigned long sleeptime = 0;
/* 读取睡眠定时器的当前计数值 */
sleeptime |= ST0;
sleeptime |= (unsigned long)ST1 << 8;
sleeptime |= (unsigned long)ST2 << 16;
/* 根据指定的睡眠时间计算出应设置的比较值 */
sleeptime += (ms * (unsigned long)(32768 / 1000));
/* 设置比较值 */
while((STLOAD & 0x01) == 0); // 等待允许加载新的比较值
ST2 = (unsigned char)(sleeptime >> 16);
ST1 = (unsigned char)(sleeptime >> 8);
ST0 = (unsigned char) sleeptime;
}
/*********************************************************************
* 函数名称:SetCC2530PowerMode
* 功 能:设置CC2530功耗模式
* 入口参数:pm : 0 空闲模式
* 1 功耗模式PM1
* 2 功耗模式PM2
* 3 功耗模式PM3
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
SetCC2530PowerMode(unsigned char pm)
{
if(pm == 0)
{
SLEEPCMD &= ~0x03;
}
else if(pm == 3)
{
SLEEPCMD |= ~0x03;
}
else
{
SLEEPCMD &= ~0x03;
SLEEPCMD |= pm;
}
/* 进入所选择的功耗模式 */
PCON |= 0x01;
asm("NOP");
}
/*********************************************************************
* 函数名称:CC2530SleepTimer_Delay
* 功 能:延时函数,延时过程中CC2530处于PM2模式。
* 入口参数:nMs 延时时长
* 出口参数:无
* 返 回 值:无
********************************************************************/
void CC2530SleepTimer_Delay(unsigned nMs)
{
SetCC2530SleepTime(nMs);
IRCON &= ~0x80;
IEN0 |= (0x01 << 5);
SetCC2530PowerMode(2);
}
/*********************************************************************
* 函数名称:ST_ISR
* 功 能:CC2530睡眠定时器中断服务函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
#pragma vector=ST_VECTOR
__interrupt void ST_ISR(void)
{
/* 清除CC2530睡眠定时器中断标志 */
IRCON &= ~0x80;
/* 禁止CC2530睡眠定时器中断 */
IEN0 &= ~(0x01 << 5);
}
/*********************************************************************
* 函数名称:SW_SPI_RW
* 功 能:CC2530模拟SPI总线发送1字节数据并从SPI总线读取1字节数据。
* 入口参数:value 待发送的1字节数据
* 出口参数:无
* 返 回 值:读回的1字节数据
********************************************************************/
unsigned char
SW_SPI_RW(unsigned char value)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
HAL_2G4Hz_MOSI = (value & 0x80)? 1 : 0;
value <<= 1;
HAL_2G4Hz_SCK = 1;
value |= HAL_2G4Hz_MISO;
HAL_2G4Hz_SCK = 0;
}
HAL_2G4Hz_MOSI = 0;
return(value);
}
/*********************************************************************
* 函数名称:hal_nrf_set_irq_mode
* 功 能:使能或禁止nRF24L01+的指定中断源
* 入口参数:int_source nRF24L01+的指定中断源
* irq_state 使能或禁止
* 出口参数:无
* 返 回 值:无
********************************************************************/
void hal_nrf_set_irq_mode(hal_nrf_irq_source_t int_source, bool irq_state)
{
if(irq_state)
{
hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) & ~SET_BIT(int_source));
}
else
{
hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) | SET_BIT(int_source));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_clear_irq_flags
* 功 能:获取并清除nRF24L01+的中断标志
* 入口参数:无
* 出口参数:无
* 返 回 值:中断标志
* 0x10 最大重传次数中断
* 0x20 TX数据发送中断
* 0x40 RX数据接收中断
********************************************************************/
unsigned char
hal_nrf_get_clear_irq_flags(void)
{
return hal_nrf_write_reg(STATUS, (BIT_6|BIT_5|BIT_4)) & (BIT_6|BIT_5|BIT_4);
}
/*********************************************************************
* 函数名称:hal_nrf_clear_irq_flag
* 功 能:清除nRF24L01+的指定中断标志
* 入口参数:int_source 指定中断源
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_clear_irq_flag(hal_nrf_irq_source_t int_source)
{
hal_nrf_write_reg(STATUS, SET_BIT(int_source));
}
/*********************************************************************
* 函数名称:hal_nrf_get_irq_mode
* 功 能:获取指定中断的模式
* 入口参数:int_type 指定中断源
* 出口参数:无
* 返 回 值:FALSE 禁止
* TRUE 使能
********************************************************************/
bool
hal_nrf_get_irq_mode(unsigned char int_type)
{
if(hal_nrf_read_reg(CONFIG) & SET_BIT(int_type))
return false;
else
return true;
}
/*********************************************************************
* 函数名称:hal_nrf_nop
* 功 能:调用该函数接收nRF24L01+的状态寄存器
* 入口参数:无
* 出口参数:无
* 返 回 值:状态寄存器的值
********************************************************************/
unsigned char
hal_nrf_nop(void)
{
return hal_nrf_write_reg(NOP,0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_irq_flags
* 功 能:获取nRF24L01+的中断标志
* 入口参数:无
* 出口参数:无
* 返 回 值:中断标志
* 0x10 最大重传次数中断
* 0x20 TX数据发送中断
* 0x40 RX数据接收中断
********************************************************************/
unsigned char
hal_nrf_get_irq_flags(void)
{
return hal_nrf_nop() & (BIT_6|BIT_5|BIT_4);
}
/*********************************************************************
* 函数名称:hal_nrf_set_crc_mode
* 功 能:设置nRF24L01+的CRC模式
* 入口参数:crc_mode 禁止
* 1字节
* 2字节
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_crc_mode(hal_nrf_crc_mode_t crc_mode)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(BIT_3|BIT_2)) |
(UINT8(crc_mode)<<2));
}
/*********************************************************************
* 函数名称:hal_nrf_open_pipe
* 功 能:打开nRF24L01+的1个或所有管道,并设置带有/不带自动ACK特性。
* 入口参数:pipe_num 管道号
* auto_ack 自动ACK特性开/关
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_open_pipe(hal_nrf_address_t pipe_num, bool auto_ack)
{
switch(pipe_num)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) | SET_BIT(pipe_num));
if(auto_ack)
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) | SET_BIT(pipe_num));
else
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
break;
case HAL_NRF_ALL:
hal_nrf_write_reg(EN_RXADDR, ~(BIT_7|BIT_6));
if(auto_ack)
hal_nrf_write_reg(EN_AA, ~(BIT_7|BIT_6));
else
hal_nrf_write_reg(EN_AA, 0);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_close_pipe
* 功 能:关闭nRF24L01+的1个或所有管道
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_close_pipe(hal_nrf_address_t pipe_num)
{
switch(pipe_num)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) & ~SET_BIT(pipe_num));
hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
break;
case HAL_NRF_ALL:
hal_nrf_write_reg(EN_RXADDR, 0);
hal_nrf_write_reg(EN_AA, 0);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_address
* 功 能:设置RX或TX地址
* 入口参数:address 设置哪个地址
* addr 指向保存地址值的缓冲区的指针
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_address(hal_nrf_address_t address, unsigned char *addr)
{
switch(address)
{
case HAL_NRF_TX:
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
hal_nrf_write_multibyte_reg((unsigned char) address, addr, 0);
break;
case HAL_NRF_PIPE2:
case HAL_NRF_PIPE3:
case HAL_NRF_PIPE4:
case HAL_NRF_PIPE5:
hal_nrf_write_reg(RX_ADDR_P0 + (unsigned char) address, *addr);
break;
default:
break;
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_auto_retr
* 功 能:设置重传次数和重传延时
* 入口参数:retr 重传次数
* delay 重传延时(单位:us)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_auto_retr(unsigned char retr, unsigned short delay)
{
hal_nrf_write_reg(SETUP_RETR, (((delay/250)-1)<<4) | retr);
}
/*********************************************************************
* 函数名称:hal_nrf_set_address_width
* 功 能:设置地址宽度
* 入口参数:address_width 地址宽度
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_address_width(hal_nrf_address_width_t address_width)
{
hal_nrf_write_reg(SETUP_AW, (UINT8(address_width) - 2));
}
/*********************************************************************
* 函数名称:hal_nrf_set_rx_pload_width
* 功 能:设置指定管道上期望接收的数据长度(单位:字节)
* 入口参数:pipe_num 管道
* pload_width 期望接收的字节数量
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_rx_pload_width(unsigned char pipe_num, unsigned char pload_width)
{
hal_nrf_write_reg(RX_PW_P0 + pipe_num, pload_width);
}
/*********************************************************************
* 函数名称:hal_nrf_get_crc_mode
* 功 能:获取所使用的CRC模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 无CRC
* 0x02 CRC-8
* 0x03 CRC-16
********************************************************************/
unsigned char
hal_nrf_get_crc_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (BIT_3|BIT_2)) >> CRCO;
}
/*********************************************************************
* 函数名称:hal_nrf_get_pipe_status
* 功 能:获取指定管道的状态
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:0x00 管道关闭,自动ACK禁止
* 0x01 管道打开,自动ACK禁止
* 0x03 管道打开,自动ACK打开
********************************************************************/
unsigned char
hal_nrf_get_pipe_status(unsigned char pipe_num)
{
unsigned char en_rx, en_aa;
en_rx = hal_nrf_read_reg(EN_RXADDR) & (1<<pipe_num);
en_aa = hal_nrf_read_reg(EN_AA) & (1<<pipe_num);
en_rx >>= pipe_num;
en_aa >>= pipe_num;
return (en_aa << 1) + en_rx;
}
/*********************************************************************
* 函数名称:hal_nrf_get_address
* 功 能:获取指定管道的地址
* 入口参数:address 要获取哪一种地址,PIPE或TX地址
* addr 获取到得地址数据将写入该指针指向的缓冲区
* 出口参数:无
* 返 回 值:地址宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_address(unsigned char address, unsigned char *addr)
{
switch(address)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
return hal_nrf_read_multibyte_reg(address, addr);
default:
*addr = hal_nrf_read_reg(RX_ADDR_P0 + address);
return hal_nrf_get_address_width();
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_auto_retr_status
* 功 能:获取自动重传参数,即重传次数和重传延时。
* 入口参数:无
* 出口参数:无
* 返 回 值:高4位 重传延时
* 低4位 重传次数
********************************************************************/
unsigned char
hal_nrf_get_auto_retr_status(void)
{
return hal_nrf_read_reg(OBSERVE_TX);
}
/*********************************************************************
* 函数名称:hal_nrf_get_packet_lost_ctr
* 功 能:获取丢包计数器的值
* 入口参数:无
* 出口参数:无
* 返 回 值:丢包计数器的值
********************************************************************/
unsigned char
hal_nrf_get_packet_lost_ctr(void)
{
return (hal_nrf_read_reg(OBSERVE_TX) & (BIT_7|BIT_6|BIT_5|BIT_4)) >> 4;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_pload_width
* 功 能:获取所指定管道上所期望接收的数据宽度(单位:字节)
* 入口参数:pipe_num 管道号
* 出口参数:无
* 返 回 值:数据宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_rx_pload_width(unsigned char pipe_num)
{
return hal_nrf_read_reg(RX_PW_P0 + pipe_num);
}
/*********************************************************************
* 函数名称:hal_nrf_set_operation_mode
* 功 能:进入 PTX (primary TX) 或 PRX (primary RX)模式
* 入口参数:op_mode 运行模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_operation_mode(hal_nrf_operation_mode_t op_mode)
{
if(op_mode == HAL_NRF_PRX)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PRIM_RX)));
}
else
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PRIM_RX)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_power_mode
* 功 能:上电或掉电RF
* 入口参数:pwr_mode POWER_UP 或 POWER_DOWN
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_power_mode(hal_nrf_pwr_mode_t pwr_mode)
{
if(pwr_mode == HAL_NRF_PWR_UP)
{
hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PWR_UP)));
}
else
{
asm("nop");
asm("nop");
}
}
/*********************************************************************
* 函数名称:hal_nrf_set_rf_channel
* 功 能:选择所使用的RF信道
* 入口参数:channel RF信道
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_rf_channel(unsigned char channel)
{
hal_nrf_write_reg(RF_CH, channel);
}
/*********************************************************************
* 函数名称:hal_nrf_set_output_power
* 功 能:选择RF TX输出功率
* 入口参数:power RF TX输出功率
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_output_power(hal_nrf_output_power_t power)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) &
~((1<<RF_PWR1)|(1<<RF_PWR0))) | (UINT8(power)<<1));
}
/*********************************************************************
* 函数名称:hal_nrf_set_datarate
* 功 能:设置无线通信数据速率
* 入口参数:datarate 无线通信数据速率
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_datarate(hal_nrf_datarate_t datarate)
{
if(datarate == HAL_NRF_1MBPS)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<RF_DR)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<RF_DR)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_operation_mode
* 功 能:获取运行模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 Primary RX (PRX)
* 0x01 Primary TX (PTX)
********************************************************************/
unsigned char
hal_nrf_get_operation_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (1<<PRIM_RX)) >> PRIM_RX;
}
/*********************************************************************
* 函数名称:hal_nrf_get_power_mode
* 功 能:获取功耗模式
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 POWER_DOWN
* 0x01 POWER_UP
********************************************************************/
unsigned char
hal_nrf_get_power_mode(void)
{
return (hal_nrf_read_reg(CONFIG) & (1<<PWR_UP)) >> PWR_UP;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rf_channel
* 功 能:获取所使用的RF信道
* 入口参数:无
* 出口参数:无
* 返 回 值:RF信道
********************************************************************/
unsigned char
hal_nrf_get_rf_channel(void)
{
return hal_nrf_read_reg(RF_CH);
}
/*********************************************************************
* 函数名称:hal_nrf_get_output_power
* 功 能:获取所使用的RF TX输出功率
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 -18dBm
* 0x01 -12dBm
* 0x02 -6dBm
* 0x03 0dBm
********************************************************************/
unsigned char
hal_nrf_get_output_power(void)
{
return (hal_nrf_read_reg(RF_SETUP) & ((1<<RF_PWR1)|(1<<RF_PWR0))) >> RF_PWR0;
}
/*********************************************************************
* 函数名称:hal_nrf_get_datarate
* 功 能:获取所使用的无线通信数据速率
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 1Mbps
* 0x01 2Mbps
********************************************************************/
unsigned char
hal_nrf_get_datarate(void)
{
return (hal_nrf_read_reg(RF_SETUP) & (1<<RF_DR)) >> RF_DR;
}
/*********************************************************************
* 函数名称:hal_nrf_rx_fifo_empty
* 功 能:检查RX FIFO是否为空
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE RX FIFO 不空
* TRUE RX FIFO 空
********************************************************************/
bool
hal_nrf_rx_fifo_empty(void)
{
if(hal_nrf_get_rx_data_source()==7)
{
return true;
}
else
{
return false;
}
}
/*********************************************************************
* 函数名称:hal_nrf_rx_fifo_full
* 功 能:检查RX FIFO是否为满
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE RX FIFO 不满
* TRUE RX FIFO 满
********************************************************************/
bool
hal_nrf_rx_fifo_full(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> RX_EMPTY) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_tx_fifo_empty
* 功 能:检查TX FIFO是否为空
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE TX FIFO 不空
* TRUE TX FIFO 空
********************************************************************/
bool
hal_nrf_tx_fifo_empty(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_EMPTY) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_tx_fifo_full
* 功 能:检查TX FIFO是否为满
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE TX FIFO 不满
* TRUE TX FIFO 满
********************************************************************/
bool
hal_nrf_tx_fifo_full(void)
{
return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_FIFO_FULL) & 1);
}
/*********************************************************************
* 函数名称:hal_nrf_get_tx_fifo_status
* 功 能:检查TX FIFO的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 TX FIFO 不空, 也不满
* 0x01 TX FIFO 空
* 0x02 TX FIFO 满
********************************************************************/
unsigned char
hal_nrf_get_tx_fifo_status(void)
{
return ((hal_nrf_read_reg(FIFO_STATUS) &
((1<<TX_FIFO_FULL)|(1<<TX_EMPTY))) >> 4);
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_fifo_status
* 功 能:检查RX FIFO的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:0x00 RX FIFO 不空, 也不满
* 0x01 RX FIFO 空
* 0x02 RX FIFO 满
********************************************************************/
unsigned char
hal_nrf_get_rx_fifo_status(void)
{
return (hal_nrf_read_reg(FIFO_STATUS) & ((1<<RX_FULL)|(1<<RX_EMPTY)));
}
/*********************************************************************
* 函数名称:hal_nrf_get_fifo_status
* 功 能:检查FIFO状态
* 入口参数:无
* 出口参数:无
* 返 回 值:FIFO状态寄存器的值
********************************************************************/
unsigned char
hal_nrf_get_fifo_status(void)
{
return hal_nrf_read_reg(FIFO_STATUS);
}
/*********************************************************************
* 函数名称:hal_nrf_get_transmit_attempts
* 功 能:获取重传尝试的次数和丢包数量
* 入口参数:无
* 出口参数:无
* 返 回 值:重传尝试计数器的值
********************************************************************/
unsigned char
hal_nrf_get_transmit_attempts(void)
{
return hal_nrf_read_reg(OBSERVE_TX) & (BIT_3|BIT_2|BIT_1|BIT_0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_carrier_detect
* 功 能:获取载波检测标志
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE 未检测到载波
* TRUE 检测到载波
********************************************************************/
bool
hal_nrf_get_carrier_detect(void)
{
return hal_nrf_read_reg(CD) & 1;
}
/*********************************************************************
* 函数名称:hal_nrf_write_tx_pload
* 功 能:写数据包的数据载荷部分到RF
* 入口参数:tx_pload 指向存储数据载荷的缓冲区的指针
* length 数据载荷的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_tx_pload(unsigned char *tx_pload, unsigned char length)
{
hal_nrf_write_multibyte_reg(UINT8(HAL_NRF_TX_PLOAD), tx_pload, length);
}
/*********************************************************************
* 函数名称:hal_nrf_setup_dyn_pl
* 功 能:设置接收管道的动态数据负载特性。
* 入口参数:setup 管道特性位掩码
* 例如:bit0设置为1时,管道0使用ACK数据负载。
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_setup_dyn_pl(unsigned char setup)
{
hal_nrf_write_reg(DYNPD, setup & ~0xC0);
}
/*********************************************************************
* 函数名称:hal_nrf_enable_dynamic_pl
* 功 能:使能动态数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_dynamic_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x04));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_dynamic_pl
* 功 能:禁止动态数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_dynamic_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x04));
}
/*********************************************************************
* 函数名称:hal_nrf_enable_ack_pl
* 功 能:使能ACK数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_ack_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x02));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_ack_pl
* 功 能:禁止ACK数据负载特性。
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_ack_pl(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x02));
}
/*********************************************************************
* 函数名称:hal_nrf_enable_dynamic_ack
* 功 能:使能no-ack特性
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_enable_dynamic_ack(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x01));
}
/*********************************************************************
* 函数名称:hal_nrf_disable_dynamic_ack
* 功 能:禁止no-ack特性
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_disable_dynamic_ack(void)
{
hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x01));
}
/*********************************************************************
* 函数名称:hal_nrf_write_ack_pload
* 功 能:给指定管道写入带ACK特性的数据负载。
* 入口参数:pipe 管道号
* tx_pload 指向存储待写入数据的缓冲区的指针
* length 待写入数据的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_ack_pload(unsigned char pipe, unsigned char *tx_pload,
unsigned char length)
{
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WR_ACK_PLOAD | pipe);
while(length--)
{
SW_SPI_RW(*tx_pload++);
}
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_nrf_read_rx_pl_w
* 功 能:读取接收到的ACK数据负载的宽度
* 入口参数:无
* 出口参数:无
* 返 回 值:接收到的ACK数据负载的宽度
********************************************************************/
unsigned char
hal_nrf_read_rx_pl_w()
{
unsigned char temp;
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RD_RX_PLOAD_W);
temp = SW_SPI_RW(0);
HAL_2G4Hz_CSN = 1;
return temp;
}
/*********************************************************************
* 函数名称:hal_nrf_lock_unlock
* 功 能:给nRF24L01+发送ACTIVATE命令
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_lock_unlock()
{
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(LOCK_UNLOCK);
SW_SPI_RW(0x73);
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_nrf_get_rx_data_source
* 功 能:获取当前哪一个管道接收的数据包是当前最高级别数据包
* 入口参数:无
* 出口参数:无
* 返 回 值:管道号
********************************************************************/
unsigned char
hal_nrf_get_rx_data_source(void)
{
return ((hal_nrf_nop() & (BIT_3|BIT_2|BIT_1)) >> 1);
}
/*********************************************************************
* 函数名称:hal_nrf_read_reg
* 功 能:读取nRF24L01+的寄存器内容
* 入口参数:reg 要读取的寄存器
* 出口参数:无
* 返 回 值:读出的寄存器内容
********************************************************************/
unsigned char
hal_nrf_read_reg(unsigned char reg)
{
unsigned char temp;
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(reg);
temp = SW_SPI_RW(0);
HAL_2G4Hz_CSN = 1;
return temp;
}
/*********************************************************************
* 函数名称:hal_nrf_read_rx_pload
* 功 能:读取RX FIFO中可用的最高级别数据载荷
* 入口参数:rx_pload 指向存储读出数据的缓冲区的指针
* 出口参数:无
* 返 回 值:高8位 管道号
* 低8位 数据长度(单位:字节)
* 数据长度为0且管道号为7意味着FIFO为空
********************************************************************/
unsigned short
hal_nrf_read_rx_pload(unsigned char *rx_pload)
{
return hal_nrf_read_multibyte_reg(UINT8(HAL_NRF_RX_PLOAD), rx_pload);
}
/*********************************************************************
* 函数名称:hal_nrf_reuse_tx
* 功 能:设置RF使用最后一次发送的数据载荷作为下一个数据包
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_reuse_tx(void)
{
hal_nrf_write_reg(REUSE_TX_PL, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_get_reuse_tx_status
* 功 能:检查reuse_tx功能的状态
* 入口参数:无
* 出口参数:无
* 返 回 值:FALSE 未激活
* TRUE 激活
********************************************************************/
bool
hal_nrf_get_reuse_tx_status(void)
{
return (bool)((hal_nrf_get_fifo_status() & (1<<TX_REUSE)) >> TX_REUSE);
}
/*********************************************************************
* 函数名称:hal_nrf_flush_rx
* 功 能:清空RX FIFO
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_flush_rx(void)
{
hal_nrf_write_reg(FLUSH_RX, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_flush_tx
* 功 能:清空TX FIFO
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_flush_tx(void)
{
hal_nrf_write_reg(FLUSH_TX, 0);
}
/*********************************************************************
* 函数名称:hal_nrf_set_pll_mode
* 功 能:LOCK或UNLOCK RF PLL
* 入口参数:pll_mode PLL locked: TRUE 或 FALSE
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_pll_mode(hal_nrf_pll_mode_t pll_mode)
{
if(pll_mode == HAL_NRF_PLL_LOCK)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<PLL_LOCK)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<PLL_LOCK)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_pll_mode
* 功 能:获取 RF PLL的当前模式
* 入口参数:无
* 出口参数:无
* 返 回 值:RF PLL的当前模式
********************************************************************/
hal_nrf_pll_mode_t
hal_nrf_get_pll_mode(void)
{
return (hal_nrf_pll_mode_t)((hal_nrf_read_reg(RF_SETUP) &
(1<<PLL_LOCK)) >> PLL_LOCK);
}
/*********************************************************************
* 函数名称:hal_nrf_set_lna_gain
* 功 能:设置RF使用的LNA增益模式
* 入口参数:lna_gain LNA增益模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_set_lna_gain(hal_nrf_lna_mode_t lna_gain)
{
if(lna_gain == HAL_NRF_LNA_HCURR)
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<LNA_HCURR)));
}
else
{
hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<LNA_HCURR)));
}
}
/*********************************************************************
* 函数名称:hal_nrf_get_lna_gain
* 功 能:获取RF当前使用的LNA增益模式
* 入口参数:lna_gain LNA增益模式
* 出口参数:无
* 返 回 值:0 LNA 低电流
* 1 LNA 高电流
********************************************************************/
hal_nrf_lna_mode_t
hal_nrf_get_lna_gain(void)
{
return (hal_nrf_lna_mode_t) ( (hal_nrf_read_reg(RF_SETUP) &
(1<<LNA_HCURR)) >> LNA_HCURR );
}
/*********************************************************************
* 函数名称:hal_nrf_read_multibyte_reg
* 功 能:从nRF24L01+的指定寄存器读取多字节数据
* 入口参数:reg nRF24L01+的指定寄存器
* pbuf 指向存储读出数据的缓冲区的指针
* 出口参数:无
* 返 回 值:高8位:接收数据的管道号(用于hal_nrf_read_rx_pload函数)
* 低8位:读取数据的长度(用于hal_nrf_read_rx_pload 或hal_nrf_get_address函数)
********************************************************************/
unsigned short
hal_nrf_read_multibyte_reg(unsigned char reg, unsigned char *pbuf)
{
unsigned char ctr, length;
switch(reg)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
length = ctr = hal_nrf_get_address_width();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RX_ADDR_P0 + reg);
break;
case HAL_NRF_RX_PLOAD:
if( (reg = hal_nrf_get_rx_data_source()) < 7)
{
length = ctr = hal_nrf_read_rx_pl_w();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(RD_RX_PLOAD);
}
else
{
ctr = length = 0;
}
break;
default:
ctr = length = 0;
break;
}
while(ctr--)
{
*pbuf++ = SW_SPI_RW(0);
}
HAL_2G4Hz_CSN = 1;
return (((unsigned short) reg << 8) | length);
}
/*********************************************************************
* 函数名称:hal_nrf_write_reg
* 功 能:写一个新值到nRF24L01+的指定寄存器
* 入口参数:reg 待写入新值的寄存器
* value 待写入的新值
* 出口参数:无
* 返 回 值:1字节返回值
********************************************************************/
unsigned char
hal_nrf_write_reg(unsigned char reg, unsigned char value)
{
unsigned char retval;
HAL_2G4Hz_CSN = 0;
if(reg < WRITE_REG)
{
retval = SW_SPI_RW(WRITE_REG + reg);
SW_SPI_RW(value);
}
else
{
if(!(reg == FLUSH_TX) && !(reg == FLUSH_RX) && !(reg == REUSE_TX_PL) && !(reg == NOP))
{
retval = SW_SPI_RW(reg);
SW_SPI_RW(value);
}
else
{
retval = SW_SPI_RW(reg);
}
}
HAL_2G4Hz_CSN = 1;
return retval;
}
/*********************************************************************
* 函数名称:hal_nrf_get_address_width
* 功 能:获取nRF24L01+射频使用的地址宽度,包括RX和TX
* 入口参数:无
* 出口参数:无
* 返 回 值:地址宽度(单位:字节)
********************************************************************/
unsigned char
hal_nrf_get_address_width(void)
{
return (hal_nrf_read_reg(SETUP_AW) + 2);
}
/*********************************************************************
* 函数名称:hal_nrf_write_multibyte_reg
* 功 能:写多个字节数据到nRF24L01+的指定寄存器
* 入口参数:reg 待写入数据的寄存器
* pbuf 指向保存待写入数据的缓冲区的指针
* length 待写入数据的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
hal_nrf_write_multibyte_reg(unsigned char reg, unsigned char *pbuf,
unsigned char length)
{
switch(reg)
{
case HAL_NRF_PIPE0:
case HAL_NRF_PIPE1:
case HAL_NRF_TX:
length = hal_nrf_get_address_width();
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WRITE_REG + RX_ADDR_P0 + reg);
break;
case HAL_NRF_TX_PLOAD:
HAL_2G4Hz_CSN = 0;
SW_SPI_RW(WR_TX_PLOAD);
break;
default:
break;
}
while(length--)
{
SW_SPI_RW(*pbuf++);
}
HAL_2G4Hz_CSN = 1;
}
/*********************************************************************
* 函数名称:hal_2G4Hz_Tag_Init
* 功 能:RFID-2.4GHz-Tag硬件抽象层初始化
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 注 意:本函数使能了CC2530的全局中断
********************************************************************/
void hal_2G4Hz_Tag_Init(void)
{
/* 使能CC2530的缓存预取模式 */
PREFETCH_ENABLE();
/* LED相关初始化 */
HAL_2G4Hz_LED1_TURN_OFF();
HAL_2G4Hz_LED1_DDR |= HAL_2G4Hz_LED1_BV;
HAL_2G4Hz_LED2_TURN_OFF();
HAL_2G4Hz_LED2_DDR |= HAL_2G4Hz_LED2_BV;
/* CC2530与nRF24L01+相连引脚初始化 */
HAL_2G4Hz_CSN = 1;
HAL_2G4Hz_CE = 0;
HAL_2G4Hz_MOSI = 0;
HAL_2G4Hz_SCK = 0;
HAL_2G4Hz_CSN_DDR |= HAL_2G4Hz_CSN_BV;
HAL_2G4Hz_CE_DDR |= HAL_2G4Hz_CE_BV;
HAL_2G4Hz_SCK_DDR |= HAL_2G4Hz_SCK_BV;
HAL_2G4Hz_MOSI_DDR |= HAL_2G4Hz_MOSI_BV;
HAL_2G4Hz_MISO_DDR &= ~HAL_2G4Hz_MISO_BV;
HAL_2G4Hz_IRQ_DDR &= ~HAL_2G4Hz_IRQ_BV;
P0INP |= HAL_2G4Hz_BUTTON_BV;
PICTL |= 0x01;
P0IEN |= HAL_2G4Hz_IRQ_BV;
IEN1 |= (1 << 5);
EA = 1;
}
/*********************************************************************
* 函数名称:Radio_Set_Status
* 功 能:更新status全局变量
* 入口参数:new_status 新状态值
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_Set_Status (radio_status_t new_status)
{
status = new_status;
}
/*********************************************************************
* 函数名称:Radio_Get_Status
* 功 能:读取status全局变量
* 入口参数:无
* 出口参数:无
* 返 回 值:RF当前状态标志变量status的当前值
********************************************************************/
radio_status_t
Radio_Get_Status (void)
{
return status;
}
/*********************************************************************
* 函数名称:HAL_2G4Hz_CE_PULSE
* 功 能:脉动nRF24L01+的CE信号至少10us
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
HAL_2G4Hz_CE_PULSE(void)
{
unsigned char count;
count = 40;
HAL_2G4Hz_CE = 1;
while(count--);
HAL_2G4Hz_CE = 0;
}
/*********************************************************************
* 函数名称:Radio_SB_MODE_Init
* 功 能:nRF24L01+的ShockBurst(TM)模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_SB_MODE_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, false);
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_datarate(HAL_NRF_2MBPS);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_ESB_MODE_Init
* 功 能:nRF24L01+的Enhanced ShockBurst(TM)模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_ESB_MODE_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
/* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, true);
/* 使用CRC-16模式 */
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
/* 使能自动重传:重传次数为RF_RETRANSMITS,重传延时为RF_RETRANS_DELAY */
hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
/* 设置为PTX模式 */
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
/* 设置为RTX模式 */
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
/* 设置运行信道为 频率 = 2400 + RF_CHANNEL */
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
/* RF就绪 */
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_ESB_MODE_PL_Init
* 功 能:nRF24L01+的Enhanced ShockBurst(TM) with bidirectional Data模式初始化
* 入口参数:address 设备地址
* operational_mode PTX(Primary TX operation)模式
* RTX(Primary RX operation)模式
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_ESB_MODE_PL_Init (unsigned char *address,
hal_nrf_operation_mode_t operational_mode)
{
/* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
hal_nrf_close_pipe(HAL_NRF_ALL);
hal_nrf_open_pipe(HAL_NRF_PIPE0, true);
hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);
hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
hal_nrf_set_address(HAL_NRF_TX, address);
hal_nrf_set_address(HAL_NRF_PIPE0, address);
/*
以下部分与Radio_ESB_MODE_Init函数不同
使能ACK数据载荷
使能动态数据载荷宽度
使能动态ACK
*/
/****************************************************************************/
/* 使能ACK数据载荷特性 */
hal_nrf_enable_ack_pl();
if(hal_nrf_read_reg(FEATURE) == 0x00 && (hal_nrf_read_reg(DYNPD) == 0x00))
{
hal_nrf_lock_unlock ();
hal_nrf_enable_ack_pl();
}
/* 使能动态数据载荷特性 */
hal_nrf_enable_dynamic_pl();
/* 设置所有接收管道具有动态数据载荷特性 */
hal_nrf_setup_dyn_pl(ALL_PIPES);
/****************************************************************************/
/* 设置为PTX模式 */
if(operational_mode == HAL_NRF_PTX)
{
hal_nrf_set_operation_mode(HAL_NRF_PTX);
}
/* 设置为RTX模式 */
else
{
hal_nrf_set_operation_mode(HAL_NRF_PRX);
hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
}
hal_nrf_set_rf_channel(RF_CHANNEL);
hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
Radio_Set_Status (RF_IDLE);
}
/*********************************************************************
* 函数名称:Radio_Send_Packet
* 功 能:RF发送数据包
* 入口参数:packet 指向保存待发送数据包的缓冲区的指针
* length 待发送数据包的长度(单位:字节)
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_Send_Packet(unsigned char *packet, unsigned char length)
{
/* 加载数据包到RF */
hal_nrf_write_tx_pload(packet, length);
/* RF发送 */
HAL_2G4Hz_CE_PULSE();
/* 更新RF状态变量status 为RF_BUSY */
Radio_Set_Status (RF_BUSY);
}
/*********************************************************************
* 函数名称:Radio_Get_Pload_Byte
* 功 能:byte_index 数据载荷的字节索引
* 入口参数:无
* 出口参数:无
* 返 回 值:数据载荷字节索引所指定的1字节数据
********************************************************************/
unsigned char
Radio_Get_Pload_Byte (unsigned char byte_index)
{
return pload[byte_index];
}
/*********************************************************************
* 函数名称:Radio_IRQ
* 功 能:nRF24L01+的中断处理函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
Radio_IRQ(void)
{
/* 若nRF24L01+触发了CC2530的外部中断 */
if(RADIO_ACTIVITY())
{
hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN);
HAL_2G4Hz_CE = 0;
switch(hal_nrf_get_clear_irq_flags ())
{
/* 达到最大重传次数中断 */
case (1<<HAL_NRF_MAX_RT):
hal_nrf_flush_tx();
Radio_Set_Status (RF_MAX_RT);
break;
/* TX数据发送中断 */
case (1<<HAL_NRF_TX_DS):
Radio_Set_Status (RF_TX_DS);
break;
/* RX数据接收中断 */
case (1<<HAL_NRF_RX_DR):
while (!hal_nrf_rx_fifo_empty ())
{
hal_nrf_read_rx_pload(pload);
}
Radio_Set_Status (RF_RX_DR);
break;
/* 接收到ACK数据载荷中断 */
case ((1<<HAL_NRF_RX_DR)|(1<<HAL_NRF_TX_DS)):
while (!hal_nrf_rx_fifo_empty ())
{
hal_nrf_read_rx_pload(pload);
}
Radio_Set_Status (RF_TX_AP);
break;
default:
break;
}
RESET_RADIO_ACTIVITY();
}
}
/*********************************************************************
* 函数名称:P0INT_ISR
* 功 能:CC2530的P0口中断服务函数
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
#pragma vector=P0INT_VECTOR
__interrupt void P0INT_ISR(void)
{
Radio_IRQ();
}
#endif
/*******************************************************************************
* 文件名称:SYSCLK.c
* 功 能:MCU时钟选择
* 作 者:
* 公 司:
******************************************************************************/
/* 包含头文件 */
/********************************************************************/
#include "SYSCLK.h"
#include "iocc2530.h"
/********************************************************************/
/*********************************************************************
* 函数名称:SystemClockSourceSelect
* 功 能:选择系统时钟源(主时钟源)
* 入口参数:source
* XOSC_32MHz 32MHz晶体振荡器
* RC_16MHz 16MHz RC振荡器
* 出口参数:无
* 返 回 值:无
********************************************************************/
void SystemClockSourceSelect(enum SYSCLK_SRC source)
{
unsigned char osc32k_bm = CLKCONCMD & 0x80;
unsigned char __clkconcmd,__clkconsta;
/*
系统时钟源(主时钟源)选择16MHz RC振荡器,定时器tick设置为16MHz,时钟速度设置为16MHz
CLKCONCMD.OSC32K[b7]不改变 32KHz时钟源选择保持先前设置
CLKCONCMD.OSC[b6] = 1 系统时钟源(主时钟源)选择16MHz RC振荡器
CLKCONCMD.TICKSPD[b5..b3] = 001 定时器tick设置为16MHz
CLKCONCMD.CLKSPD[b2..b0] = 001 时钟速度设置为16MHz
*/
if(source == RC_16MHz)
{ /* CLKCONCMD.OSC32K[b7] */
CLKCONCMD = ((osc32k_bm) | \
/* CLKCONCMD.OSC[b6] = 1 */
(0x01 << 6) | \
/* CLKCONCMD.TICKSPD[b5..b3] = 001 */
(0x01 << 3) | \
/* CLKCONCMD.CLKSPD[b2..b0] = 001 */
(0x01 << 0));
}
/*
系统时钟源(主时钟源)选择32MHz晶体振荡器,定时器tick设置为32MHz,时钟速度设置为32MHz
CLKCONCMD.OSC32K[b7]不改变 32KHz时钟源选择保持先前设置
CLKCONCMD.OSC[b6] = 0 系统时钟源(主时钟源)选择32MHz晶体振荡器
CLKCONCMD.TICKSPD[b5..b3] = 000 定时器tick设置为32MHz
CLKCONCMD.CLKSPD[b2..b0] = 000 时钟速度设置为32MHz
*/
else if(source == XOSC_32MHz)
{
CLKCONCMD = (osc32k_bm /*| (0x00<<6) | (0x00<<3) | (0x00 << 0)*/);
}
/* 等待所选择的系统时钟源(主时钟源)稳定 */
__clkconcmd = CLKCONCMD;
do
{
__clkconsta = CLKCONSTA;
}while(__clkconsta != __clkconcmd);
}
/*******************************************************************************
* 文件名称:UART0.c
* 功 能:CC2530的UART0驱动
* 作 者:
* 公 司:
******************************************************************************/
#if !defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h" // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "UART0.h"
/********************************************************************/
/*********************************************************************
* 函数名称:InitUART0
* 功 能:UART0初始化
* P0.2 RX
* P0.3 TX
* 波特率:115200
* 数据位:8
* 停止位:1
* 奇偶校验:无
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void InitUART0(void)
{
/* 片内外设引脚位置采用上电复位默认值,即PERCFG寄存器采用默认值 */
/*
P0.2 RX
P0.3 TX
P0.4 CT
P0.5 RT
*/
/* UART0相关引脚初始化 */
P0SEL |= ((0x01 << 2) | (0x01 << 3));
/* P0口外设优先级采用上电复位默认值,即P2DIR寄存器采用默认值 */
/*
第一优先级:USART0
第二优先级:USART1
第三优先级:Timer1
*/
/* UART0波特率设置 */
/* 波特率:115200
当使用32MHz 晶体振荡器作为系统时钟时,要获得115200波特率需要如下设置:
UxBAUD.BAUD_M = 216
UxGCR.BAUD_E = 11
该设置误差为0.03%
*/
U0BAUD = 216;
U0GCR = 11;
/* USART模式选择 */
U0CSR |= 0x80; // UART模式
/* UART0配置 */
U0UCR |= 0x80; // 进行USART清除
/*
以下配置参数采用上电复位默认值:
硬件流控:无
奇偶校验位(第9位):奇校验
第9位数据使能:否
奇偶校验使能:否
停止位:1个
停止位电平:高电平
起始位电平:低电平
*/
/* 用于发送的位顺序采用上电复位默认值,即U0GCR寄存器采用上电复位默认值 */
/* LSB先发送 */
UTX0IF = 0; // 清零UART0 TX中断标志
}
/*********************************************************************
* 函数名称:UART0SendByte
* 功 能:UART0发送一个字节
* 入口参数:c
* 出口参数:无
* 返 回 值:无
********************************************************************/
void UART0SendByte(unsigned char c)
{
U0DBUF = c; // 将要发送的1字节数据写入U0DBUF
while (!UTX0IF); // 等待TX中断标志,即U0DBUF就绪
UTX0IF = 0; // 清零TX中断标志
}
/*********************************************************************
* 函数名称:UART0SendString
* 功 能:UART0发送一个字符串
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void UART0SendString(unsigned char *str, unsigned char longStr)
{
while( longStr > 0 )
{
// if(*str == '\0') break; // 遇到结束符,退出
UART0SendByte(*str++); // 发送一字节
longStr--;
}
}
/*********************************************************************
* 函数名称:UART0Send_BackSpace
* 功 能:UART0发送退格键
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void UART0Send_BackSpace(void)
{
UART0SendByte('\b');
UART0SendByte(' ');
UART0SendByte('\b');
}
/*********************************************************************
* 函数名称:UART0Send_Space
* 功 能:UART0发送空格键
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void UART0Send_Space(void)
{
UART0SendByte(' ');
}
/*********************************************************************
* 函数名称:UART0Send_Crlf
* 功 能:UART0发送换行键
* 入口参数:无
* 出口参数:无
* 返 回 值:无
********************************************************************/
void UART0Send_Crlf(void)
{
UART0SendByte('\r');
UART0SendByte('\n');
}
/*********************************************************************
* 函数名称:Nibble2Ascii
* 功 能:将4位二进制比特转换为ASCII HEX字节
* 入口参数:anibble 4位二进制比特
* 出口参数:无
* 返 回 值:ASCII HEX字节
********************************************************************/
static unsigned char
Nibble2Ascii(unsigned char anibble)
{
unsigned char AsciiOut = anibble;
if(anibble > 9) AsciiOut = AsciiOut + 0x07;
AsciiOut = AsciiOut + 0x30;
return(AsciiOut);
}
/*********************************************************************
* 函数名称:UART0Send_2HEX
* 功 能:将1个字节的数据按两个十六进制字符方式输出
* 入口参数:abyte 字节数据
* 出口参数:无
* 返 回 值:无
********************************************************************/
void
UART0Send_2HEX(unsigned char abyte)
{
unsigned char temp1, temp2;
temp1 = (abyte >> 4) & 0x0F;
temp2 = Nibble2Ascii(temp1);
UART0SendByte(temp2);
temp1 = abyte & 0x0F;
temp2 = Nibble2Ascii(temp1);
UART0SendByte(temp2);
}
#endif