|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.( _4 O" S9 Z0 t. K& Q4 S
网上看到一个帖子的程序说是将收发两端分开调试
* g+ S# Z7 K/ E" ~8 Y. Z% G3 y) V单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。$ l0 R5 B/ {% {8 v
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答; U R7 W. I, z( U* N% a
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
. J/ {* u0 R8 [! |- x% l/ _: p1 H SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发
7 I9 Z6 h, A# E
& Z6 W% [2 {9 X& r4 a w而后程序如下:
8 r) R/ D% v4 i7 \7 \5 X+ R$ o9 Z, [5 k( u9 m
#include
6 X; \+ ]# |$ x9 o#include1 G/ L! X z9 [7 I/ S0 A3 O
typedef unsigned char uchar;
3 b4 d/ H" X+ k; Y" ?4 e# M+ Atypedef unsigned char uint;( Z( }& w' H" _0 n1 q, t2 n
//****************************************IO端口定义***************************************/ s1 f2 a) y! n7 S9 P3 d
I6 P& _4 f/ g# d# w***it MISO =P2^0;
- e0 v- }6 s5 F7 p0 u9 [' }***it MOSI =P2^4;
. ?: B( O5 L1 E& Z1 ]- I***it SCK =P2^1; V( d' R6 p0 `3 H* ~8 W+ C* p
***it CE =P2^2;
) N9 H8 u5 ~, }***it CSN =P3^3;
O" \1 i% K" M& ?3 T- S& J' B***it IRQ =P2^5;) Q O% Y- J5 n7 b/ x u
***it LED = P0^0;
1 E1 O) f, y8 I' b5 f5 k1 ?4 U. N; q& q- ]8 O1 i
//*********************************************NRF24L01*************************************
, |3 J5 F0 q6 ~" @# ~" X8 x; _7 U#define TX_ADR_WIDTH 5 // 5 uints TX address width
+ M- @0 d$ K6 m* |+ O2 e#define RX_ADR_WIDTH 5 // 5 uints RX address width
8 }: ?. n9 C" E3 @* F) u1 i3 W, z#define TX_PLOAD_WIDTH 20 // 20 uints TX payload/ d! Y9 G! z7 I6 n! \8 R) W
#define RX_PLOAD_WIDTH 20 // 20 uints TX payload7 v& r; W# c: p: J7 {5 n) m6 U
2 t% C) g/ W( w
//***************************************NRF24L01寄存器指令*******************************************************2 z2 B/ c3 Y$ ]# G3 p9 M
#define READ_REG 0x00 // 读寄存器指令
8 R0 _9 z [: U" i#define WRITE_REG 0x20 // 写寄存器指令+ B' t5 R3 A, O9 p2 T8 s
#define RD_RX_PLOAD 0x61 // 读取接收数据指令; C# B: p, `/ o
#define WR_TX_PLOAD 0xA0 // 写待发数据指令+ n( `& j: W+ l! R
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
. E5 ]% R0 P& g* W! i5 x#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令) X% `1 ?! x ^1 X2 n5 G
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 G- o$ J4 S" h2 i- j
#define NOP 0xFF // 保留
9 s# D: _8 E9 {" s//*************************************SPI(nRF24L01)寄存器地址****************************************************
6 c, ?: y- W% b7 I1 n+ [#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
6 k7 i5 s& J. R$ q; } w#define EN_AA 0x01 // 自动应答功能设置
. E6 i/ ]1 u1 ]3 {( g6 V R7 K#define EN_RXADDR 0x02 // 可用信道设置# y( K; T8 A+ y v9 F: K* e
#define SETUP_AW 0x03 // 收发地址宽度设置7 {& a% H" U, e) H$ B
#define SETUP_RETR 0x04 // 自动重发功能设置
1 k4 D" X" e# C y& U7 x#define RF_CH 0x05 // 工作频率设置
* N7 a$ l% i; p: T/ z; Q) Z" q' t#define RF_SETUP 0x06 // 发射速率、功耗功能设置
' N5 I1 O, B" M# O: [$ Y6 ]+ J% V! z#define STATUS 0x07 // 状态寄存器3 u* ]& e p1 B% s
#define OBSERVE_TX 0x08 // 发送监测功能3 J6 z) u# A; d, T; K; }- V
#define CD 0x09 // 地址检测 % i, O0 M$ O3 ~' M# a
#define RX_ADDR_P0 0x0A // 频道0接收数据地址; _' h7 K7 U( N% l/ R& X! i
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
, }. d/ q9 n0 U3 p- Q#define RX_ADDR_P2 0x0C // 频道2接收数据地址 Y% k' _7 J, [3 a: p
#define RX_ADDR_P3 0x0D // 频道3接收数据地址4 j( v7 ]$ p. o( ]# M5 J6 w3 ^- p
#define RX_ADDR_P4 0x0E // 频道4接收数据地址0 p3 m* q8 }( }/ B$ b3 {/ w. V8 ], z
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
5 j. Z$ P4 L$ N9 G" a9 ^. L! j#define TX_ADDR 0x10 // 发送地址寄存器
/ {8 ~3 y4 m2 R7 M#define RX_PW_P0 0x11 // 接收频道0接收数据长度
/ b( f7 {7 {3 e$ k/ y9 t( p9 U. b#define RX_PW_P1 0x12 // 接收频道0接收数据长度. B6 J% Y0 }, v; m! z
#define RX_PW_P2 0x13 // 接收频道0接收数据长度- ]3 s) R6 y7 F9 o# n
#define RX_PW_P3 0x14 // 接收频道0接收数据长度$ n; T: u. E0 E
#define RX_PW_P4 0x15 // 接收频道0接收数据长度/ }8 @/ n) `/ r: d% _$ x @
#define RX_PW_P5 0x16 // 接收频道0接收数据长度. w) |" X; R/ z) i6 \) o# D, l" O6 [5 V
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
7 f3 ?9 v5 o4 _9 q' ?6 y9 B//**************************************************************************************
! c% m% N5 ~2 c' uvoid Delay(unsigned int x);" G. Y1 a1 \$ \$ p& ]2 o
void InerDelay_us(unsigned char n);
+ X1 o3 v# B* \8 p* M$ @void Init_NRF24L01(void);+ p; l7 E$ O+ D4 V( B( p
uint SPI_RW(uint uchar);9 ]: w* Y, L: Q0 X' ?# R
uchar SPI_Read(uchar reg);' K5 @5 N$ ]; n& c5 _0 W/ T' ?
void SetRX_Mode(void);3 g3 ~& B u1 t+ M7 b8 R) F
uint SPI_RW_Reg(uchar reg, uchar value);! g: { |$ X' R9 L: Y& _
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);8 }# T/ [( }3 j* A3 m! D: b
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);9 F8 R! l$ D0 B3 }
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf); 8 Y4 _) B- ~9 M7 _- ]' G
' T1 L" A8 C4 Y( Z, t D
//******************************************************************************************5 |, W) O, K( ]$ P( J. n
uint bdata sta; //状态标志! Q5 `# S+ W6 e# W
***it RX_DR =sta^6;
$ T& c4 h4 S# ~1 T***it TX_DS =sta^5;
- ~6 d- R/ Y: z2 W! I5 F- M***it MAX_RT =sta^4;8 L3 S. V# t9 r
- s6 D8 P2 _ [
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址
5 z! d, [$ F3 ^) K: N' \/******************************************************************************************
7 T' \. O3 i$ D% H7 |" ]/*延时函数" E. I* Z. Q6 n1 h; E( o
/******************************************************************************************/
- u- a. t4 W1 M7 @ j& `void InerDelay_us(unsigned char n) [! _/ i" `8 W
{6 @+ t+ ~, P5 F, X# W" H
for(;n>0;n--)+ R: n h j& ?- f- {" p
{+ B& l# }& P; {: ?3 ^( o! O
_nop_();0 A. B/ O- O4 c! Z
}
" u: O e2 F" ?1 z% p. c6 L}
$ v! B. u) J1 b! V/ h* |3 i
% \( K% ~% Z1 U9 K( B4 M//*****************************************长延时*****************************************
1 m# k& z4 l( W, Nvoid Delay(unsigned int x)
2 w2 Z% Z: }' h{5 ?. \* `4 g, j
unsigned int i,j;" \. U0 [ c$ ^* p. `
for(i=x; i>0; i--)8 Y y4 W5 \* q* h* E
{- A% E V5 y* V1 `
for(j=110; j>0; j--);; z4 q6 U) o1 y9 ^+ q) Q( F
}
) ^3 U' t! r: |" P! f+ ?}% ], M, O2 S; P- u t
# H- S/ Q( u" \: ^* M2 @) [
/****************************************************************************************
$ n. \8 W8 `; V2 y) w( w* J& @7 J/*NRF24L01初始化$ P9 b$ x, O8 o! K
//***************************************************************************************/
5 g- K! u* d1 H+ v/ s, h' N: Qvoid Init_NRF24L01(void)- \1 ]) V1 q b2 Y" ~4 g. A; x
{
" @& s5 m# G3 _$ h$ z) y2 O5 ^ InerDelay_us(100);
# B# R" s+ T8 P }1 B: p CE=0;
2 X# K; N! L) t+ ~' R5 b CSN=1; 6 t% M7 ~- i/ R% M6 ?9 ~
SCK=0;
6 U1 D6 n" r+ Q4 P3 O( [3 |7 W IRQ=1;
) g" v6 H5 l" C SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址 X' D) C+ E/ R; B& v0 \& a" x/ c
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址6 K/ n3 \/ U) I8 }9 n! F$ ~/ z# s
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1$ v0 P3 X! [- R' a8 q
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 28 L9 H" }6 Z# a0 Y9 {1 g' ]' {
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点
8 ?' v S- f# x) c6 e5 J SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致3 p9 m. Y8 t, h. W6 T @! A
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
; _! a& T/ b4 g* a$ x SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB : N2 J$ R8 U4 z; r* r3 `9 \
}# \7 R; I2 c) l; s
. `& e! p, H7 F
/****************************************************************************************************# n; X7 {$ e1 f% t5 r; f# ^
/*函数:uint SPI_RW(uint uchar)6 X6 S+ j$ F7 I k! I
/*功能:NRF24L01的SPI写时序
: b! c1 l& M1 K- K# B/****************************************************************************************************/
9 z- r7 s c% a h" w, k0 Nuint SPI_RW(uint uuchar)& N ^; ]4 S n5 B3 s
{' `* [3 F& X+ }' V
uint bit_ctr;
8 r+ P, u; |! Q9 v2 ~ for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
% O* u+ ^( Z- g {% u2 m9 x/ T c( G3 R" {: w
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI
" b/ {$ x& j; k4 b" e; x uuchar = (uuchar << 1); // shift next bit into MSB..
2 n5 f* ?8 c: f0 s3 y SCK = 1; // Set SCK high..* H7 h8 {: W. ~- v! ]
uuchar |= MISO; // capture current MISO bit4 `" ~: e) H/ P7 ]
SCK = 0; // ..then set SCK low again
3 f+ Q f$ D9 k! c4 I } s( R5 j8 G- W& I* F/ i
return(uuchar); // return read uchar- M0 K& N1 K+ T9 m- f ?
}) y5 ]+ F! m- B. t% ]$ J
# r; g" T4 I/ U+ j( {
/****************************************************************************************************
5 u2 ~& v2 ?& u% Q/*函数:uchar SPI_Read(uchar reg)
$ Z: r$ ?4 y6 U9 k% U/*功能:NRF24L01的SPI时序
2 C9 o! h Z. X( u( j: N6 K/****************************************************************************************************/* F- {; v: X& l
uchar SPI_Read(uchar reg)
9 ^' f4 k% s2 x* Y{0 b2 ^& G3 a4 z
uchar reg_val;6 t9 N" F( N; k& z& x: {3 G
) T! `: _3 C+ f, {9 [" U: G) P CSN = 0; // CSN low, initialize SPI communication..., U% k/ i1 R% Z; T7 N! V" J1 n& x
SPI_RW(reg); // Select register to read from..
! q" B1 K, H: ?- | reg_val = SPI_RW(0); // ..then read registervalue
5 S' }" |$ ~8 u6 ^9 Y CSN = 1; // CSN high, terminate SPI communication& S e( c3 N+ g& z
$ P' b$ `1 d! a+ P% ~* x
return(reg_val); // return register value) y* y/ t8 K: v! q# H
}; j% B# \7 A+ A2 \( u
- D# P% J) z" [5 `) M/****************************************************************************************************/6 F6 g* C/ f0 y$ ^! F4 g6 l+ @4 C0 H
/*功能:NRF24L01读写寄存器函数
; Q4 A6 x+ C- K* g* _; `+ w0 D/****************************************************************************************************/% W* N3 I/ Z, a$ m
uint SPI_RW_Reg(uchar reg, uchar value)
2 {+ J, e O1 l, V% s{
`! n/ U+ e, y1 s uint status;
y% c! a3 Q) ~/ Q$ K8 b b- b3 M9 _( j) u! e- |% I
CSN = 0; // CSN low, init SPI transaction
, J% D5 v8 D) R+ W& x status = SPI_RW(reg); // select register
$ U, j; b u2 h SPI_RW(value); // ..and write value to it..- z v; ]5 h1 |: R' D' Q* Q
CSN = 1; // CSN high again
7 D* t( G5 [' d* Y8 a6 C, }+ J8 m+ F# l; l
return(status); // return nRF24L01 status uchar
! u* O7 ~3 d: D3 g3 n}& F' ], Y/ E* {3 S' P# H! A0 [
7 A5 L# N' s! s( Z$ m3 m M9 g- f
/*********************************************************************************************************
3 o2 \3 x% ^& K1 f/ _# k) x1 @/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)3 h/ }3 o+ m* `& I6 N0 Y n
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数! E) e. D1 c1 Q
/*********************************************************************************************************/3 D$ Y3 r F. @7 t
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) K. [- _/ L, w, W* W
{6 t& l' L, x- ?2 C' y8 l
uint status,uchar_ctr;9 A$ y3 b+ `0 X
5 [& e3 v) { m! i5 r/ q4 | CSN = 0; //SPI使能 1 ^9 G2 a& O8 o) |
status = SPI_RW(reg);
: _' b7 g1 h( a" N ` for(uchar_ctr=0; uchar_ctr {
$ C3 q% i4 B4 z$ X0 s SPI_RW(*pBuf++);
+ P; d( V X2 o+ Z' v1 `% k }
9 f4 Q# E# j4 A& a% Z7 v CSN = 1; //关闭SPI% p: y8 @0 o, o
return(status); //
6 P- f( l& B. t* N8 w2 j: F4 p}
4 x8 T, t8 O- Y' m& @/ v; g! H4 T3 c; w* A! k
/***********************************************************************************************************
2 V3 @0 E; w( Y& J& Z3 p/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
! e% _! y* Q8 U# C/*功能:发送 tx_buf中数据8 \+ d6 S- _" W! j) G8 X
/**********************************************************************************************************/9 x# l$ m+ L! C' L$ m/ w2 ]0 x
void nRF24L01_TxPacket(unsigned char * tx_buf)
+ x! u- _" o2 |% V* h0 ^0 U{: [7 g2 y# Z0 n' V# P, Y' u/ Y
CE = 0; //StandBy I模式 0 o4 z/ M1 ?. K( _6 b
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
4 k% G. @- |# H! N* a SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
% n' U, y& v2 W- k5 k$ | CE = 1; //置高CE,激发数据发送
" h3 ]# b! H3 J+ o InerDelay_us(50);$ x% N7 p& ?1 j
}. \* U1 G" j; ^) s2 |" p
. @! T6 Q! K: @1 ^3 ~4 V" ~//************************************主函数************************************************************
) Z8 }4 w6 L( N! c% Dvoid main()
1 S% |# d. p/ D{
8 E Z5 C: ~6 P& N% M& I unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,# D/ x% n* U0 s6 o3 \
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
; _) B% \4 p2 N% \7 n9 G4 P7 i Init_NRF24L01();; i+ b! E8 _. y6 j1 D+ O
nRF24L01_TxPacket(TxBuf);
% n, r! r# g! k# P/ T J2 }4 X while(1)6 e, i8 m. ?% F5 R1 o
{
: h7 i7 `1 |) O. }- p: ^ nRF24L01_TxPacket(TxBuf);
. {9 \+ Y" M3 x9 p1 V0 q! H sta = SPI_Read(STATUS);
" [8 O1 F/ ~& D: B+ e+ e if(sta == 0x2e) //查看是否发送成功
7 C. `, T9 _ H {1 ]5 A# p! o) [4 v/ H. Y
P1 = 0xfe;
3 f4 e4 A/ R3 Y5 G X4 N. D" J( E}
8 ^+ x5 w7 M; m SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器2 v1 b1 |9 H0 } Z2 j) @- U
Delay(1000); //延时
( B* ~7 u; ?5 a# z" \: y1 d! n }
, @; m6 D. t& S4 n# H7 e}2 d$ t% M: j: M: K
*6 n6 q+ b' U2 J4 s& S
( d; h8 \8 M7 W( ?! e+ ]
+ a+ V9 g! j* x+ n2 D1 n4 f |
|