|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.6 v/ j% q0 n: [$ _9 Y
网上看到一个帖子的程序说是将收发两端分开调试 " e5 F5 b8 x4 E) U: i% U
单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
4 N# d% D& _, \ SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
7 j/ e( W" N0 s/ T$ s SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
6 ]1 k+ q$ r7 n- {0 C6 N SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发
! H' |7 a- m7 s+ a; b& ], A- T ^7 P0 ?) i6 }- c; p7 x! j
而后程序如下:2 W- n1 I0 N/ w- @
" q( j1 p/ [& m. p
#include: V/ g( a& e- s* h6 H
#include+ d& Y5 Q8 s+ a
typedef unsigned char uchar;( O, [. F& e9 v
typedef unsigned char uint;3 l7 F4 |. t4 w9 T
//****************************************IO端口定义***************************************
! o2 p* W7 W, m8 s5 J
( @ y) P0 O9 {! g***it MISO =P2^0;5 N% u9 a$ Q4 ~
***it MOSI =P2^4;
9 {5 |4 o/ l; Z6 o7 J6 X: Q( P***it SCK =P2^1;
( \& u. F- w* ^; X4 e***it CE =P2^2;
0 v1 N, [ S6 V9 U***it CSN =P3^3;2 l4 m1 V/ W" S8 l$ V
***it IRQ =P2^5;4 A1 g0 ^8 y8 @ X5 Z! v
***it LED = P0^0;
, H$ e4 ~6 ~4 F8 W; I. s9 u4 V. r/ T* [) r
//*********************************************NRF24L01*************************************
8 U+ |1 _ x4 h7 b1 D#define TX_ADR_WIDTH 5 // 5 uints TX address width
1 T' }1 B- y# J7 |. h1 }#define RX_ADR_WIDTH 5 // 5 uints RX address width# }' e! i, a6 ~5 I
#define TX_PLOAD_WIDTH 20 // 20 uints TX payload
$ D) G: z' V6 V$ A2 j6 q#define RX_PLOAD_WIDTH 20 // 20 uints TX payload
: D F/ v( a, s( N* l8 `
+ p$ Q, g: B+ O- j1 J//***************************************NRF24L01寄存器指令*******************************************************
8 \! H; N |- K3 O6 t#define READ_REG 0x00 // 读寄存器指令. e Q* e2 q3 j, {! A
#define WRITE_REG 0x20 // 写寄存器指令
- V9 ~; _5 r: u! q% S7 ]6 O S#define RD_RX_PLOAD 0x61 // 读取接收数据指令. \9 y0 i/ E- I
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
& H: x. M: l! I. Q8 Z#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令" Z U6 X" s& i
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
0 _1 o/ F7 V- `$ [2 m#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
$ u2 D8 E: T. o#define NOP 0xFF // 保留2 @: @. y2 T: t6 y7 L% K' P# G
//*************************************SPI(nRF24L01)寄存器地址****************************************************& Q" w8 k0 d+ |' t( c) d- h
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
7 L) b% L5 p& k. U- c0 c% N#define EN_AA 0x01 // 自动应答功能设置
3 j6 \9 d/ D7 P1 b#define EN_RXADDR 0x02 // 可用信道设置
8 T' V+ |. k9 L# j; H9 m8 b. _' K#define SETUP_AW 0x03 // 收发地址宽度设置
+ F5 a6 E4 n8 J#define SETUP_RETR 0x04 // 自动重发功能设置
0 F. o# r k7 ]% e4 E9 r#define RF_CH 0x05 // 工作频率设置( v' T. p$ e- |" {6 R. t
#define RF_SETUP 0x06 // 发射速率、功耗功能设置3 D/ }! \! ^9 n J
#define STATUS 0x07 // 状态寄存器' d) `# l, G, F8 D6 j: E- @
#define OBSERVE_TX 0x08 // 发送监测功能" `: _/ b1 x6 [2 w
#define CD 0x09 // 地址检测
% @; L8 g' B7 P9 _% A#define RX_ADDR_P0 0x0A // 频道0接收数据地址+ N3 Y, z* z V3 a3 ~
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
9 \6 E$ l4 T- m#define RX_ADDR_P2 0x0C // 频道2接收数据地址% }% Z" i7 y" ~ _
#define RX_ADDR_P3 0x0D // 频道3接收数据地址; h% O2 l9 ?5 ?( v/ Z% O/ g
#define RX_ADDR_P4 0x0E // 频道4接收数据地址) U4 b+ V8 U! r. H
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
$ [" R/ Q# j2 A7 s+ ?#define TX_ADDR 0x10 // 发送地址寄存器
3 T6 y1 l4 i1 ?. X+ r6 Q#define RX_PW_P0 0x11 // 接收频道0接收数据长度
* C. l5 u' H. o C$ G3 f+ b, {, a#define RX_PW_P1 0x12 // 接收频道0接收数据长度
3 A% j9 ~6 X- @5 B: S) d1 m$ T; [9 F#define RX_PW_P2 0x13 // 接收频道0接收数据长度
4 u0 I- @0 `1 ?% {; H0 |#define RX_PW_P3 0x14 // 接收频道0接收数据长度) b6 e7 K6 I/ a- \% A. q6 z0 t
#define RX_PW_P4 0x15 // 接收频道0接收数据长度3 @( N) L" b- Q6 {; v
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
7 I# \$ a5 j& T! K7 L#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置' d8 j* c2 u0 V# \! `) j k/ n
//**************************************************************************************
; S' D6 l( _ Z Mvoid Delay(unsigned int x);
. d4 Q9 ~4 t& q+ vvoid InerDelay_us(unsigned char n);
. b8 C. p, s; A1 Rvoid Init_NRF24L01(void);
2 C% o4 e: Q' l yuint SPI_RW(uint uchar);
; |3 I$ g' R! L2 @2 Z1 i* huchar SPI_Read(uchar reg);1 X) t: w+ I* V- L# q
void SetRX_Mode(void);" N4 K5 o& K! z$ x: b+ z
uint SPI_RW_Reg(uchar reg, uchar value);# g1 j4 v3 h# z5 F; z0 u2 q0 G
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
* \. V' T* q4 @7 ]! guint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);! f t1 P# T0 ^/ o- h" w
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf); . ^/ t7 f8 n4 m2 E! b# T$ P ^. x
: d3 A# q$ _- t9 n7 H//******************************************************************************************4 Y; H$ b1 T: c
uint bdata sta; //状态标志* o6 B- E& B8 ]. w4 ?5 A
***it RX_DR =sta^6;
* s' h: G% g( I$ w- u0 | n***it TX_DS =sta^5;$ k$ {1 B& O+ Z7 Z3 g
***it MAX_RT =sta^4; X6 u/ Z: f4 M8 s& x5 ?# q! x2 H
; H. I7 k( D! T8 u) euint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址 & H# [- Z" ?! t9 l
/******************************************************************************************
7 g0 p# h; d* L( j) t$ o8 Z, M3 S/*延时函数
+ h m* Y/ s; g5 P/******************************************************************************************/
( K& N8 `5 K6 l* A' Bvoid InerDelay_us(unsigned char n)* g) h. f: |# Q" d* p- p6 \
{; p; T. d* @9 Z
for(;n>0;n--)
3 P, d! h8 Q' |- c, I/ m {
, E( a0 u) D `9 {, T _nop_();; t$ ~# ]2 O, G: x' M7 @" c
}2 _& a j9 Q5 G( ~, f
}/ n( a- P3 \; u
' Y) U% u9 E" C& D' |
//*****************************************长延时*****************************************2 A, r8 A8 R6 y( \6 I2 W
void Delay(unsigned int x)
5 _2 ~; N+ [" i{
% c$ O; }( A& o" H! [2 o unsigned int i,j;
4 a$ ^$ t$ ]3 T' Q; d* Q6 A for(i=x; i>0; i--)& P. a6 V; K3 [. W1 R: `* a: c
{( h" K4 Q4 Z" _+ V
for(j=110; j>0; j--);
# r0 t- |' C) E) ^ }3 M9 J: v1 L( o& U- R; U
}
' G! l V2 p* D# l, H, Y9 N, a$ R S
/****************************************************************************************- j- Q! ?* m2 Z0 A8 `9 j M( @7 h
/*NRF24L01初始化
7 G# d! q2 V! v7 {* k//***************************************************************************************// n( J6 W/ I+ @. h% [- [5 N
void Init_NRF24L01(void)* E1 K0 B) G/ D8 S
{
$ }1 A: I- t. h InerDelay_us(100);: j) f6 O3 R! I# q8 Q
CE=0; ; H2 j! a7 A/ O% S" s
CSN=1; 5 t: k6 o% P1 r9 w8 p
SCK=0;
! E: }% x. l4 I( D5 N! C- g IRQ=1;4 A2 r# @: P3 e6 Z
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址 ' |7 F, y- | v; U6 u& q
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址( M& z5 l* S4 c+ ^/ p% W6 v
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 10 e t( D' X' }3 H! f; E- Z
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2. y$ N( J: k8 g) ]2 l
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点% e1 m6 j, v2 n1 R
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致, e7 h1 o! y6 k9 _' L5 e- X/ z$ T
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
' ]4 `' t# t# Z; w SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
( Y$ G7 M' T! `% t ~# n}
1 F; M3 i# D/ \0 h% S. Y0 p& {6 y$ u2 M* F
/****************************************************************************************************
. L3 [/ G; }8 t4 B/*函数:uint SPI_RW(uint uchar)
9 H! V6 P8 l. }+ ] G( g/*功能:NRF24L01的SPI写时序
* H" t, n1 h. v& [9 N' D/****************************************************************************************************/8 V0 J* Z3 O% z6 r" K. u) a3 d6 ~ D
uint SPI_RW(uint uuchar)+ {' b. \' ?" h; j
{- h* g `- J. ~. K
uint bit_ctr;
3 i b7 Q! C1 u% ] for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit$ q: x. i w/ U+ r7 d
{. A( j4 ~! S9 k$ D
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI1 q" Q2 {9 q: l
uuchar = (uuchar << 1); // shift next bit into MSB..
5 w. D2 ?6 q0 G4 [8 f: x SCK = 1; // Set SCK high..' F9 t5 O, e1 v% v# V! k
uuchar |= MISO; // capture current MISO bit
2 |" y6 g4 \/ i9 M2 B% C3 [$ {4 C1 O SCK = 0; // ..then set SCK low again% V- U' k" @* Z# ]5 ~
}
1 `( h" A2 D- l; v3 D8 m4 n return(uuchar); // return read uchar
9 O* b, s9 m. Z- ?}% ?+ V3 o7 w$ z7 v. ^( N
3 y2 H. a- o e5 P! S
/****************************************************************************************************
" u) w/ p1 l& g, h% T) O9 s/*函数:uchar SPI_Read(uchar reg)9 x/ X8 M6 ^4 T3 N6 m9 Q" D
/*功能:NRF24L01的SPI时序
% C, U5 h# [/ F' c- z/****************************************************************************************************/. O- h0 w6 _1 P/ n" e# ^
uchar SPI_Read(uchar reg)
* k! l: k; ?& n{9 |$ b! o/ J& Z- w: \# X. g8 Y
uchar reg_val;) m: B# y$ U' l1 {9 D" f% w3 Z/ h
8 k0 A9 \) [; I& E CSN = 0; // CSN low, initialize SPI communication...
% e+ F' J2 O3 i, l+ e' d+ y SPI_RW(reg); // Select register to read from..
; H3 c6 c0 f) A7 d: L" W& n reg_val = SPI_RW(0); // ..then read registervalue
s3 v- K8 x: T) B, |+ o) W CSN = 1; // CSN high, terminate SPI communication$ B9 e. @/ M; o) w
! ]0 T$ Y5 N& b, z; H( k( h9 f
return(reg_val); // return register value6 f! j# p |. L* U0 Y
}
* P1 C# N" ]# a* y' y
! X2 ]: ~' f- t& U* g3 O# e/****************************************************************************************************/
6 e4 U9 z8 P1 P' b/ s4 p; W/*功能:NRF24L01读写寄存器函数. C i2 P( H( O, D; F6 t7 @
/****************************************************************************************************/
4 ?8 B" Q8 }3 K# v5 q) Q, g( quint SPI_RW_Reg(uchar reg, uchar value)# m, Z. u5 I2 o8 z f
{
9 P0 B! Y1 z+ W" B+ A9 x4 u% a$ P uint status;6 [7 M$ O: S w
) M6 R, l8 q0 n1 R3 f. Z5 K. } CSN = 0; // CSN low, init SPI transaction+ V$ }+ f% }+ Z; ^' w+ E9 Z6 ?
status = SPI_RW(reg); // select register0 A: ~: J6 x; G9 T# M
SPI_RW(value); // ..and write value to it..
& X/ G {3 N, R* T. K6 t( H! U CSN = 1; // CSN high again
F! {% y" t: x# l
3 ~& O6 c/ s- K return(status); // return nRF24L01 status uchar- h& k, q9 I1 v8 q7 |% w
}) E3 M9 q0 }9 O$ A
1 M4 |! |0 T" s/ t) _% Z4 D
/*********************************************************************************************************/ c7 H: X2 S5 N( O3 H
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
( k" {% z& K/ L3 M/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数8 J, f& f5 N* Y5 f& e( W
/*********************************************************************************************************/
- D0 Y( ]4 O+ k- V' huint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)) j$ d4 Z+ y& {- [- O5 V) t
{" H. f) p" Y" y& `# F N4 X
uint status,uchar_ctr;7 d4 a* U2 N, d' L O
- L+ z! J8 G9 P" `. V# N6 b/ m" N" r CSN = 0; //SPI使能 2 `; k# R$ f6 x0 \4 G! D+ F
status = SPI_RW(reg);
* E2 i2 t3 `1 D. Q1 q1 D for(uchar_ctr=0; uchar_ctr {7 E' K5 j* F( C. {
SPI_RW(*pBuf++);; `$ @! |7 W Y
}3 P# n& o0 I5 k6 u/ }1 }! [8 ]
CSN = 1; //关闭SPI
+ [, t4 u$ l& x return(status); //
* Q- r. N8 R. H0 D. _; P: I M}
* i& _/ }8 B! [& ^' d+ c E/ A+ p, L. m+ w+ A7 x
/***********************************************************************************************************
: O/ w. U1 I( X2 A5 e/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
; ]$ t7 J; P9 j, h& I0 K2 p9 N% K3 Y* r/*功能:发送 tx_buf中数据& [/ `8 L b$ ~* O; G% `
/**********************************************************************************************************/+ o( q: O$ F, r% |
void nRF24L01_TxPacket(unsigned char * tx_buf)
; D5 r8 w0 g0 D- ?+ r/ Z{
: D% k0 y! j; @9 ~1 g$ Z p; f CE = 0; //StandBy I模式
' n3 M4 b' ]7 L2 _ SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 2 P# h8 Z0 o+ W/ E+ l* ?& v
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送: d5 W( n- B4 Q G0 u; r7 b
CE = 1; //置高CE,激发数据发送# r7 `0 y, U) k- Q( R
InerDelay_us(50);7 P/ \0 }5 j6 \' Y* F$ n: m! T& t+ G
}
4 i" }; @5 v4 e2 ?- b# [6 |2 M' e' p( Q, `
//************************************主函数************************************************************$ X8 h( v: `9 |6 i: H* Q- i
void main()1 O- _, K% ]% B. Y0 Y$ j
{ ' W$ E, O x* [5 O) Z
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10," g- f, v/ \( H* \
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
* G+ @& o& m7 d% P/ [ Init_NRF24L01();
" c. Y6 e: L, V) h, k9 Z* z. h nRF24L01_TxPacket(TxBuf);
+ |5 S! M8 q5 l/ |; X while(1)
+ q# r. v' l7 |3 f2 s) t( G. [1 d {. p+ H& c! ^( X0 S' S# h: ]. U. W5 h
nRF24L01_TxPacket(TxBuf);2 ]2 y9 v- `- k/ }# K
sta = SPI_Read(STATUS);6 d Q& C; Z6 u6 Y. j
if(sta == 0x2e) //查看是否发送成功
. c* i3 C% U0 u R9 w; q( V/ V {: w: B& O3 C* n8 q$ o- D0 I
P1 = 0xfe;
! V3 n2 F! ?! }+ l; k. b+ K6 _}
2 W/ p7 V* w5 Y SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器% ]3 y1 V+ i& {8 r+ P& `
Delay(1000); //延时) F8 f' a& a8 \4 ~6 h
} ' V. y. w- Q+ b" R6 r8 g
}" R# B1 h5 ?2 O8 q8 l
*: D0 s/ r6 X' D% D2 T
2 {! }, B4 A: u
+ M w o) x( G1 ^0 P4 b |
|