|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.0 C+ Z' t% h: F9 _ |
网上看到一个帖子的程序说是将收发两端分开调试 7 Y9 B: z) c4 w' k2 K. r
单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。" B/ H. y0 a7 D: }+ w
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
* R3 _- t* c1 Y SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0" X( b' G9 j" e, S' z" U
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发
) q% m, z7 P: _! M& g8 `4 x- S/ k& V: A8 \
而后程序如下:5 }" b* p+ d% Z) e" ]" v
. g; O; [0 |: E4 H0 F6 @/ m
#include <reg52.h>
. r* h, \* L, \( W" Y#include <intrins.h> & g$ d) x: Y0 p
typedef unsigned char uchar;
" f" A! n8 q# _* J+ M$ l% O- v( ytypedef unsigned char uint;
; y' i8 s/ ^0 J) T, b//****************************************IO端口定义***************************************
6 R2 S& a g0 J+ ]0 M
& m; S0 q9 ~( ~; X' {: |1 @4 @/ t/ Lsbit MISO =P2^0;
+ `- _* s7 q$ L4 m( a4 Wsbit MOSI =P2^4;+ E! G- n% [1 o. k" Q, E
sbit SCK =P2^1;# P/ H9 O+ ^$ }/ D8 a& w$ G
sbit CE =P2^2;
8 L4 k- U" Z! s+ B8 E0 d% K. asbit CSN =P3^3;" \0 E( t' [5 O9 A9 o5 m
sbit IRQ =P2^5;
% B# N' l, x1 y8 c1 V+ ^3 Gsbit LED = P0^0;
n" Q. v7 P2 d+ K2 A& f8 P1 h$ ?! Z( r: U5 @- T+ s9 Y: V+ b
//*********************************************NRF24L01************************************* , R9 O7 D. i) I) Q: q
#define TX_ADR_WIDTH 5 // 5 uints TX address width
; ^9 x+ Q6 R( |#define RX_ADR_WIDTH 5 // 5 uints RX address width
0 a' n2 U2 z7 M#define TX_PLOAD_WIDTH 20 // 20 uints TX payload : f! x$ t; C" U6 Z3 x% s
#define RX_PLOAD_WIDTH 20 // 20 uints TX payload
1 X! A" n' z4 K v* Z3 x+ r" H( K1 O8 K; m7 ~5 z6 X
//***************************************NRF24L01寄存器指令******************************************************* 0 O3 B) k6 j" s) _
#define READ_REG 0x00 // 读寄存器指令
0 o1 G* D. k, Y$ x. c$ o5 ^#define WRITE_REG 0x20 // 写寄存器指令 : G, P) O8 R8 T! R8 o1 X
#define RD_RX_PLOAD 0x61 // 读取接收数据指令 7 g3 X0 d+ N1 N) q
#define WR_TX_PLOAD 0xA0 // 写待发数据指令 0 S6 x% V& ^. V" H$ @3 j
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 1 y$ z. m* s. w2 W' e
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 7 b8 u( r4 B1 u! P
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
$ L4 }* O0 v# F8 \#define NOP 0xFF // 保留
* G, f: S5 d$ t( |7 F; w! `//*************************************SPI(nRF24L01)寄存器地址**************************************************** : Q/ R3 l% g' l4 C# a/ @ N4 v) z
#define CONFIG 0x00 // 配置收发状态,crc校验模式以及收发状态响应方式
" g( h! w' M" e2 Q#define EN_AA 0x01 // 自动应答功能设置 + t+ [' W+ j- G$ O, E) i0 J
#define EN_RXADDR 0x02 // 可用信道设置 # k* k; \+ x0 ]$ F
#define SETUP_AW 0x03 // 收发地址宽度设置 - ]- j3 o4 ^; u; W
#define SETUP_RETR 0x04 // 自动重发功能设置 4 s/ o2 X4 T) U# _$ V6 w
#define RF_CH 0x05 // 工作频率设置
' |9 \. \8 p# o9 y" C% }9 R#define RF_SETUP 0x06 // 发射速率、功耗功能设置
0 d9 o8 h1 N6 a) T#define STATUS 0x07 // 状态寄存器 / _ {, @4 `7 v! ]( C2 L
#define OBSERVE_TX 0x08 // 发送监测功能
$ d2 E7 c& b x#define CD 0x09 // 地址检测
/ ~! j, e. f! |2 P% P8 L1 c# k#define RX_ADDR_P0 0x0A // 频道0接收数据地址
4 |1 Z/ o; w& R- W, J* @#define RX_ADDR_P1 0x0B // 频道1接收数据地址
& z# {3 R3 x+ j4 A; W" K- N#define RX_ADDR_P2 0x0C // 频道2接收数据地址 1 K L0 S$ D$ E6 a1 j+ l9 C
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
: l5 h6 @; }$ G* ]#define RX_ADDR_P4 0x0E // 频道4接收数据地址
9 Y& s2 r2 |0 i0 T: S#define RX_ADDR_P5 0x0F // 频道5接收数据地址
% m/ Q$ n2 _. Z J! l) T _1 [#define TX_ADDR 0x10 // 发送地址寄存器
0 m' O0 l; v3 t0 c/ K& g+ X#define RX_PW_P0 0x11 // 接收频道0接收数据长度 / ~( y; A$ M; U2 |( F
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
9 z2 d) o4 H9 {) y- }, @+ L- ~#define RX_PW_P2 0x13 // 接收频道0接收数据长度
& V( W) z. c/ o0 I( D2 K8 S#define RX_PW_P3 0x14 // 接收频道0接收数据长度
) h) `. J8 T- O6 A2 a#define RX_PW_P4 0x15 // 接收频道0接收数据长度 1 \( |8 M% }. d1 Q y
#define RX_PW_P5 0x16 // 接收频道0接收数据长度 5 U" ^+ [* ^& d
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
5 T& p+ o4 \; U3 o X. _3 A ^1 W- C//**************************************************************************************
2 C+ L5 W' c0 |0 i; o7 cvoid Delay(unsigned int x); 7 k- j8 F! R1 \) ~4 ^4 f# I
void InerDelay_us(unsigned char n); 6 T+ I+ V; O, \' V' F) F
void Init_NRF24L01(void); ; J k* ^, P( w! S8 m
uint SPI_RW(uint uchar); : P5 p( v% s+ i6 D' q9 @( S8 a+ b# @
uchar SPI_Read(uchar reg);
- y( e9 B5 W# N7 x/ {0 D0 [# A. {void SetRX_Mode(void);
1 k( B, R# L! c! ?5 huint SPI_RW_Reg(uchar reg, uchar value);
. u9 C# A) w7 O u" q+ Euint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); % @2 L/ C2 g2 ~& U( V9 ~
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); - w( x& i7 b8 q; N
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf); : U* l$ s+ u* g8 A W
' C1 ~# m) Y; X! D//******************************************************************************************
5 j% W& F) K5 A9 k# `uint bdata sta; //状态标志 % R \5 [7 B6 R6 L
sbit RX_DR =sta^6;
* [" O& d# f9 d" r# \sbit TX_DS =sta^5;
, @' P" H1 S9 o% G$ @" j7 I9 W* ^sbit MAX_RT =sta^4;
" r- J2 X- V/ z! {( p5 J& s. S8 v" e! |: Y& Q
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址
8 p2 A* g% C/ V+ M/******************************************************************************************
9 m8 F' \) b5 H7 C! G/*延时函数 " j% C* ~: b. n& I
/******************************************************************************************/
9 c% E$ ]" o5 _! g- S4 Ovoid InerDelay_us(unsigned char n) 2 _7 N0 e% m$ P" ]# F: L
{ $ s' n3 p9 I# m# g3 G
for(;n>0;n--)
# s$ R" _5 j% [- C* D {+ Z$ l3 k c' h( j9 N9 G7 t
_nop_();5 |% {/ R5 d1 e5 W+ M
}
$ P7 |, X! Y6 ~# ~# \}
8 N3 u4 v% e" J: {$ Y% o# @1 a. v3 u" T
//*****************************************长延时***************************************** 7 M& G" h5 s3 N/ c$ s8 J
void Delay(unsigned int x)
G/ c% @1 }' K. f# x; |" |; u{
# j' v* [9 [! @/ ?8 I7 M unsigned int i,j;
, F& `8 [( t P! X0 N S for(i=x; i>0; i--)
% v1 ^4 U9 @% B8 Z {/ Q, q V/ j+ r7 F4 f8 L# j
for(j=110; j>0; j--);
( ~3 \( y/ U. Y6 W J }+ _5 j% n9 c m# X' X3 ?$ u
}: x+ E8 I6 {- B/ u
& Y% S* ?* v& \" L* ?) t6 ?
/**************************************************************************************** % |2 Q" I; c- Q( S# v, r
/*NRF24L01初始化 7 l7 N6 B4 W# n1 Y
//***************************************************************************************/
9 s1 p8 p2 z( x; T+ D& R% Z/ gvoid Init_NRF24L01(void)
/ w z9 t9 W7 ]# y) b$ L+ l$ {5 C{ 1 L8 |$ P2 |. L F; D5 e* f
InerDelay_us(100); ) O# k) `4 H; u
CE=0;
( [: s# u) m1 G! E CSN=1; * S) S0 ?/ t/ v* p' v4 m" T2 d! F
SCK=0;
2 ?6 Z) f1 M4 ~ IRQ=1; 3 v7 o o1 {# g4 x- [
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址
" |2 n) j7 T* Q0 J+ ? SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址 ( `) K9 T7 v& J; v
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1
" _% q% V2 `; F- a- I, B) W' |- p# x0 c7 r* ] SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2. ]( e5 x" M8 ^
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点% |0 N/ ?2 v+ [" A z8 T" r& @+ A
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
9 D/ v9 b) [" E SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节 / \. p e# E; t2 I x5 l
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB _( m* S5 X5 b7 l* M) H
}
7 `8 b! i7 K8 q$ F# j( ]* o" B* ?6 N0 Q9 T* V
/**************************************************************************************************** 9 ^6 x/ o# E+ D, s7 F7 @
/*函数:uint SPI_RW(uint uchar)
" H5 N% w# Z& l4 t/*功能:NRF24L01的SPI写时序 ) j( ?: Z: f3 G8 |+ Y: J
/****************************************************************************************************/
5 W6 {8 E" l+ j2 M1 V* L) ~! v4 cuint SPI_RW(uint uuchar)
4 u: L8 Q; ?, V3 R$ V6 @2 \{ , `' V& @/ b% E ]
uint bit_ctr;
$ o! n F3 k2 x; y7 ~2 X% t2 v& y for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
3 b0 i- m3 ^0 |- ?- S r- ` { # r$ A1 h* O1 t7 s
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI
2 `' O2 f1 C6 H G0 ?5 ]2 b uuchar = (uuchar << 1); // shift next bit into MSB.. 4 V" w2 w3 _; |; L( v4 Q
SCK = 1; // Set SCK high..
8 g! `+ N7 t# g6 z uuchar |= MISO; // capture current MISO bit - }- S$ C, w! f% k1 d8 ]: {
SCK = 0; // ..then set SCK low again * N, z6 D% E- r% z( u( q j
}
/ t) p& j( x( B. J return(uuchar); // return read uchar : y- j3 U6 J' i3 v: `
}
. i8 @/ e& W( a! D$ G5 ]4 J
# M. f7 F5 }2 [2 ~! w1 J5 V/**************************************************************************************************** # b% {4 C' u. _- s
/*函数:uchar SPI_Read(uchar reg) ' B ]7 R+ J) q( _+ H. Q
/*功能:NRF24L01的SPI时序
& v0 ? o" W2 u0 C3 U/****************************************************************************************************/
3 H- e& E# |- e0 Z4 Kuchar SPI_Read(uchar reg)
. }3 d% w" d& ^- h3 I g{ & |- p# O0 n; {5 V" k4 A3 L
uchar reg_val; # c2 Q( J, ~* |" L
( Y3 F/ a8 M% ~5 u CSN = 0; // CSN low, initialize SPI communication...
u# b1 |7 L- G4 E) _, @2 g SPI_RW(reg); // Select register to read from.. 4 \$ z9 E {# k
reg_val = SPI_RW(0); // ..then read registervalue % K( d O4 n' B$ N6 A7 O
CSN = 1; // CSN high, terminate SPI communication / G0 D6 ~1 g* g# e% q
& X7 p' ?* J% w5 {' h. F
return(reg_val); // return register value 1 H/ j4 t8 K7 x4 [
} + ~% Y8 N7 \9 U2 d. W$ h* `' H$ X
& s# z8 H) f! y
/****************************************************************************************************/ 9 }) P f3 a* g
/*功能:NRF24L01读写寄存器函数
1 f) n/ Y% `; ]( X/ l Z/****************************************************************************************************/ 9 ~% t% k& Q6 e- o
uint SPI_RW_Reg(uchar reg, uchar value) & H- P' O+ i; j( P
{
2 @1 A/ }- ]! ~7 Y uint status;
3 m" e5 Y( E. {, ^- ]& D: R4 _
1 N l4 M1 N. I- V6 V CSN = 0; // CSN low, init SPI transaction 6 c8 J8 N! `2 W9 |' r; L
status = SPI_RW(reg); // select register
0 n- O7 _; d m7 t. L) R3 H SPI_RW(value); // ..and write value to it.. 6 O0 y9 e! b/ b7 c) q
CSN = 1; // CSN high again & [9 \2 T2 C2 Q+ b' g/ z7 }
& t/ K, M6 @( V) u return(status); // return nRF24L01 status uchar . A6 m. y# j/ F8 h1 h/ g0 i) U/ x
} 5 s. j( Q; ?/ t1 i; \6 I
5 G: ]4 T, D! m* I5 R
/********************************************************************************************************* 9 R% v+ g* J) V
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
6 J7 Q) }$ b8 b; ^/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
5 \7 X. Z4 y8 n1 _; Z/*********************************************************************************************************/ 4 a/ @' y W" q$ k
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) # b( E& v1 p2 @
{ / M9 L8 Q r: g1 C3 P9 J
uint status,uchar_ctr;
( v' S5 b) ?, W
. J% \5 p; o' J" m CSN = 0; //SPI使能 9 j7 u( U: D5 ]% P; t, }
status = SPI_RW(reg); : ^0 Q1 p- H4 ]0 I- n1 M# l% K
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
# g2 g# @9 Z# @* A# I4 I {
) o" M. @* I8 W `% W4 l |' e2 \ SPI_RW(*pBuf++);% ]4 u! @6 U1 l7 W
} & c& p: Z5 Y! S4 [6 [ [
CSN = 1; //关闭SPI 4 V5 H, L8 t9 u. p& C3 A- a
return(status); //
6 C# h, }# e* i- e}
$ s$ r2 ^2 v9 x7 N9 h3 R3 ~# L9 R. L" E
/*********************************************************************************************************** # X3 z' G! H9 |, R+ f* J
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf) * \% U* k7 b: A
/*功能:发送 tx_buf中数据 $ J1 }2 r( C9 ~$ V
/**********************************************************************************************************/
3 }; z: q) o) P5 t8 L. Y0 fvoid nRF24L01_TxPacket(unsigned char * tx_buf) 8 q1 p7 z4 h" J! O7 X$ V. T: S0 K3 |
{
6 G q. c. x) s5 F* L* l CE = 0; //StandBy I模式 5 S2 U; ~7 g( G0 F# z# H
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 " l1 l* H( b1 j7 f. s8 K
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
7 h: w! ^7 M- w$ h5 G1 e CE = 1; //置高CE,激发数据发送
$ A M0 R& f7 u8 T$ t8 ^; e InerDelay_us(50);
+ Y; |0 f* |% A5 U/ K}
) u( _9 h! v! a/ K& K7 M8 b9 D# c7 ~$ k# f
//************************************主函数************************************************************
* S; w8 k f8 c b) ^/ f, bvoid main() 8 \+ p# o: `) L/ m/ e4 c
{ ' C0 b" F7 P$ U! a5 m9 P
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
$ l% S3 \$ E8 K$ |$ ]' E 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
8 V3 L8 G) [, y3 ~" b6 C Init_NRF24L01(); 0 z9 h1 D* c% W; ?6 f: V
nRF24L01_TxPacket(TxBuf); " I8 Y# @" H4 h# Y5 b1 L
while(1)
9 m' J% g+ i2 f; X; X {
4 f6 p' C' D4 _" B2 r [ nRF24L01_TxPacket(TxBuf); 3 e: _3 _2 F' ~7 n
sta = SPI_Read(STATUS);
6 n4 k: X' z0 E if(sta == 0x2e) //查看是否发送成功' k8 R. r) M: a: @5 H5 {7 }0 X# W4 F
{3 p1 H9 q3 m# Y+ Y$ l# _
P1 = 0xfe; 3 L! ^+ x' R# X$ X% p
}2 S; M, y2 d9 Q- |7 E% T8 n) m8 N
SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
2 w$ D6 y& F, V1 k% R/ { Delay(1000); //延时
2 \; A$ {! b+ E( K5 E }
: p4 S4 h& T) K} `1 x3 w8 ]9 W% x) O: K
*
9 l) c$ j% e1 g* e5 |" G4 f5 i
% i- l* W- A, ^- u |
|