EDA365电子论坛网
标题:
nrf24l01调不通,不明白硬件还是程序出问题
[打印本页]
作者:
RGB_lamp
时间:
2023-3-7 14:44
标题:
nrf24l01调不通,不明白硬件还是程序出问题
求教各位,小弟弄了两个星期的nrf24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.
9 D7 @5 M( x4 a* t+ X' t+ {6 T
网上看到一个帖子的程序说是将收发两端分开调试
f2 J) S" c& [4 C. c8 \% T
单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
, }3 N, m# w1 K2 m) \9 k- V9 \ i
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
1 d7 E& ~, `9 a5 N6 b+ C% j2 _
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
3 F( ~8 ~: l" O$ O {
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发
% v' X, M9 V9 @5 P* a `3 l* `
6 C$ x, W, {. k8 p: F C, d) x
而后程序如下:
; X1 K5 _) k6 @$ I
5 O" K; m$ b6 z# n: ~2 h
#include
* b8 B8 A' z; z
#include
. t& G1 _ _/ F9 ]/ R3 F
typedef unsigned char uchar;
& v9 N4 e1 F' B0 o+ l8 n; R# S
typedef unsigned char uint;
- W9 w$ `' P+ p. z) A1 M2 m
//****************************************IO端口定义***************************************
& o6 n+ [6 A6 N6 G; t+ F3 _% _) ?
: e* F. ^3 g1 {
***it MISO =P2^0;
" `3 d) S, r# m" D& w
***it MOSI =P2^4;
5 Y6 {# T* {+ L; \' m" p
***it SCK =P2^1;
8 D& O4 ^5 X0 y- u: R
***it CE =P2^2;
0 f2 K+ ~) m/ M1 o G: _
***it CSN =P3^3;
% f" \. C6 z$ h' D
***it IRQ =P2^5;
$ T6 |! h0 o+ o$ r1 @9 Y0 ^
***it LED = P0^0;
2 _/ E2 \% S0 j7 J: |+ Z8 w
$ E6 T7 i1 W1 M* `
//*********************************************NRF24L01*************************************
$ k5 `6 E0 g, r. O5 N
#define TX_ADR_WIDTH 5 // 5 uints TX address width
/ s% T/ D! Y2 t4 i4 ?8 [" _
#define RX_ADR_WIDTH 5 // 5 uints RX address width
6 a6 k; h8 C9 g* H
#define TX_PLOAD_WIDTH 20 // 20 uints TX payload
* l+ l; P7 V9 J/ a( m
#define RX_PLOAD_WIDTH 20 // 20 uints TX payload
& w4 w4 y7 _! s/ B# M
* }; v* m4 K. S! I6 D
//***************************************NRF24L01寄存器指令*******************************************************
" J$ L- v, d9 M! v1 l# ~
#define READ_REG 0x00 // 读寄存器指令
: Z( [' s& q# a* @9 B
#define WRITE_REG 0x20 // 写寄存器指令
$ a. Y: w7 N) {8 ]' i
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
7 i5 j$ ^# K! v! A9 n$ s
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
# j) U$ c; `3 P+ q+ n4 B3 V
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
) w! r2 e7 g& N2 }, W
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
' ?1 Q; @2 {" ?
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
- G) A# Z( Y8 `0 [6 Q1 J5 ~ r9 Z
#define NOP 0xFF // 保留
7 b( h% g; U1 Q
//*************************************SPI(nRF24L01)寄存器地址****************************************************
! \5 U% s3 B& B, o) W( ~" ^
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
+ |- ~! x; c% }3 j' k! S N
#define EN_AA 0x01 // 自动应答功能设置
0 ?0 l. g* A; s) e
#define EN_RXADDR 0x02 // 可用信道设置
( W) K% o5 G9 j0 D% B
#define SETUP_AW 0x03 // 收发地址宽度设置
" I' i; m/ l( y# `4 j& E+ Q
#define SETUP_RETR 0x04 // 自动重发功能设置
- _. G, P9 r1 S H
#define RF_CH 0x05 // 工作频率设置
) Y( \" M" i3 q+ b' Q
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
0 K; o. [" Q4 k$ u( C( {
#define STATUS 0x07 // 状态寄存器
1 p2 b$ h; S5 S. O' |4 d
#define OBSERVE_TX 0x08 // 发送监测功能
* S% W6 a+ {& v. ~
#define CD 0x09 // 地址检测
7 M/ g& g t4 ^" e
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
& D x( ?7 t" S
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
/ f% I6 b* j' N+ [) A+ A/ I
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
; j9 s5 f! N, I. y. I
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
3 g' n3 _, |) T/ N. B f. Q. U
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
5 H0 V, W$ l9 |5 G6 }
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
G6 w- ?/ Y+ t' }" z' \8 a' g
#define TX_ADDR 0x10 // 发送地址寄存器
" `& D$ X4 T( C8 J' P
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
8 I. A5 D. C* r7 A( n
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
: q' S0 q8 ~5 _( G7 D: T V
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
5 T$ O2 J( w0 h, O* o
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
- m( M0 D: L( f! C
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
9 v% X; Z1 [& x% [0 p* ?
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
; j% G# d) @3 P/ I. w7 i6 a
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
# x& ?5 Y2 i8 w# }7 z
//**************************************************************************************
8 v3 q, L6 j. u; j, {- t
void Delay(unsigned int x);
; i: |( R: ^. o3 }6 z
void InerDelay_us(unsigned char n);
8 F/ O y y1 x% f
void Init_NRF24L01(void);
" M H. T# S7 X' g H' R
uint SPI_RW(uint uchar);
3 L& O4 P" p I# k/ z
uchar SPI_Read(uchar reg);
: u! V- }# m) f
void SetRX_Mode(void);
1 G! x! f4 M+ e& r" S9 f: U B
uint SPI_RW_Reg(uchar reg, uchar value);
6 I, X# R9 C* D e9 q/ Q8 w
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
; l; s2 U- X" E. i9 M! Z9 m3 t0 b9 A
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
, `, m) o' D- @
unsigned char NRF24L01_RxPacket(unsigned char* rx_buf);
8 L( R* z. e- F4 v8 a
) X0 |2 V3 H$ Y. @% J
//******************************************************************************************
$ b7 Q6 M9 @) l
uint bdata sta; //状态标志
; O3 G {4 L% o( R
***it RX_DR =sta^6;
9 `2 ]' x9 Y& P# v7 p* V& \
***it TX_DS =sta^5;
; Q, N" K* Z" Y1 V
***it MAX_RT =sta^4;
) d9 G' U+ B3 }( d# R3 m
' j( O- K5 J2 \$ N5 ?3 n
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址
0 b. i K9 J# ]
/******************************************************************************************
, e! S) z! S' t4 W. p! p6 H2 O E
/*延时函数
% w% [" ^, @& t, g3 \$ s
/******************************************************************************************/
0 J9 n) u0 H( P9 t1 ~
void InerDelay_us(unsigned char n)
4 c" A4 t& G M4 m( j
{
Q6 w7 ^4 y4 I5 J/ H
for(;n>0;n--)
: n9 b) h1 w9 {/ f$ n
{
' ^+ w h, }3 S) ]/ w9 C
_nop_();
" S0 A- a' c& M" ~4 ?' Q
}
$ c. Y; l' s% w/ ^3 o
}
8 i$ t+ y: m; q' a9 Z
7 _, Q8 G N; \; I9 \6 x
//*****************************************长延时*****************************************
4 |3 w: |! L) z
void Delay(unsigned int x)
0 y+ Q* i' V& h* j
{
; p$ q6 L& F) X+ v
unsigned int i,j;
3 N! k, h! `/ Q
for(i=x; i>0; i--)
( p7 f8 F% V" f% Y% G6 {$ F
{
3 Q0 {7 J0 X0 t( } [7 M
for(j=110; j>0; j--);
# ?; C. `/ f' j& x
}
9 R' E1 @3 J2 @) O% M. N! O+ g2 u
}
- _3 V1 W/ C$ h6 @- N
: \1 J& Y0 u) U& a1 W+ E( E; ]0 p N
/****************************************************************************************
% e( q. Q! m U
/*NRF24L01初始化
% ^/ e4 }, g1 s, }
//***************************************************************************************/
/ [" k% j9 y3 x K8 Q* P
void Init_NRF24L01(void)
, i4 v# A/ H) m9 |2 Q% E
{
% c8 r! y4 [. D3 ^. j
InerDelay_us(100);
. z u* e" v) t; y
CE=0;
) }- T3 w1 g4 Q6 |% ~& [, F! S
CSN=1;
: }% H( p: [7 H- [- n
SCK=0;
, ~' o" R6 `& E g6 }( G+ X
IRQ=1;
- k" P' M0 k9 `0 M! S! L j! `3 v
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址
2 Y0 B% K6 v6 N2 ~
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址
& k' k4 a. y0 j- c3 u9 w
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 1
?# T- Q% }. _; P- E- w
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2
. N0 T! N( ^2 N0 g5 n- B
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点
1 S- X. B# \+ }: p! D4 ] j
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
. D1 \0 _) x5 p1 e% a0 n
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
) O; t9 x% E6 L: S& G8 y% ]/ [
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
' O+ @# [7 C2 B; N1 g
}
! A5 b( `# ~* P) |7 o, X& l
& Z# I. _, j0 M
/****************************************************************************************************
/ f. n* l( ?, d7 {
/*函数:uint SPI_RW(uint uchar)
9 O0 w2 `# g- q5 _
/*功能:NRF24L01的SPI写时序
7 ?. _* ^% @9 r) c' f8 a5 a `
/****************************************************************************************************/
4 u, Q6 B8 J G& s! ~& b
uint SPI_RW(uint uuchar)
; b% G% N8 z3 v
{
6 Y& | p7 a) j# @
uint bit_ctr;
; }5 h2 A! g! O. b
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
8 Y. Y% q8 k7 p' B6 Y
{
/ r7 b( Y% {# Y @% N
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI
6 N8 x8 A: p' y0 Q* j7 ]
uuchar = (uuchar << 1); // shift next bit into MSB..
- G0 C4 {# `* K7 a$ h. c" @
SCK = 1; // Set SCK high..
1 Y M1 ], G8 e8 J% I
uuchar |= MISO; // capture current MISO bit
0 i- @* m- ~* R; |3 A1 Q& e
SCK = 0; // ..then set SCK low again
" ~) `5 l. f8 p5 L8 ~( `# n( r/ h
}
$ J2 m9 H# o; a. A1 A
return(uuchar); // return read uchar
5 E! U/ J, I8 n' y/ h& N
}
) q% ]) ` O/ O3 _' |
3 S0 x( a; {0 F. ~3 F
/****************************************************************************************************
0 l9 S( y. q6 m
/*函数:uchar SPI_Read(uchar reg)
4 Y2 j/ i3 t% j- g# z0 y9 P5 _
/*功能:NRF24L01的SPI时序
5 Z2 r( h! o: J6 I, V: C
/****************************************************************************************************/
+ Q4 t3 L6 U! T, f3 E
uchar SPI_Read(uchar reg)
& `# M/ o) B3 m1 Z5 _- w
{
2 {. P6 E+ Y* b
uchar reg_val;
+ l+ _" T6 s/ A; M
# \9 L$ `2 D% i9 n: q
CSN = 0; // CSN low, initialize SPI communication...
# {9 P( `4 [: i ~" T! j, b
SPI_RW(reg); // Select register to read from..
! Z0 u. ^0 X# w0 z" Y2 }5 D( h
reg_val = SPI_RW(0); // ..then read registervalue
+ C! l) n2 Z1 @5 r$ w) F! b
CSN = 1; // CSN high, terminate SPI communication
# o4 X- s0 q/ {/ ~% _( y8 g
$ |6 @) R' }; m7 H
return(reg_val); // return register value
; c) S2 ^3 l/ @
}
) P! J. O* S% Z3 a
6 L- t% B @0 h( O5 c
/****************************************************************************************************/
: v2 N& I3 y. N+ G( v7 @' l
/*功能:NRF24L01读写寄存器函数
) L5 L0 l; N5 V( q2 L" N
/****************************************************************************************************/
% G v9 N$ t8 S$ E8 R( z# h0 j
uint SPI_RW_Reg(uchar reg, uchar value)
& k: g% T! }9 p) ~7 m
{
5 ^9 c* v4 j6 _( g- h) X; w- A, }$ p
uint status;
; d3 I! i) `6 g, [$ v
2 e3 i i1 `: T8 p' A$ F2 m
CSN = 0; // CSN low, init SPI transaction
3 F2 \1 e& @+ z" w4 p% a: ?+ L
status = SPI_RW(reg); // select register
. T5 x. I, Y) V- {+ |; @0 p* }
SPI_RW(value); // ..and write value to it..
% ^! H# R. J0 V6 q8 a+ `7 M0 v3 ^
CSN = 1; // CSN high again
- f. j6 r- {) f8 n3 w
7 \9 v/ H* M( y* u
return(status); // return nRF24L01 status uchar
; S1 v; F/ h% s5 [9 z6 e) R) Z) m
}
7 m1 X1 q1 |! [* u. k: ^
* W* C3 M( F: j; s( K5 A
/*********************************************************************************************************
! Z# c9 i& g# f, i
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
% |/ M4 D8 J7 {3 e1 X% P
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
7 ?9 x& s A0 ]" j# F6 E3 f
/*********************************************************************************************************/
7 N$ e. B7 P! W; n3 `( M, p
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
6 l( D1 ]3 Z& v$ L# I4 k9 I
{
% r8 |; z1 j# v* F+ k3 i, E% i) P& g) {
uint status,uchar_ctr;
/ K9 ]" h. p! F
# O: L# f1 }; c4 d
CSN = 0; //SPI使能
( n& z( G7 S- V- Q) n5 _! Y
status = SPI_RW(reg);
+ L4 \5 l6 k; i& ?! k# t- q
for(uchar_ctr=0; uchar_ctr {
0 g/ M& h/ H; a; _5 T7 a
SPI_RW(*pBuf++);
0 l4 @. O8 G4 r* Y: w e p
}
k0 M C5 u' z8 z( S5 b
CSN = 1; //关闭SPI
: M( w8 B# [3 ?2 [! L' Z; F
return(status); //
/ Q8 u! b: S# y. p1 z# M w+ C
}
( B4 n8 m- d$ j' C) }7 Q5 Q% G
J8 {8 R0 T0 P9 p6 y; Q
/***********************************************************************************************************
. M0 p6 V0 t7 t* `+ I
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
3 a; m- T A, i$ Z3 x- i
/*功能:发送 tx_buf中数据
9 G9 k6 ~0 t- m) @2 L: R( e6 N- D
/**********************************************************************************************************/
. c. m2 P& a, v0 E# u6 V
void nRF24L01_TxPacket(unsigned char * tx_buf)
9 j" \) w9 K1 C' q0 N* S" l& S
{
7 s) |& J0 O( M5 T% ?! t5 z1 G5 S
CE = 0; //StandBy I模式
5 y' B4 w9 A) y. B$ w
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
% Z6 ^" N( j' \- H h6 \& `3 `$ N
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
/ h5 _$ ?, O8 h& [! y( {2 b
CE = 1; //置高CE,激发数据发送
7 g" p6 x2 C# c- o- }& O5 B$ A4 t
InerDelay_us(50);
8 [% K8 T0 W3 [2 T7 M
}
6 m4 Q! ~6 t4 D9 ?7 t
0 z4 z6 Y4 U7 @: i! ?% u
//************************************主函数************************************************************
5 i1 W; l* @1 f$ C# Y: z, O) \
void main()
& l8 d0 P$ z' c7 Z
{
' A! o# n( d) R
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
+ Z9 T- h& G$ s! y% n s
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
4 L/ K; T$ g& x5 g. u
Init_NRF24L01();
3 L! V0 z$ a# r" h( e2 l
nRF24L01_TxPacket(TxBuf);
' o' t5 _7 F0 R* a' S, W
while(1)
& x% a t4 T4 a& w5 m' s5 p7 b
{
+ e. q) l0 O/ E
nRF24L01_TxPacket(TxBuf);
7 t9 \2 ?+ }; F5 v9 Z3 h! e
sta = SPI_Read(STATUS);
' e5 ~4 k0 u+ n+ [
if(sta == 0x2e) //查看是否发送成功
* P( F. H6 w8 } m9 T
{
r' O( w9 J4 K( h8 X
P1 = 0xfe;
0 m& x- i3 M# X8 I1 p, }
}
: P: f) A" L U2 Q! e9 c. y3 C8 a8 L
SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
: ?) x3 u' q) X6 ~, r
Delay(1000); //延时
& a7 L% z# f! q& T, h
}
7 v* T. N" w3 W
}
$ ]4 w3 V+ `! b C a
*
9 s8 X# D: j3 h2 j3 _, A5 s
7 M; }- t6 |. U' E: [
& y0 e1 q, U' }+ j# \
作者:
niubility
时间:
2023-3-7 15:20
只能说最后还是只能自力更生,这里程序本身并无问题,主要问题是我自己的电源没有用稳压芯片,用电阻分压的电压不稳定,用个AMS1117-3.3v稳压以后就好了.
作者:
CRAZY_argentina
时间:
2023-3-7 16:00
这个程序是接收和发送一样的吗
+ S3 f y$ k, u, o1 ~/ v
程序怎么调试呢?
作者:
架海梁心
时间:
2023-3-7 16:18
本帖最后由 架海梁心 于 2023-3-7 16:19 编辑
) y: ^+ @1 \% ^2 M7 N, m
) [/ M" k) f$ E1 M$ r
嗯,不论是无线通信还是其它,电源稳定很重要的。
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2