|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.1 T+ X0 j0 i/ b A+ M1 W% `& W+ g3 L
网上看到一个帖子的程序说是将收发两端分开调试 3 Z) ]3 M: T4 b9 }/ U2 d" ]: w
单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
, ^ T" _1 Y2 T3 M+ m+ V* R' f7 o SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答' p2 A) s: p4 u* }1 s* I
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
; c V" R$ A q SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发
! E1 ?" J# h9 u$ `: J4 \9 h% W7 Z% n( v2 ?
而后程序如下:
5 P4 |6 }2 S, o
$ J7 k& e: v6 x- @1 E#include) C8 l) d9 w* ^6 S
#include
5 z; R8 A5 M- v6 Ntypedef unsigned char uchar;
: y4 v5 p6 `% r7 R5 atypedef unsigned char uint;
; S2 g& G. A2 C( P0 _, V//****************************************IO端口定义***************************************
4 N& c! ~/ j) ^. [ i: w5 Q* K4 ?% A
***it MISO =P2^0;( G4 k5 Y4 B8 c; a: m9 @8 R
***it MOSI =P2^4;
% j# K2 g }5 Z' ?! e+ K' x***it SCK =P2^1;
$ _5 E3 t) ]/ Y% _***it CE =P2^2;: z# o' ?- D# A# I
***it CSN =P3^3;
7 f/ m3 l3 q1 b- s0 e* |: h5 P6 `***it IRQ =P2^5;
' o6 m( H! Q$ b# A3 S/ J***it LED = P0^0;
% d0 l4 [* A, }7 }, Y p# C4 `3 i
1 E6 q1 a% l5 w$ N& t//*********************************************NRF24L01*************************************0 o' x! j# @3 X: Q- X
#define TX_ADR_WIDTH 5 // 5 uints TX address width* p& D1 _4 ` D( L, [' O
#define RX_ADR_WIDTH 5 // 5 uints RX address width
; d- S- Q+ I; T1 ]#define TX_PLOAD_WIDTH 20 // 20 uints TX payload
/ u1 D) R) K/ Q6 R, b4 D; l$ I#define RX_PLOAD_WIDTH 20 // 20 uints TX payload( ]5 Y+ ~/ z/ S+ B/ v# @; E
0 V( ]5 @+ k+ w# h
//***************************************NRF24L01寄存器指令*******************************************************! t9 r& L a7 u& ~9 Q$ V3 F. k
#define READ_REG 0x00 // 读寄存器指令# c5 o E- I5 Y n" j4 R, O
#define WRITE_REG 0x20 // 写寄存器指令
* u- H: w4 r/ @#define RD_RX_PLOAD 0x61 // 读取接收数据指令
% a6 b* F9 j$ q: p! `" i#define WR_TX_PLOAD 0xA0 // 写待发数据指令" a0 C, w9 {5 ^: [
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
6 c* {+ m: ]3 }+ ~#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
c+ S- g$ u% Q/ a6 k#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
3 H6 J: g% T5 V! p$ c#define NOP 0xFF // 保留- v8 x" H0 o4 E3 k
//*************************************SPI(nRF24L01)寄存器地址****************************************************
; d* [# E# v& d- |- U#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
; u1 m. H2 Z6 r- ?( y% y0 U! y: r#define EN_AA 0x01 // 自动应答功能设置6 |* [& z* A }# l" I
#define EN_RXADDR 0x02 // 可用信道设置
& r9 g. G) X: {7 X6 T#define SETUP_AW 0x03 // 收发地址宽度设置6 R& [3 l* N$ }& N0 B
#define SETUP_RETR 0x04 // 自动重发功能设置& E& a- R) d& ]. {, H
#define RF_CH 0x05 // 工作频率设置# C. e' `1 o2 c# y1 \2 a
#define RF_SETUP 0x06 // 发射速率、功耗功能设置6 S) l( V' E9 A# U7 h$ b
#define STATUS 0x07 // 状态寄存器
, r# G# O3 k# _) p2 `! f#define OBSERVE_TX 0x08 // 发送监测功能" d x, t2 p' ?( Z1 [
#define CD 0x09 // 地址检测
8 W) N4 |) |* d& Z- M#define RX_ADDR_P0 0x0A // 频道0接收数据地址$ R0 A1 }, N& i" X- V
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
0 J- h) I; O9 X- t; U#define RX_ADDR_P2 0x0C // 频道2接收数据地址- U$ @- O: @# \" F9 q+ ?4 B
#define RX_ADDR_P3 0x0D // 频道3接收数据地址* s, |' x; U" J3 M( M
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
" s# D a; S+ s2 T: b6 _ J3 k3 o#define RX_ADDR_P5 0x0F // 频道5接收数据地址4 G2 A5 x' x) |2 O8 _ M
#define TX_ADDR 0x10 // 发送地址寄存器
* I, @. u) X7 b5 i& v#define RX_PW_P0 0x11 // 接收频道0接收数据长度
) ]3 ^8 i' D8 e: r#define RX_PW_P1 0x12 // 接收频道0接收数据长度- D) @" x0 g# k9 z) @+ ]: U
#define RX_PW_P2 0x13 // 接收频道0接收数据长度7 ]" h6 P& \+ R0 a$ g0 j
#define RX_PW_P3 0x14 // 接收频道0接收数据长度1 E7 z0 X. U. ]3 o- `
#define RX_PW_P4 0x15 // 接收频道0接收数据长度0 a$ U6 r% W/ W# m
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
+ A$ a2 K* u" L+ R#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 h5 \, ^- I- J0 X3 g
//**************************************************************************************
6 |' e/ v0 { u+ Ivoid Delay(unsigned int x);
t: f Y7 J6 x1 s, Y: `) E3 q, Tvoid InerDelay_us(unsigned char n);' k9 p/ N2 S: A. @( v3 h9 g
void Init_NRF24L01(void);
4 T; ]6 b V7 q- ?8 uuint SPI_RW(uint uchar);
. w- Y5 g$ D" `' Q5 Tuchar SPI_Read(uchar reg);1 A9 [% o9 [* p, t% j
void SetRX_Mode(void);" Z, e; \: K- |2 m
uint SPI_RW_Reg(uchar reg, uchar value);
- Z; E" ~% a* m9 C [uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);* d: O# N. [+ P0 a* L% J
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
7 @9 S3 U- D2 n1 Vunsigned char NRF24L01_RxPacket(unsigned char* rx_buf);
- ]% e. N. W% `; G, v
' [1 y+ g% P6 N+ T( g//******************************************************************************************# l9 r( i# t) Q# K4 k1 V
uint bdata sta; //状态标志
4 b- n- ~! ?' l- `8 g6 _6 g***it RX_DR =sta^6;
% `5 |: t8 ~4 j2 ^& i***it TX_DS =sta^5;
3 [# B) v4 }4 q, g4 ~2 \' W+ m***it MAX_RT =sta^4;# R3 s F# h Z6 s% i+ K
4 w7 S) W/ Q2 Y! W3 a% O3 P7 N
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址 - m n7 g$ D2 S" ~7 F7 ]. I
/******************************************************************************************
& ^/ }- b1 J4 t* f- t/ r1 C5 q/*延时函数1 t4 F% y/ r1 |1 N6 p
/******************************************************************************************/
( r3 X; k/ K. P2 ~* b9 C! Qvoid InerDelay_us(unsigned char n)0 r6 }' S! J$ h
{
1 u! W# g, p/ x K5 q5 \1 a" w for(;n>0;n--)* a( t) t* n, y r
{
W+ P' T y9 d% }: t2 R _nop_();
9 Y/ j7 G5 ]1 |7 o9 L U }
" y' L0 l y6 g# C0 H}+ k3 Q& w0 Y$ [. I0 n: h ?
( Q! N4 k% K5 y ~8 s" A
//*****************************************长延时*****************************************
" F$ P5 H5 e/ `void Delay(unsigned int x)$ F7 n4 V1 a" O! }, ?
{1 n2 O7 J/ ~# A6 s5 E
unsigned int i,j;: ^2 _, N; P9 R( D
for(i=x; i>0; i--)
+ v9 z8 Z3 N. F {* B+ B4 }0 l# t( V& i
for(j=110; j>0; j--);, w, o5 B( z- e' X
}; E5 N$ C- b) s
}
/ Y9 _7 b& p2 l# R- R2 e2 R9 L! u6 M2 J$ D/ o
/****************************************************************************************
1 n8 ]! O+ w5 |$ a) j! j$ i/*NRF24L01初始化* v- v3 F" ~+ _8 y+ i' a+ e: ]
//***************************************************************************************/, E/ Z! F8 V( |- V& Y6 v+ \
void Init_NRF24L01(void)
# ?# w/ E) O1 s) [{
5 o- u+ b+ {4 c: w' a& r9 f InerDelay_us(100);2 x6 t, V! e$ \. x1 Z/ h9 Q$ t D
CE=0;
6 p" ~( u V' Q" K% H CSN=1; / x0 ]( x' p7 z# K" A5 e" S
SCK=0;
. z4 p' Y9 d J* {0 `+ V) J IRQ=1;
3 a* Q; M5 ^/ S6 U( F7 g" A SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址
2 n5 f; U k" J, ^ SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址" p- q* N+ m1 X5 N# a
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1
# G' \- e& U. U' | SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2
5 i$ T# W" U* G4 @& { SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点8 V2 j6 X) d' t8 c L; T$ t- V% ~
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致; L$ m+ C2 d1 x8 \4 C Y
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
1 E: a) ]# H6 h$ ?5 \& n SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB 7 c/ p2 O) z: w! z$ K2 ]0 y! C
}) k* s7 D$ N9 ^8 w. R3 S. w: N) S# ^
, _* g: _: o3 g7 }6 b. S* A: \" P
/****************************************************************************************************7 V. i9 \* U- l( Q& ?( P9 w
/*函数:uint SPI_RW(uint uchar). N I' q# i- g8 u; Y* ] ~
/*功能:NRF24L01的SPI写时序
6 V' a& Q# O; x9 B$ R/ [* e/****************************************************************************************************/
9 L2 m! E& U) x( p. }! {' J# ruint SPI_RW(uint uuchar)! F/ V4 U" \) H9 Z" P' B
{! l5 r4 q7 _- [: ]8 U9 o. Y, {8 I0 |6 V
uint bit_ctr;
- L; E7 p8 H9 X) j; j for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit X3 h/ g5 w# Z4 G
{1 v3 `( j( k ?, C% z9 G- [
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI
# u7 `# H- L, E: s" o7 N7 Q uuchar = (uuchar << 1); // shift next bit into MSB..
* Q! w$ M: @2 M; X$ ? SCK = 1; // Set SCK high../ p' _# Q5 N8 a9 R! s8 |& X3 E6 A
uuchar |= MISO; // capture current MISO bit) p9 X7 P2 z' v0 ~0 H
SCK = 0; // ..then set SCK low again
) q* |- h0 K4 Z( [, x' | }
. K+ G( f4 ]7 i3 `$ f e return(uuchar); // return read uchar
% W Q$ \6 J3 [4 v, l: z}8 x: A* F0 u @% T: Q0 b
2 Y, E7 p( A" D5 e+ \/****************************************************************************************************! Q: f- O+ Z3 b. K! x
/*函数:uchar SPI_Read(uchar reg)& {! Y% w! O9 ~! R2 m: i8 u
/*功能:NRF24L01的SPI时序% _8 y6 T2 Z+ {; b* U
/****************************************************************************************************/
5 P, G5 o5 D/ ?" @uchar SPI_Read(uchar reg)
2 t( ^+ j* ^& m$ t+ }{. m1 f* h2 ?6 Z# E3 U9 g
uchar reg_val;0 |2 }! Y* {4 Z g) P& I
" x& g! ]# b* W" h- A2 ^; S9 L
CSN = 0; // CSN low, initialize SPI communication...! G, r% b/ B9 R; O
SPI_RW(reg); // Select register to read from.., C d0 h! g1 v& s9 z
reg_val = SPI_RW(0); // ..then read registervalue
- ?, U8 e2 x$ E' R CSN = 1; // CSN high, terminate SPI communication c: L# A. j; m5 O+ l* f" N; S; h
- o7 N6 b6 B! y& _ return(reg_val); // return register value2 z$ N2 m( A2 _ m% @$ E6 U
}
4 L# l* w# q: z7 I3 J7 R" ~- ` @: B# P. c1 G6 C3 N9 f9 ^
/****************************************************************************************************/
9 p$ t7 l7 H7 F) l/ h/*功能:NRF24L01读写寄存器函数8 c7 m% V: p" W9 h
/****************************************************************************************************/
, D! B/ a+ {- V; ]7 `- c; Zuint SPI_RW_Reg(uchar reg, uchar value)( z9 t& P& d! y# K4 o' j: B1 L
{
9 _$ Q' b0 O9 f. v4 f( w; d uint status;
; @+ [) y/ y. i4 b
0 g; J5 m+ Z% n0 B9 A8 V$ { CSN = 0; // CSN low, init SPI transaction. j4 `- z6 C+ v) m' x, \
status = SPI_RW(reg); // select register" k6 V- f; W: _7 x3 B
SPI_RW(value); // ..and write value to it..
5 }& D0 m" |- {, o5 C$ Q+ } CSN = 1; // CSN high again
. d3 [- W3 l% Q3 t; |4 J/ E
/ q, P# u& K7 F6 K B, S return(status); // return nRF24L01 status uchar3 ^/ q# ^6 i! D5 C. `- q
}, N% q/ L8 y* o2 l0 Z* J+ |7 S
; p( A4 r; D* p4 b
/*********************************************************************************************************. L7 x3 ]2 h: w* Q, H' ]) \) q$ j
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
8 ~" _3 T6 ?8 b/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数5 o8 x4 v% T! \7 m$ a. E! [
/*********************************************************************************************************/
9 Z) V- r$ U6 luint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
; V: R0 e5 G% U7 l; `! M% i{9 \5 I$ s6 {. i- Z( n9 G' T. s9 q
uint status,uchar_ctr;. E' j Q3 K) z8 c2 Q. W
! [! w- H/ u+ |6 h" X: q, O CSN = 0; //SPI使能 4 o; r; n6 Z. r9 e- g
status = SPI_RW(reg);
! u; ~5 H- b8 n/ C% W9 n for(uchar_ctr=0; uchar_ctr {
+ t; V) E* @3 ]1 z3 [ SPI_RW(*pBuf++);
; }; A7 d3 g' O% y }4 }2 q7 l" X5 i I5 X& n
CSN = 1; //关闭SPI
$ ?. M# x& W9 ?- R/ @7 @ return(status); //
& {7 o I$ @' H# Q V% |4 R8 r}
+ O6 G) w4 a7 r1 x) ?& J. W }, q7 R$ U$ c
/***********************************************************************************************************, X- d L( K! d) O) I& k# v
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)" V0 B, ?+ D4 f q1 I" s! V
/*功能:发送 tx_buf中数据' W7 ?4 s5 l: G7 g- j1 c) b' M
/**********************************************************************************************************/
. n, o9 f" G u- R8 w" Tvoid nRF24L01_TxPacket(unsigned char * tx_buf)
( I n1 ~( Q4 x# e" a/ q: X: C{: j% n/ y ?- P. J% C
CE = 0; //StandBy I模式
6 w9 Y. D+ [; j0 ^ C C6 A SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 / P; |4 X( W3 L! k3 i3 n
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送5 C3 `9 W7 _# U* |
CE = 1; //置高CE,激发数据发送
+ G9 P" F; m. B& i! ^3 R InerDelay_us(50);3 O0 p4 P( x9 B8 T6 F
}
3 u2 \6 M: S* x# ^; w
- `9 W' ~# _. `" A//************************************主函数************************************************************1 x- k. W6 d9 k+ z% ^
void main()
' v$ E: z/ _# m' c* [5 _8 n{
- s$ H8 m/ q$ V unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
4 E8 e ^5 G/ ?( t' l$ e, n 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};# ?% d: ~" }0 |# W X
Init_NRF24L01();4 _7 S- m! u; |" o$ e
nRF24L01_TxPacket(TxBuf);
! w& F' x; m9 d1 R" U/ S8 L while(1)
( Q& I1 q) N5 y# E& {1 G {
6 I8 ^2 z9 i$ j# v2 F: T nRF24L01_TxPacket(TxBuf);8 [& q' i& \9 R2 K/ ]) D+ _3 G
sta = SPI_Read(STATUS);2 Y( G t. |4 h" L7 n
if(sta == 0x2e) //查看是否发送成功
. |0 j/ v- z5 u; G( C6 R% P! w1 Q4 { {, ]# s7 T7 d5 ]: a& r- x
P1 = 0xfe;
, U) [, O, e1 i( e2 F}
% j T" M, C) e2 G) [$ m SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
& e7 x% e4 }, M Delay(1000); //延时
# o6 q6 t% s- T. _( o } $ E" s, E$ S( o& Q; {
}9 R) D9 k2 l% l6 L x! \0 Q9 E
*( {; t: j* s2 c( f1 b$ X
/ E( Z( q. A+ T4 [
+ G" g5 ]+ u) f; d9 P7 I |
|