|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.9 ?" D& d1 o3 F) b, h
网上看到一个帖子的程序说是将收发两端分开调试 - o; N& X2 b' T7 Y6 M6 i
单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
& {$ ^4 R* W1 H+ Z0 C SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
+ N, N$ Z9 j: S$ F' J SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道07 [+ L0 a4 k, x* X" X6 { x: F
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发! r6 F) u1 X0 X$ R, h3 w7 {0 Y
! n; E' A6 S% b q' x而后程序如下:
) P* b. f b' A0 |% d; r a( @/ o. G* ?0 F* }
#include8 V4 { W& y% b$ \
#include. k5 W) T. |& J/ q2 l1 M: s# V2 g
typedef unsigned char uchar;0 C" y2 K/ _$ V+ |5 ?
typedef unsigned char uint;
. F, c6 F2 E$ g' _; w//****************************************IO端口定义***************************************/ @( t# \9 [" J5 w% S# M
& l" ]/ R8 i0 Z( r9 j- Y
***it MISO =P2^0;$ Y1 K. N/ d2 U8 } k& E1 _* ]3 G
***it MOSI =P2^4;5 A. m% K2 ~ D+ ?1 t e
***it SCK =P2^1;
& F" W- N f& d***it CE =P2^2;' H4 M5 ? ] _& j
***it CSN =P3^3;
% T! V4 K7 S# o o***it IRQ =P2^5;* @2 q2 O! v! Z. \
***it LED = P0^0;: k+ Y7 d- l, Z$ q
) o3 L9 v3 t0 ] Q/ K
//*********************************************NRF24L01*************************************. p2 n6 Q. u$ Q9 d: p* q4 j' s
#define TX_ADR_WIDTH 5 // 5 uints TX address width
3 ?3 y' h# m' J. n7 O1 r, B8 L#define RX_ADR_WIDTH 5 // 5 uints RX address width
0 J' q: n# @! l# G3 B# L#define TX_PLOAD_WIDTH 20 // 20 uints TX payload* \: r$ N5 B( z2 N. q0 x) j
#define RX_PLOAD_WIDTH 20 // 20 uints TX payload
; i1 f w) x! ^! Q. C! P$ V* _$ q* k' M! q' z; r
//***************************************NRF24L01寄存器指令*******************************************************/ ^' C5 c3 h- d$ y3 B5 z% V
#define READ_REG 0x00 // 读寄存器指令6 U) O# }8 t! C% P N' O
#define WRITE_REG 0x20 // 写寄存器指令 {0 E* t7 Z4 r1 X
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
# U! \7 Z; t! t, Q1 s+ ]#define WR_TX_PLOAD 0xA0 // 写待发数据指令
/ O* O0 {& e( X$ w/ Y#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
/ {& R5 k4 Y% d* K0 k g1 G#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
/ e7 W* \& i8 ?8 t9 V( c0 u; e#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令" F4 w R S9 T( l/ C( Z+ N4 d
#define NOP 0xFF // 保留6 Q' y* h2 n& z- k( [( Y
//*************************************SPI(nRF24L01)寄存器地址****************************************************! _% e( ^6 w- X. c( b+ y# q
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
( z2 \4 R6 c. W3 k#define EN_AA 0x01 // 自动应答功能设置# v+ U8 ?6 o; o+ U0 b# b
#define EN_RXADDR 0x02 // 可用信道设置- n- ?" s+ G% Z; z7 V
#define SETUP_AW 0x03 // 收发地址宽度设置
: _( s& C: X3 |6 V5 c#define SETUP_RETR 0x04 // 自动重发功能设置6 _5 _; z. F6 ^+ O
#define RF_CH 0x05 // 工作频率设置, O7 r$ v5 n1 p* i( T
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
7 q7 P$ B; o: e; ^4 ]#define STATUS 0x07 // 状态寄存器
$ P5 `% {+ ?1 O8 a- _1 m; v6 F7 |#define OBSERVE_TX 0x08 // 发送监测功能" N0 [% I$ L: C2 @, h6 f# r7 U
#define CD 0x09 // 地址检测
' |$ U' l$ X" \) A5 X" y: B#define RX_ADDR_P0 0x0A // 频道0接收数据地址1 M0 Y( K1 Z; l; ^4 J
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
4 R+ d; f% N/ l9 Y" I" V9 u#define RX_ADDR_P2 0x0C // 频道2接收数据地址9 T2 d% M9 K5 C0 Q, d; b
#define RX_ADDR_P3 0x0D // 频道3接收数据地址& E. p5 I, K; U: F, M
#define RX_ADDR_P4 0x0E // 频道4接收数据地址% d( d$ p( p4 k0 m8 K% M
#define RX_ADDR_P5 0x0F // 频道5接收数据地址# M. c/ g' r* Y7 j( D- D
#define TX_ADDR 0x10 // 发送地址寄存器2 K5 W: Q( L3 W" G6 K" e( ?( p
#define RX_PW_P0 0x11 // 接收频道0接收数据长度) t) V& ?9 R; Y4 E; }
#define RX_PW_P1 0x12 // 接收频道0接收数据长度, x0 Y$ C# F. [9 l6 h" j: q7 w$ M+ @
#define RX_PW_P2 0x13 // 接收频道0接收数据长度' ^* G# E X% V7 d
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
9 y8 Q. C) Q; j: _5 v1 I3 Z#define RX_PW_P4 0x15 // 接收频道0接收数据长度( M% |6 v5 R- V& z
#define RX_PW_P5 0x16 // 接收频道0接收数据长度9 P* k! c* q- l1 c
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
4 |/ m6 L3 f* t' k( L! d//**************************************************************************************' }% ^3 Y) t* ?; z$ c" y
void Delay(unsigned int x);6 l$ b4 S3 G$ I& I4 x% w9 N; G6 v
void InerDelay_us(unsigned char n);
5 J2 O: j9 u# L! F% d+ _void Init_NRF24L01(void);
, e1 k5 Y8 p6 Puint SPI_RW(uint uchar);! t3 x% a+ t# ~% k5 K& w" [1 b6 g, E
uchar SPI_Read(uchar reg);
- _" [! T! ?2 T* Lvoid SetRX_Mode(void);( S1 Q: K9 u. v* j( [& w- z( m, j
uint SPI_RW_Reg(uchar reg, uchar value);7 n7 {) h, Z4 T
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);$ B) a0 S* f$ y4 G9 I$ c
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);, P4 [) f# ~6 T5 e! ]. E! @% e7 u3 P
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf); & y0 H4 ^: o7 }4 |" a
' W8 |: W5 M- `! c
//******************************************************************************************
& k5 R" z0 Q- i) H' t1 W$ F% Duint bdata sta; //状态标志* s% ^) x# I& P3 y; Y
***it RX_DR =sta^6;
H' r* v+ N$ @% {+ T2 C/ i***it TX_DS =sta^5;4 m# R5 t6 m" s+ X
***it MAX_RT =sta^4;3 e: C% E* z7 r- a1 ]) F7 ^& [" Y
) x5 O% R2 i& Z. D% E
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址 6 M! I5 V6 B) v B* ~# C9 M
/******************************************************************************************
( t$ V( l0 ^# w% k R+ F: X8 y+ x/*延时函数/ _- i3 ?* i/ j
/******************************************************************************************/: m7 v/ Y* p1 z5 V
void InerDelay_us(unsigned char n)
r" r" r- M* D6 B; b{
0 q; }$ k5 _/ d$ X9 k. k for(;n>0;n--)# S- M4 B! M* y2 K# Q7 Y1 X
{
8 M( F/ p- q% q _nop_();
% ?6 p) y! Q7 n/ Q! z% e }0 N; b. G# t0 N i- P# F- F% k
}; y2 u. `" E( V, D
8 z5 g7 i. u4 u F! v4 Z//*****************************************长延时*****************************************
) l+ W$ W8 Z. A) l7 zvoid Delay(unsigned int x)
8 y0 h2 P( ]& Q{
& S1 R& C; O$ {: Q4 _1 y. ~, W4 K unsigned int i,j;
* z8 l$ j& ?* A0 c- Y8 q9 a: _ for(i=x; i>0; i--)- r4 B& D: V) p" [, U
{
6 D- T8 V' m$ u8 _/ j for(j=110; j>0; j--);+ _. A5 B$ r2 ], W2 m
}( _& M* j5 X3 y7 O# ^# F
}: K6 ^: q: L5 u d
& G. l) y. o) a/****************************************************************************************/ u4 X8 C1 D, M" i, F8 K
/*NRF24L01初始化
' ?( R5 g* C! M/ w! q; J+ S3 j1 E//***************************************************************************************/
, n# P* J- x8 q4 Xvoid Init_NRF24L01(void)% R( p4 w2 A! [% T4 }3 B
{
! v) A' p5 Z+ d InerDelay_us(100);
# o0 }- x+ N, ?: C' m CE=0;
4 L& A6 I" Q7 C' ~ CSN=1;
$ }) C8 z4 o7 V% i+ T SCK=0; 6 {+ V8 _' g- l! ]
IRQ=1;4 B# o) o2 t' u! P* { j
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址
/ Q+ i' o( m4 \9 g7 [ SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址
7 K1 W |$ C& ^* s* |8 k SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1( k6 T& `7 R" Z
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2
2 X- b2 V: M! l) x) B SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点
, }0 j3 m* j: g2 w+ \ SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
9 a& o1 O6 @ z7 u# d6 K5 Q$ d: { SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节( Z' I& a+ ?" w3 C3 V8 b8 z) S
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
U/ N0 O l; |0 Y$ c' y}' e* d; I5 b+ e# h5 x' L) H) R
8 @: ^( K4 Y2 b+ ?/****************************************************************************************************
& _& _7 V: z4 \3 ]2 q5 q# L* V* l/*函数:uint SPI_RW(uint uchar)$ I7 g, k2 L' t8 n$ Y
/*功能:NRF24L01的SPI写时序( v2 m! t: |3 x3 B
/****************************************************************************************************/
; ?% S$ E" F9 ?/ |0 \) B) g- Cuint SPI_RW(uint uuchar)" h+ \- ~* H7 i4 A* u
{
6 [! ]" A9 u7 a* {" r uint bit_ctr;$ F4 p) E/ e: Q4 A) c; R
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit% w. r) n2 L7 |! @, G2 Z: o
{
3 \8 r9 h& I/ Q MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI
+ n6 i+ L' S3 o- X* {. X uuchar = (uuchar << 1); // shift next bit into MSB..
* ]" `, O! q7 k$ U3 h1 M SCK = 1; // Set SCK high..
) H [" N0 {: B+ l; \ uuchar |= MISO; // capture current MISO bit& H2 J* x- o( C( q* H. r" i
SCK = 0; // ..then set SCK low again
" F0 P6 I5 }- @9 Y }
3 D9 |* t$ d& b- [# Z0 D return(uuchar); // return read uchar% ~7 Y7 ~$ i4 ^7 X1 _+ ^* M: ~3 @- u
}
. x7 d+ K3 n: _( `# M% S
: z3 | R, y+ z$ m8 G9 u* @9 Q/****************************************************************************************************6 z( [7 Q- i. B; {) k, p
/*函数:uchar SPI_Read(uchar reg)% m. b0 `% m3 t8 m4 M
/*功能:NRF24L01的SPI时序6 B1 w: n6 r" h; J. h C
/****************************************************************************************************/
2 Y0 |1 n" N! r4 V; auchar SPI_Read(uchar reg)9 }7 P% ]0 F( {6 I& i* d9 Y, p
{6 A, Q7 x! N7 W5 [# D; D4 P( Q
uchar reg_val;
j# r4 M5 N) m' X# [2 I8 t1 J5 P( V9 a
CSN = 0; // CSN low, initialize SPI communication...
& G: O% Z/ `7 {" H. B SPI_RW(reg); // Select register to read from..$ H7 a# F+ ]: M
reg_val = SPI_RW(0); // ..then read registervalue r* c7 P5 X% x: }0 w) r, i8 I
CSN = 1; // CSN high, terminate SPI communication: O" c" a3 R, R1 O% y4 G/ z
4 t1 r4 ^9 } u, @) v+ g2 M return(reg_val); // return register value$ r, ]" c& B1 z
}
; h% z3 `& d( ^5 e$ w9 a% B* }/ T; M5 Z( m) q2 K
/****************************************************************************************************/: y# L5 u* A. w7 I
/*功能:NRF24L01读写寄存器函数
- f; u" x1 ~' {8 |2 Z8 W2 e7 n; \# O/****************************************************************************************************/
`# ?$ u4 ]; r3 T/ V/ ]uint SPI_RW_Reg(uchar reg, uchar value)
1 ]& w T3 g) U+ K{* }! D# Y* K- i5 D
uint status;
: k4 x( B" [! e) L0 u1 `2 P7 a5 u' c. t' M6 Y4 T6 {5 d
CSN = 0; // CSN low, init SPI transaction
* x, Y0 d0 ?: W8 [! _- T0 O% { status = SPI_RW(reg); // select register- c7 d5 W* n7 X/ `! q5 `* } a& U
SPI_RW(value); // ..and write value to it..% M! f1 ?0 }& D. o S# B5 C
CSN = 1; // CSN high again4 V" L% n4 r+ c. Z( U4 @, I9 h
! V9 c" _- C" E# F% j A' m
return(status); // return nRF24L01 status uchar8 U# L/ v" J1 @! L
}* R! s' o5 M) L* Y7 I# y/ v: n# u
6 D) R% |) _& L; K% F
/*********************************************************************************************************' p5 ?% W+ b6 j8 B' S/ Q3 `. b, E
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)$ e7 a( w! E( X- e! z9 M
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数* H: x, L% k! p6 x7 z
/*********************************************************************************************************/4 Z& q; E: N% l! l
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
1 M& v- T- w" ~{8 \" m3 |2 F* n6 u: h8 ^
uint status,uchar_ctr;
S; f1 F/ o. _1 U& Y1 m, q/ F/ Q# i( u; A' ?( z4 a
CSN = 0; //SPI使能
- t5 J' K! @6 c: T1 {, S status = SPI_RW(reg); + K8 I! |. l' H' O1 f0 [
for(uchar_ctr=0; uchar_ctr {
# E! D Z' Q2 D8 }0 p* G1 L- J8 C6 n SPI_RW(*pBuf++);. p) r/ n. D5 O+ k9 Q# k, N* T
}% D8 X* o5 \5 @$ ^' Z
CSN = 1; //关闭SPI
L# O, O: q @. x. @! E- R% T1 D return(status); //
8 N& q& I3 D! n+ L9 j" |) _$ P}; X) e6 g. O( T9 e5 m
4 t. b1 c! r, ?9 Q. {- J+ o/***********************************************************************************************************
/ T- o; Y; }. @7 h7 e) ^/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)( \$ z1 f% l. Z4 R! ?" v
/*功能:发送 tx_buf中数据" |3 O8 n6 e+ ]- D& |0 H
/**********************************************************************************************************/
/ }4 L; u& H1 Jvoid nRF24L01_TxPacket(unsigned char * tx_buf)( S! Q$ F. B) n4 o/ R
{1 g4 Z/ v; D! l5 h0 G1 `- E: R
CE = 0; //StandBy I模式
3 y: [/ L0 Q6 V( ?- u SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 ( u% O, b) q# \2 |
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
. e) J. s5 A- F. K' a CE = 1; //置高CE,激发数据发送
& R6 H ^; h( g* p5 z& I8 p InerDelay_us(50);
+ S: G1 A0 E9 J3 Z) a+ J1 U}
( U$ m# [' ?+ P" L; B; z' b# E. _9 ]* F
//************************************主函数************************************************************
# M' \% y9 ^0 n1 L5 ~% k& jvoid main()/ Y+ q6 k( q, k/ u z
{ ; ^3 V: \. p. K
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,, q: O0 ~) L$ e
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};1 u" ?" x# \0 V6 n% Q' }
Init_NRF24L01();, d( X- m# V- h, D8 L" f: ~
nRF24L01_TxPacket(TxBuf);% ^$ e6 u) k# f& u0 x
while(1)
/ w4 S, f. l# O1 L {
- R/ w! \) _8 ] B3 `8 R: b nRF24L01_TxPacket(TxBuf);
- Q2 i) e& R9 e, i& N0 {4 Q sta = SPI_Read(STATUS);* s& `! F! f+ b5 h- z, A
if(sta == 0x2e) //查看是否发送成功. ~* O6 \* ?- O
{( c: |2 i+ k5 [9 y, e
P1 = 0xfe;
- ]6 h$ v* n. t g3 L* J. ~$ ? R}
' G* Y& n& c$ x( y! H, i7 n- w, d SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
5 a" X) m( h1 f% x6 s: k7 k3 U Delay(1000); //延时$ i5 O E( r }% {# h+ E m
} " L+ C! k* |: ]( ^+ W# l+ j
}4 u" U; M2 s' K& ~# J h
*
& j) f. M* g4 q6 ^# N3 {3 p) o# _3 n7 I0 |/ K0 n
& ~# Y- q& x% x0 j3 b' ]
|
|