|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内./ I" S5 x. Y$ V' x6 I
网上看到一个帖子的程序说是将收发两端分开调试
, l7 a3 }$ y9 Q2 z单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。; l) U4 w4 r" ~( J
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
- H0 p3 e8 ] ^1 W" d% f& p6 J( i6 @ SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
% O# s# I: O; `7 M7 D SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发- `) {- ^. o s: x4 h4 C# q
+ \/ w- Q% L1 m7 f6 {# O6 G而后程序如下:4 a0 k( y' f- I( [
/ Q6 n% `% ^3 {5 b2 V
#include) E* L) B# j \) U4 L5 C' h
#include
. P0 m+ s) q' jtypedef unsigned char uchar;
, q2 m7 ^/ G* r( dtypedef unsigned char uint;. G+ b# A2 j4 W( r
//****************************************IO端口定义***************************************. S: E$ `& X& |" K+ K
, V. t' |7 G8 @; Q }! S
***it MISO =P2^0;& ~, z2 o' B ?/ E- Z U3 Z
***it MOSI =P2^4;: n0 N( J, l% c( o+ q8 g
***it SCK =P2^1;
1 }; {% S8 c/ Q9 z! m1 V***it CE =P2^2;
" T! p$ m- G5 j***it CSN =P3^3;1 Y, j7 N8 G f
***it IRQ =P2^5;
* x$ ~2 [+ \ N+ O o***it LED = P0^0;+ Z7 p2 u: u2 o; P% X
8 I: D7 q5 V6 ^+ \
//*********************************************NRF24L01************************************* ^, Q& n* s0 c7 k# W/ m
#define TX_ADR_WIDTH 5 // 5 uints TX address width" H+ r' t+ ^* c3 c1 V [0 m
#define RX_ADR_WIDTH 5 // 5 uints RX address width
% K" r& m) N! s5 U0 d \5 N+ v- a; L# r#define TX_PLOAD_WIDTH 20 // 20 uints TX payload
, B6 k. X, S5 B5 ]4 L" v' o#define RX_PLOAD_WIDTH 20 // 20 uints TX payload
2 p/ d" }. s! i, T1 }6 @+ i- W5 P. K1 }/ I7 p, c* }+ s/ g
//***************************************NRF24L01寄存器指令*******************************************************3 I# z, c. H8 }
#define READ_REG 0x00 // 读寄存器指令
4 e1 G/ q6 q" B3 g#define WRITE_REG 0x20 // 写寄存器指令
' ~. K7 m! q6 F8 H, b/ C#define RD_RX_PLOAD 0x61 // 读取接收数据指令
* Y8 s3 r' K, x3 M: @0 l#define WR_TX_PLOAD 0xA0 // 写待发数据指令7 f8 @) {& O5 e6 {# c/ o) T
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
+ t! C3 V5 R! a+ ?#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令( l; Z( R: F" q! R, z
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令* G# X% o' u, j
#define NOP 0xFF // 保留* ~6 i( y3 n. G% l- v
//*************************************SPI(nRF24L01)寄存器地址****************************************************
0 ~ p. J$ \, m D$ G( `3 z2 j" Z* y#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式( s1 n' W; o1 `5 M3 f! \4 x/ ~
#define EN_AA 0x01 // 自动应答功能设置' }" ?/ y! K {4 q2 B) s
#define EN_RXADDR 0x02 // 可用信道设置
6 O& {9 c8 A; J- b& x+ _, Y8 ^#define SETUP_AW 0x03 // 收发地址宽度设置8 u0 I# i: d J! z9 T3 b
#define SETUP_RETR 0x04 // 自动重发功能设置
1 ^( M7 t5 t/ f: o; t* K2 e: \#define RF_CH 0x05 // 工作频率设置4 c4 ]/ |: V7 }, I1 k# d
#define RF_SETUP 0x06 // 发射速率、功耗功能设置3 u8 P% O1 r9 }$ n2 q I
#define STATUS 0x07 // 状态寄存器
/ o. \! m7 g" c' t#define OBSERVE_TX 0x08 // 发送监测功能" @* d9 g2 L1 F2 m- A/ M
#define CD 0x09 // 地址检测 * `" H" o9 e; I% b2 E/ u9 w
#define RX_ADDR_P0 0x0A // 频道0接收数据地址/ _: L6 Y5 I$ r+ O) K/ M$ {: l
#define RX_ADDR_P1 0x0B // 频道1接收数据地址7 p" C7 ~3 L) B- o
#define RX_ADDR_P2 0x0C // 频道2接收数据地址6 o, v% X+ ^$ r- m! x
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
8 s- _5 z- C6 `& |) P#define RX_ADDR_P4 0x0E // 频道4接收数据地址
5 f- d) s3 Q. b9 Q6 |7 P#define RX_ADDR_P5 0x0F // 频道5接收数据地址' ]% N) b5 m8 O& _
#define TX_ADDR 0x10 // 发送地址寄存器( ]" j: r/ G. O1 O' Y' ^9 w! S6 _
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
4 j+ Y7 o6 t! N6 x! R#define RX_PW_P1 0x12 // 接收频道0接收数据长度" m% {8 e; ], _- E1 ~/ H
#define RX_PW_P2 0x13 // 接收频道0接收数据长度0 W- ~+ W! L4 f( }) P
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
$ E( A- x8 C+ ?1 n% W#define RX_PW_P4 0x15 // 接收频道0接收数据长度
# f- n' ^9 |, u! H#define RX_PW_P5 0x16 // 接收频道0接收数据长度
* q1 ^& R' X5 a/ V) Z, s4 Q#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
- E0 x3 d& T; q% l: p- ?9 e//**************************************************************************************
2 \: }+ p% E- ?4 J- f: I: q3 r; Nvoid Delay(unsigned int x);
( o) V y$ _7 i, D) M" Vvoid InerDelay_us(unsigned char n);+ B* ?$ L1 } `: w
void Init_NRF24L01(void);7 S+ N2 H7 H& K6 `- m; T5 Z
uint SPI_RW(uint uchar);! z+ q+ w6 Q0 u' m4 J9 D
uchar SPI_Read(uchar reg);' p, N3 R. [& d- @5 r4 A& y1 I
void SetRX_Mode(void);+ L# y. D" W- e5 e7 E
uint SPI_RW_Reg(uchar reg, uchar value);% B: @* D; A5 H$ n' L: D) L$ W1 d
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);4 q/ M n( ?0 w
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);4 U% R9 N* D, r* o! s; _
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf);
; `4 t' l6 v# ~4 S' H: g e0 ~: Q. x1 r$ E) k3 L4 h
//******************************************************************************************) o3 P/ s$ g6 F F1 `3 O7 U3 y
uint bdata sta; //状态标志
/ r1 e3 P. o6 |$ d, c/ U***it RX_DR =sta^6;- K9 ~2 z- A% e0 E
***it TX_DS =sta^5;
) V$ b0 @* ~! e1 a- }) k***it MAX_RT =sta^4;+ `3 R! P0 p, j9 B* n
. o4 {. I+ L/ }, y/ M
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址 & k F3 H/ I3 z( Z# f, I3 }
/******************************************************************************************
7 [' o0 v5 Y. Y3 y: z6 E/*延时函数7 p" ?' s: K+ R- e- Y9 S3 {
/******************************************************************************************/& C" k; ?+ E9 i
void InerDelay_us(unsigned char n)( s! M# G! ?7 ~2 r
{
. P* }+ `8 a9 E/ ?8 f, H4 K) A; v for(;n>0;n--)
) k: e* o8 y5 ~" f {
- `$ G0 {! w3 b5 d1 d( S _nop_();) x- [& b: w! P3 X) \7 X, Y
}9 o! o2 N L) K
}
& j) ` t* W, C8 d: d' b# a) O) A$ E& G1 K% q, q# x
//*****************************************长延时*****************************************
! D6 W) h) g7 s3 ~4 Q& s4 c* Xvoid Delay(unsigned int x)
) Y5 {$ R4 k: h) W2 m9 H{! x& F: u7 }0 ~* [/ Q9 t( J
unsigned int i,j;
9 p9 O. R8 v6 Q8 t1 V& M for(i=x; i>0; i--)' Q( r/ d* D( Y, u* M
{
4 d+ ~' I$ ]1 C3 i, n3 i for(j=110; j>0; j--);
- C$ k3 V+ D) ?: Q2 e }
2 | @( w8 ?. n" e3 R' T$ [- ?! f}
- k( G" f* H* P6 p% {7 c7 c- I% Z( Y7 q1 G+ U: M5 ^
/****************************************************************************************& Q- f! w& Y" E8 p. v) r
/*NRF24L01初始化
5 G1 J; H* n4 J a3 F! _( y3 e//***************************************************************************************/
& ^! t l+ T( M+ x6 qvoid Init_NRF24L01(void)3 Y: [2 x7 _+ F ~9 C+ h& ~' y2 K) @
{5 Y4 g/ O! h7 m( x
InerDelay_us(100);
$ N9 q3 ]3 _7 v9 E CE=0;
, v% { d& c) ?0 z& U. n CSN=1; , b, q) u5 k# K/ Q+ g* [* Y& r9 S! U
SCK=0; . O) f# n- x$ {, z
IRQ=1;
/ Y# O# \1 v) v/ ]* v1 x4 Q% _ SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址
. z2 e7 g7 _+ _( i( r7 n7 E0 a SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址
$ w% C! [9 L- S SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1, u& I, h* u7 G8 G
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2
, }, s+ M7 P1 C' z8 _: m9 {! g SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点8 Q5 @8 l8 K) E" K: }9 B1 C/ `
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致1 R ~& F x, K3 L# n6 v! P% }
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
! U6 X2 T; ?: l" I& y SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
( a: a/ ]3 ]' I# T v}% w8 o4 x5 g2 S4 l) K7 a
* M9 v3 n( {2 X+ i3 q/****************************************************************************************************
D/ C1 R* z! `7 Z5 v/*函数:uint SPI_RW(uint uchar); Q" j6 E d, h" ], `, H. e
/*功能:NRF24L01的SPI写时序+ d' |: J: y+ x, w8 K! ~) h3 \9 V
/****************************************************************************************************/. I1 g9 r! C' I$ N# t5 `+ S' ^% u
uint SPI_RW(uint uuchar)! M7 _. u2 z% t9 h& B
{# B# P9 a0 m* p8 Z* x( a) [9 ]
uint bit_ctr;
6 t" N& L% [. _# e, ^0 X9 W2 { for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
# V# K4 O/ p- d8 R# o% U1 B( p: M {
5 r9 }* w: \6 K; s4 k MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI$ s8 _) i9 k! C
uuchar = (uuchar << 1); // shift next bit into MSB..$ \: R& q; Q; O- l, {- O
SCK = 1; // Set SCK high..
0 f' y: D+ a, l, c uuchar |= MISO; // capture current MISO bit* a% n: |0 B' t6 {) L/ l
SCK = 0; // ..then set SCK low again
* u8 n0 t) G8 z1 A$ r }& x& m! S. p5 \2 z7 C& K) a' ]
return(uuchar); // return read uchar, O9 y4 g. {0 R5 I, ~' h
}( X; k* {5 S" Z
# ]2 S; S& _/ H$ y. G. }
/****************************************************************************************************8 [$ o( C+ N% C
/*函数:uchar SPI_Read(uchar reg)3 Q6 x& I( m- h V8 u' {
/*功能:NRF24L01的SPI时序
& t4 d$ K7 g3 [" s4 Q; V3 [1 C/****************************************************************************************************/
H& q$ L( W) h5 Juchar SPI_Read(uchar reg)
1 J0 N3 M8 v4 Q6 b4 K$ r) h/ ~, l{
: G9 [! L# V6 \4 K3 {9 W uchar reg_val;! u, u2 r' D4 t
! Y4 z# ^" Y6 w4 G* D$ n* j
CSN = 0; // CSN low, initialize SPI communication...7 |- C6 r' n% E2 U- J2 n, I' h
SPI_RW(reg); // Select register to read from..9 d+ a/ U$ @5 ^+ j; x9 G, V
reg_val = SPI_RW(0); // ..then read registervalue
" G# l, Q. ?: }. ^ b: @ L& I CSN = 1; // CSN high, terminate SPI communication
; t' m4 }9 c4 @% J @
4 ^$ H& B2 U+ v! a return(reg_val); // return register value
( p; F4 T% q( @5 \; V# O}
9 K$ a. f8 Z% D: c s e2 k$ F. p+ |- U: s& B
/****************************************************************************************************/+ C! n- p3 W1 ^4 p- J8 V
/*功能:NRF24L01读写寄存器函数' C, _9 }% u, ?6 N1 T
/****************************************************************************************************/
3 S/ S. ]7 ^% m8 Nuint SPI_RW_Reg(uchar reg, uchar value)
5 Y0 A7 y/ a6 Y% E" Y{2 x+ _. _3 m) w4 \" `7 q' X
uint status;
8 B4 v; ~0 h# a4 f; A5 J2 _$ ^, r+ {+ _/ u9 s: w: V& s4 Q, @
CSN = 0; // CSN low, init SPI transaction' P, ?- A# B" Z1 d9 k8 ^
status = SPI_RW(reg); // select register
: @, [3 K3 {- V2 ?! v6 E) h SPI_RW(value); // ..and write value to it..3 g; k7 h- A4 o" z" B7 c3 |6 F
CSN = 1; // CSN high again
p0 g4 h9 |1 {6 j
! h- H0 a4 n8 J. v: f& v& d return(status); // return nRF24L01 status uchar
4 s5 Y& g1 Y$ d* x! h}
8 ?: P* k: P, C; \4 v$ p
5 H+ G! P* c0 l' g+ S/*********************************************************************************************************3 ^# p6 n7 [1 v5 x6 ^( {8 l2 m: S
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
& m$ h6 n3 Y0 ]4 K/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数0 u, j/ l& [( x& Y
/*********************************************************************************************************/
' v g: e6 Z+ ~( h5 ]uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)# M5 E+ s8 x2 E0 P, t' r
{
5 r1 b' a; G; i' I uint status,uchar_ctr;: T9 J+ ]$ z7 d. U6 H; _3 @. U: w
' z* d2 j0 Z0 L4 B, p CSN = 0; //SPI使能 ) H0 b7 \( ?5 L1 N+ B
status = SPI_RW(reg);
, J4 k; M7 U; o6 Q& r for(uchar_ctr=0; uchar_ctr {
' ^ f! [# Z& O, V. E. l8 x SPI_RW(*pBuf++);9 O! ~- i- X; M6 P; `* V' `! G6 Z5 B
}
! |6 [4 t9 }0 a4 k# U$ ` CSN = 1; //关闭SPI2 P* P/ j5 \0 L F2 G4 q
return(status); //
1 {. a2 M! t3 m2 m}
* Y: [+ v- C% L- P) C$ l: `
( U$ d" v+ s& V/***********************************************************************************************************2 M2 l0 }/ H/ Z K% E
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
- N6 }6 D8 Y' c/*功能:发送 tx_buf中数据! d( d. L* c) S) h
/**********************************************************************************************************/- c. o ?4 j' b+ F
void nRF24L01_TxPacket(unsigned char * tx_buf)7 b; [2 o# x: Q* Y8 w2 B, S
{- Z# l: A' t/ \$ P
CE = 0; //StandBy I模式 5 x' e, ]) m- {# k
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 h# i1 O, V7 k" T! h
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送# f8 I$ \/ C F$ T, v. c% D
CE = 1; //置高CE,激发数据发送6 w3 @' i* m# o [1 C& {6 D2 |4 W
InerDelay_us(50);9 z( v- H) }% o* C. ^! h* I
}
7 ~. Z0 p P8 H3 l v/ N8 X8 c1 f! X
//************************************主函数************************************************************ @8 a" |% P) ?
void main()
9 _0 A) p9 o. F' A9 ~- E9 o s7 s{ - @4 F' C" g0 v
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10, C5 }3 I2 U! O4 ^; B9 C
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
; d) |' U) y/ m Init_NRF24L01();! f/ C6 `( T0 M% D/ H9 [: O
nRF24L01_TxPacket(TxBuf);
& L6 ?& ?" \* c# F4 n while(1)0 c; t6 e8 c! e; `+ ^1 u
{" O4 Z/ f/ R4 h2 X0 r. q
nRF24L01_TxPacket(TxBuf);
* C- s0 B& m* ?0 F# x sta = SPI_Read(STATUS);9 L/ s _5 s& S* N
if(sta == 0x2e) //查看是否发送成功* m; N, H/ ^% q C$ t$ l. m! @
{6 R; o( x% B: \8 I0 m5 v
P1 = 0xfe;
6 x9 N. Z% w% G& A0 L( H}
2 z; Z1 | Q% ], L0 V SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器& l- j% t/ U- \$ [) W' G! ]* M
Delay(1000); //延时; Q. L! z _8 A2 L. h: O
}
! J# H% u+ Q6 Y7 N, O: }# E}. t' |" ^( C2 z
*+ k1 @$ D, @6 f3 B& s# v$ a4 l
( J- H' L. C2 S4 ]% R Y" j
}/ B% f/ j! a: t |
|