这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» nRF2401的C51驱动程序[已经调试通过]

共2条 1/1 1 跳转至

nRF2401的C51驱动程序[已经调试通过]

菜鸟
2009-03-25 15:54:20 打赏

nRF2401的C51驱动程序[已经调试通过]

Microcontrol CODE


Desc Demo App for RF2401 Module
Vender httpwww.newmsg.com
Date 2007-3-12
Update 2007-9-8

这是我购买在nRF2401时从开发商中得到的代码。我已经验证过。
供大家学习用,只要修改下代码就可以应用到其他的单片机。
这个程序是一个半双工的通信模式.


#include reg51.h
常量定义
#define uchar unsigned char
#define uint unsigned int

#define BYTE_BIT0 0x01
#define BYTE_BIT1 0x02
#define BYTE_BIT2 0x04
#define BYTE_BIT3 0x08
#define BYTE_BIT4 0x10
#define BYTE_BIT5 0x20
#define BYTE_BIT6 0x40
#define BYTE_BIT7 0x80

RF2401_Pins 对应引脚 , 具体细节请参考相关电路图 NewMsg_RFDemo2401.SchDoc(用PortelDXP打开)
sbit PWR_UP = P1^6;
sbit CE = P1^2;
sbit DR2 = P3^5; 暂时没有用到
sbit CLK2 = P3^4;
sbit OUT2 = P3^3;
sbit CS = P1^1;
sbit DR1 = P1^0;
sbit CLK1 = P3^7;
sbit DATA = P3^3;

sbit LED0 = P3^4;
sbit LED1 = P3^5;
sbit KEY0 = P3^0;
sbit KEY1 = P3^1;


RF2401 Configuration
保存2401的配置信息

=====RF-Configuration-Register 配置信息=====
芯片测试用,无需修改
#define TEST_2 0x8E MSB D143~D136
#define TEST_1 0x08 D135~D128
#define TEST_0 0x1C D127~D120

注意 DATAx_W + ADDRx_W + CRC 的值必须小于256 ! 单个数据包的大小必须小于32字节(256位)
#define DATA2_W 0x10 2字节 频道2 数据长度(单位Bit)
#define DATA1_W 0xE0 28字节 频道1 数据长度(单位Bit)

0xE0 = 224
16bit Address + 224bit(28byte)Data + 16bit CRC = 256bit

注意2401忽略ADDR中超过ADDR_W设定宽度的那些位,同时地址不能全部设置为0
频道2 接收地址(当前模块地址)
#define ADDR2_4 0x00
#define ADDR2_3 0x1c
#define ADDR2_2 0xcc
#define ADDR2_1 0xcc
#define ADDR2_0 0xcc
频道1 接收地址
#define ADDR1_4 0x00
#define ADDR1_3 0xcc
#define ADDR1_2 0xcc
#define ADDR1_1 0xcc
#define ADDR1_0 0xcc

#define ADDR_W 0x10 2字节 接收地址宽度(单位Bit)
#define CRC_L 0x1 CRC模式 08位 116
#define CRC_EN 0x1 CRC校验启用

#define RX2_EN 0x0 双频道功能启用
#define CM 0x1 0Direct mode 1ShockBurst mode
#define RFDR_SB 0x0 0250kbps 11Mbps
#define XO_F 0x3 16M nRF2401晶振频率
#define RF_PWR 0x3 信号发射功率

#define RF_CH 0x2 Channel RF 频率
#define RXEN 0x0DEF_RXEN 0Tx 1Rx
程序会重新设置此项参数

-----------------------------------------------------------
将设置信息组合成每个字节的数据信息,此区域无需修改
#define RFConfig_Byte0 TEST_2
#define RFConfig_Byte1 TEST_1
#define RFConfig_Byte2 TEST_0
#define RFConfig_Byte3 DATA2_W
#define RFConfig_Byte4 DATA1_W
#define RFConfig_Byte5 ADDR2_4
#define RFConfig_Byte6 ADDR2_3
#define RFConfig_Byte7 ADDR2_2
#define RFConfig_Byte8 ADDR2_1
#define RFConfig_Byte9 ADDR2_0
#define RFConfig_Byte10 ADDR1_4
#define RFConfig_Byte11 ADDR1_3
#define RFConfig_Byte12 ADDR1_2
#define RFConfig_Byte13 ADDR1_1
#define RFConfig_Byte14 ADDR1_0
#define RFConfig_Byte15 (ADDR_W2 CRC_L1 CRC_EN)
#define RFConfig_Byte16 (RX2_EN7 CM6 RFDR_SB5 XO_F 2 RF_PWR)
#define RFConfig_Byte17 (RF_CH1 RXEN)

------------------------------------------------------------
通过宏定义将18字节的寄存器参数按照各个功能分解,以便于参数的调整
unsigned char code nRF2401_Conf[18] ={
RFConfig_Byte0,
RFConfig_Byte1,
RFConfig_Byte2,
RFConfig_Byte3,
RFConfig_Byte4,
RFConfig_Byte5,
RFConfig_Byte6,
RFConfig_Byte7,
RFConfig_Byte8,
RFConfig_Byte9,
RFConfig_Byte10,
RFConfig_Byte11,
RFConfig_Byte12,
RFConfig_Byte13,
RFConfig_Byte14,
RFConfig_Byte15,
RFConfig_Byte16,
RFConfig_Byte17
};

------------------------------------------------------------

nRF2401 TxRx functions

void Delay100(void);
void Config2401(void); 配置2401,写入初始化设置
void SetTxMode(void); 设置为发送模式
void SetRxMode(void); 设置为接收模式
void nRF2401_TxPacket(unsigned char TxBuf[]);
发送TxBuf[]内的数据 长度由 DATA1_W 决定
unsigned char nRF2401_RxPacket(unsigned char RxBuf);
检查是否有数据需要接受 如果有,则保存至RxBuf[]
返回值 0没有接收到数据 1接收到数据

16M晶振 600us左右
void Delay100(void)
{
unsigned int i;
for(i=0;i100;i++);
}

void Delay(uchar n)
{
uint i;
while(n--)
for(i=0;i80;i++);
}

bdata unsigned char DATA_BUF;
#define DATA7 ((DATA_BUF & BYTE_BIT7) != 0)
#define DATA0 ((DATA_BUF & BYTE_BIT0) != 0)

2401数据传输接口
详细内容参见2401手册Configuration mode timing章节

unsigned char Spi_ByteRead(void)
{
unsigned char i = 0;
for (i=0; i8; i++)
{
DATA_BUF = DATA_BUF 1;
CLK1 = 1;
DATA = 1; 设置为输入状态
if (DATA) 读取最高位,保存至最末尾,通过左移位完成整个字节
{
DATA_BUF = BYTE_BIT0;
}
else
{
DATA_BUF &= ~BYTE_BIT0;
}
CLK1 = 0;
}

return DATA_BUF;
}

void Spi_ByteWrite(unsigned char send)
{
unsigned char i;

DATA_BUF = send;

CLK1 = 0;

for (i=0; i8; i++)
{

if (DATA7) 总是发送最高位
{
DATA = 1;
}
else
{
DATA = 0;
}
CLK1 = 1;
DATA_BUF = DATA_BUF 1;
CLK1 = 0;
}
}

RF2401配置寄存器的写入方式
NOTE.
On the falling edge of CS, the nRF2401A updates the number of bits actually shifted
in during the last configuration.
Ex
If the nRF2401A is to be configured for 2 channel RX in ShockBurst., a total of 120
bits must be shifted in during the first configuration after VDD is applied.
Once the wanted protocol, modus and RF channel are set, only one bit (RXEN) is
shifted in to switch between RX and TX.

void Config2401(void)
{
unsigned int i = 0;
unsigned char variablel;

RF2401进入配置方式
CS = 0;
CE = 0;
PWR_UP = 1; 上电

for(i=0; i20; i++)
{
Delay100();
}

CS = 1;
DATA = 0;
CLK1 = 0;

Delay100();-----

for(i=0; i20; i++)
{
Delay100();
}

PWR_DWN - Configuration_mode Delay_3ms

for(i=0; i18; i++)
{
variablel = nRF2401_Conf[I];
Spi_ByteWrite(variablel);
}

Delay100(); configuration mode - stand by mode

CS = 0; CS置低使配置有效
Delay100();
}

void SetTxMode(void)
{
设置为配置模式
PWR_UP = 1;
CE = 0;
CS = 1;

Delay100();

配置寄存器0字节RXEN 设置为0发送模式
DATA = 0;
CLK1=1;
CLK1=0;

设置为Activemodes(Tx)
CS=0;
CE=1;
Delay100();
}

void SetRxMode(void)
{
Delay100();
设置为配置模式
PWR_UP = 1;
CE=0;
CS=1;
Delay100(); ----
配置寄存器0字节RXEN 设置为1接收模式
DATA = 1;
CLK1 = 1;
CLK1 = 0;

设置为Activemodes(Rx)
CS=0;
CE=1;
Delay100();
}

接收方通道硬件地址
unsigned char TxAddress[]={0xcc,0xcc,0xcc,0xcc};

nRF2401数据发送函数定义如下:
void RF2401_TxPacket(unsigned char TxBuf[])
{
int i;
unsigned char variable2;
CE=1;
Delay100();
for(i=0;i (ADDR_W8);i++) 写入接收地址(按字节对齐)
{
variable2=TxAddress[I];
Spi_ByteWrite(variable2);
}

for(i=0;i(DATA1_W8);i++) 写入需要发送的数据(按字节对齐)
{
variable2=TxBuf[I];
Spi_ByteWrite(variable2);
}

CE=0; CE置低使发送有效

Delay100(); 时钟信号高电平保持
Delay100(); 时钟信号高电平保持
Delay100(); 时钟信号高电平保持
Delay100(); 时钟信号高电平保持
}


接收数据函数
返回 0没有数据接收
1接收到数据
unsigned char RF2401_RxPacket(unsigned char RxBuf)
{
unsigned int i;

DR1=1;

if(DR1)
{
for (i=0; iDATA1_W8; i++)
{
RxBuf = Spi_ByteRead();
RxBuf++;
}
return 1;
}
return 0;
}





unsigned char TxRxBuf[32];
void main(void)
{
unsigned int i = 0;
unsigned int j = 0;
unsigned int led0_count = 0;
unsigned int led1_count = 0;


Config2401();
Delay100();

TxRxBuf[0] = 1;
TxRxBuf[DATA1_W8 - 1] = 1;

SetTxMode(); Set Tx Mode

RF2401_TxPacket(TxRxBuf); Transmit Tx buffer data

LED0 = 0;
LED1 = 0;

Delay(500); delay for led light

LED0 = 1;
LED1 = 1; led close
TxRxBuf[0] = 0xff;
TxRxBuf[DATA1_W8 - 1] = 0xff;
SetRxMode(); Set RF2401 in Rx mode
while(1)
{
for(i=0;i30;i++) for(j=0;j30;j++);
if (RF2401_RxPacket(TxRxBuf) == 1) 返回1 表明有数据包接收到
{
if (TxRxBuf[0]==1)
{
led0_count=15;
}
if (TxRxBuf[DATA1_W8 - 1]==1)
{
led1_count=15;
}
}
TxRxBuf[0]=0;
TxRxBuf[DATA1_W8 - 1]=0;
按键检测
if (KEY0==0)
{
TxRxBuf[0] = 1;
led0_count=15;
while( KEY0==0);
}
if (KEY1==0)
{
TxRxBuf[DATA1_W8 - 1] = 1;
led1_count=15;
while( KEY1==0);
}
if (TxRxBuf[0]==1 TxRxBuf[DATA1_W8 - 1]==1)
{
SetTxMode(); 设置为发射模式
RF2401_TxPacket(TxRxBuf); 发送数据
SetRxMode();
}
TxRxBuf[0]=0;
TxRxBuf[DATA1_W8 - 1]=0;

LED显示延时
if (led0_count0)
{
led0_count--;
LED0 = 0;
}
else LED0 = 1;
if (led1_count0)
{
led1_count--;
LED1 = 0;
}
else LED1 = 1;

}end_while(1);
}




关键词: nRF2401 驱动程序 已经 调试 通过 RF2

高工
2009-03-25 17:04:58 打赏
2楼

我以前用的nRF2401给的也是这个例程。我后来改到自己的项目中了。当初花了好多时间看完了几十页的英文Datasheet。
nRF2401是单工的,可以分时复用做成半双工的,但在收发状态切换时有点麻烦。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]