最近在用nRF2401,本来也想偷个懒,上网上下一个程序随便改改了事,但找了好长时间发现几乎都是一个版本,而且并不是那么好用。一个好的驱动程序应该是很好移植的,这就要求在驱动程序中尽量少用全局的变量,把与体系相关的部分放在头文件中,当跨平台移植时,只需改改头文件即可,同时也要把相关的参数配置通过宏定义的形式列出来,用户只需简单的修改宏定义就可以满足自己的要求。本驱动程序希望能达到这个目的,由于水平有限,程序中的不足在所难免,希望大家指正。本程序在MSP430F169上通过测试。
/************************************************************************
** 文件名:nrf2401.h
** 功 能:nRF2401驱动程序头文件
*************************************************************************/
#ifndef NRF2401_H
#define NRF2401_H
#include <msp430x16x.h>
/*
** 接口说明:
** CS:P4.6, CE:P5.2, PWR_UP:P5.3, DR1:P4.5, CLK1:P4.4
** DATA:P4.3, DR2:P5.1, CLK2:P5.0, DOUT2:P4.7
*/
#define CS BIT6
#define CE BIT2
#define PWR_UP BIT3
#define DR1 BIT5
#define CLK1 BIT4
#define DATA BIT3
#define DR2 BIT1
#define CLK2 BIT0
#define DOUT2 BIT7
#define CS_H P4OUT |= CS
#define CS_L P4OUT &= ~CS
#define CE_H P5OUT |= CE
#define CE_L P5OUT &= ~CE
#define PWR_UP_H P5OUT |= PWR_UP
#define PWR_UP_L P5OUT &= ~PWR_UP
#define CLK1_H P4OUT |= CLK1
#define CLK1_L P4OUT &= ~CLK1
#define DATA_OUT P4DIR |= DATA
#define DATA_OUT_H P4OUT |= DATA
#define DATA_OUT_L P4OUT &= ~DATA
#define DR1_IN P4DIR &= ~DR1
#define DR1_IN_H P4IN & DR1 // DR1输入是否为高电平
#define DATA_IN P4DIR &= ~DATA
#define DATA_IN_H P4IN & DATA // DATA输入是否为高电平
#define CLK2_H P5OUT |= CLK2
#define CLK2_L P5OUT &= ~CLK2
#define DOUT2_IN P4DIR &= ~DOUT2
#define DOUT2_IN_H P4IN & DOUT2 // DOUT2输入是否为高电平
#define DR2_IN P5DIR &= ~DR2
#define DR2_IN_H P5IN & DR2 // DR2输入是否为高电平
/*
** 相应端口设为IO模式
*/
static inline void IO_MODE()
{
P4SEL &= ~(DATA + CLK1 + DR1 + CS + DOUT2);
P5SEL &= ~(CLK2 + DR2 + CE + PWR_UP);
}
/*
** IO端口方向初始化
*/
static inline void IO_DIR_INIT()
{
P4DIR |= (DATA + CLK1 + CS);
DR1_IN;
DOUT2_IN;
P5DIR |= (CLK2 + CE + PWR_UP);
DR2_IN;
}
/*
** IO初始化
*/
static inline void IO_Init(void)
{
IO_MODE();
IO_DIR_INIT();
}
#define IO_INIT() IO_Init()
/*
** nRF2401配置宏,所有的参数都在这里设置
*/
#define DATA2_W 0 // Length of data payload section RX channel 2
#define DATA1_W 32 // Length of data payload section RX channel 1
// 本驱动程序只支持8的整数倍的数据长度
// DATAx_W(bits) = 256 - ADDR_W - CRC
#define ADDR2_0 0x1f // Up to 5 byte address for RX channel 2
#define ADDR2_1 0x3f
#define ADDR2_2 0x00
#define ADDR2_3 0x00
#define ADDR2_4 0x00
#define ADDR1_0 0x26 // Up to 5 byte address for RX channel 1
#define ADDR1_1 0x26
#define ADDR1_2 0x00
#define ADDR1_3 0x00
#define ADDR1_4 0x00
#define ADDR_W 16 // Number of address bits (both RX channels)
// 本驱动程序只支持8、16、32、40地址位数
#define CRC_L 0 // 8 or 16 bit CRC Logic 0: 8 bit CRC Logic 1: 16 bit CRC
#define CRC_EN 1 // Enable on-chip CRC generation/checking
// Logic 0: On-chip CRC generation/checking disabled
// Logic 1: On-chip CRC generation/checking enabled
#define RX2_EN 0 // Enable two channel receive mode
// Logic 0: One channel receive
// Logic 1: Two channels receive
//receive channel 2 is always 8 channels (8 MHz) above receive channel 1
#define CM 1 // Communication mode (Direct or ShockBurst)
// Logic 0: nRF2401A operates in direct mode.
// Logic 1: nRF2401A operates in ShockBurst mode
#define RFDR_SB 0 // RF data rate (1Mbps requires 16MHz crystal)
// Logic 0: 250 kbps Logic 1: 1 Mbps
#define XO_F 3 // Crystal frequency 0:4M 1:8M 2:12M 3:16M 4:20M
#define RF_PWR 3 // RF output power(dbm) 0:-20 1:-10 2:-5 3:0
#define RF_CH 60 // Frequency channel(7bit,0 - 127)
// ChannelRf=2400M + RF_CH * 1M
#define RXEN 0 // RX or TX operation
// Logic 0: transmit mode Logic 1: receive mode
/*
** Enter Active modes
*/
extern void RF_Active(void);
/*
** Enter Configuration modes
*/
extern void RF_Config(void);
/*
** Enter Stand by modes
*/
extern void RF_Standby(void);
/*
** Power down modes
** Note:When the nRF2401A is in power down it must always settle
** in stand by mode for 3ms before it can enter configuration or one
** of the active modes.
*/
extern void RF_PowerDown(void);
/*
** nRF2401初始化
*/
extern void RF_Init(void);
/*
** 向指定channel指定地址发送指定数据
** channel:接收端的频道(0 - 127)
** addr: 接收端的地址的指针
** alength:地址长度(byte)
** sendbuffer:要发送数据的首指针
** dlength:数据长度
*/
extern void RF_SendData(unsigned char channel, \
unsigned char *addr, \
unsigned char alength, \
unsigned char *sendbuffer,\
unsigned char dlength);
/*
** 进入接收模式
*/
extern void RF_RXMode(void);
/*
** 接收数据
** receivebuffer:接收缓冲区指针
** channel:接收的通道
** 返回接收到得字节数,错误返回-1
*/
extern int RF_ReceiveData(unsigned char *receivebuffer, unsigned char channel);
#endif