|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
求教各位,小弟弄了两个星期的nRF24l01无线模块,芯片用的是stc89c52,可是几乎毫无进展,在网上搜到了很多的程序,函数定义部分基本上大同小异,我做了两个最小系统,用流水灯来显示结果,nrf24l01的电源是接了51单片机的VCC端后用电阻分压出来的在1.9V~3.6V以内.
/ I: i: A' I' ^! S/ X" H d5 Z 网上看到一个帖子的程序说是将收发两端分开调试
; K% U* u# W' ^! D& l单独调试发送,完全抛开接收,配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
9 u$ M0 d2 B, M* \+ m$ [ SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答
8 j0 V' R0 h4 @$ P, |0 V& z% B, P SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 失能接收通道0
* g- x3 g5 V8 K6 J SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发/ W/ M7 N0 f5 p* V' S3 x
; a6 i( G2 ?' O- f* o |( S
而后程序如下:8 ^" c: j% a2 ]' W% O
5 ?: l8 ~! a6 w% p9 J8 `#include <reg52.h>
7 W# r0 Y4 A. ]( m0 j f9 _1 }#include <intrins.h>
! y' B' I I" r% J$ Z% |typedef unsigned char uchar; 4 M, Y' ]" Q( d* ^: m. b
typedef unsigned char uint;
1 Y: L. K7 k0 @7 `//****************************************IO端口定义*************************************** 7 [' O" \$ z/ k' v7 O1 c
( O* Y& X0 j( }& r4 F0 ?. a& F
sbit MISO =P2^0;
, u- c, ?) G* csbit MOSI =P2^4;+ V" x, ~# E! M o: ^1 A6 Z9 U
sbit SCK =P2^1;; Y& o$ C1 a+ l' v8 I* c
sbit CE =P2^2;& u2 X' B: p1 Z6 y' l
sbit CSN =P3^3;
7 o1 E+ U* Q/ v; H) o$ u6 N! vsbit IRQ =P2^5;# u( }" v9 |5 U1 _7 V
sbit LED = P0^0;) ^. J! h G4 O" r1 K
; T/ M9 `, {4 f! e' v6 t! J7 R7 S
//*********************************************NRF24L01************************************* ' P% @: d( D% e; N
#define TX_ADR_WIDTH 5 // 5 uints TX address width
- R! M4 M5 ^ h- [) D6 b#define RX_ADR_WIDTH 5 // 5 uints RX address width - j1 H! n& r4 w" h; c1 |
#define TX_PLOAD_WIDTH 20 // 20 uints TX payload 0 x( o! H' H0 B4 }' [
#define RX_PLOAD_WIDTH 20 // 20 uints TX payload 6 j( ]5 d5 I+ E( ^" v
& V7 R6 I. ?! ~( @. K* Y
//***************************************NRF24L01寄存器指令*******************************************************
! p+ X# ^3 i0 h" b; A#define READ_REG 0x00 // 读寄存器指令
* X2 S& T( B5 E' @5 x' w#define WRITE_REG 0x20 // 写寄存器指令
2 \" y' @. W) G2 p#define RD_RX_PLOAD 0x61 // 读取接收数据指令
7 P$ q; f/ ^2 P# y7 B#define WR_TX_PLOAD 0xA0 // 写待发数据指令
* x# D& K: _7 ^+ a3 n2 R#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 - I" s" x O$ `% E6 E
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 ! j- V- h$ o% v8 R1 m
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 4 q3 t: |% C+ v3 `4 X1 e+ f
#define NOP 0xFF // 保留
# S# @3 k5 f0 B% l8 U//*************************************SPI(nRF24L01)寄存器地址**************************************************** , s$ F8 e; H' M% H2 s. C. U2 [- f
#define CONFIG 0x00 // 配置收发状态,crc校验模式以及收发状态响应方式
1 P0 Q# e9 [+ E; [#define EN_AA 0x01 // 自动应答功能设置
( m: L9 V* n' Z! d* q1 ^#define EN_RXADDR 0x02 // 可用信道设置
: x; U+ b6 ]4 [- y#define SETUP_AW 0x03 // 收发地址宽度设置
. }# S+ @, l7 `: ~3 f6 s7 [#define SETUP_RETR 0x04 // 自动重发功能设置 % H3 d3 Z/ G( _! N5 J
#define RF_CH 0x05 // 工作频率设置
4 H& q' s' x# X5 \9 Y#define RF_SETUP 0x06 // 发射速率、功耗功能设置 3 q8 j) \2 }. o9 H9 J
#define STATUS 0x07 // 状态寄存器 4 v& F, Q1 O) ?1 W9 [7 g
#define OBSERVE_TX 0x08 // 发送监测功能 0 s# U9 m! E5 X; ?* O! u( Z- p
#define CD 0x09 // 地址检测 ' I. h7 C. n6 s
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
; `: m* B' O( Q4 x- M#define RX_ADDR_P1 0x0B // 频道1接收数据地址 , P9 K, d8 H$ d# m8 C& Y: n6 q
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
6 z2 ?, U Z# r" O- `#define RX_ADDR_P3 0x0D // 频道3接收数据地址 3 C, |) T+ F8 |. A& C B
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
0 _, x! C+ S3 K( N' r6 N#define RX_ADDR_P5 0x0F // 频道5接收数据地址 : I, }, `1 b+ o8 u, z
#define TX_ADDR 0x10 // 发送地址寄存器 ' ^ ]" g' L% l0 h. @/ _6 g
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
% U7 ?0 P# K8 n) |' s#define RX_PW_P1 0x12 // 接收频道0接收数据长度 / p8 M3 M2 C+ }2 k# e+ S
#define RX_PW_P2 0x13 // 接收频道0接收数据长度 ! X N) o0 m9 B
#define RX_PW_P3 0x14 // 接收频道0接收数据长度 ' N8 D; t- _& Q
#define RX_PW_P4 0x15 // 接收频道0接收数据长度 & M" e" ?0 D2 }# {8 ~8 z
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
& n- l _3 U1 W2 m+ W6 e, |#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 ! f. [/ M' k5 c% T9 y! X3 ?
//**************************************************************************************
- @; F: y& S" j+ zvoid Delay(unsigned int x); : M7 F! ~4 ^+ @' J x1 X
void InerDelay_us(unsigned char n);
& r: G* B$ _5 `9 S* ovoid Init_NRF24L01(void); - o( ^% Z" A% E" e+ r1 W9 N* r4 q
uint SPI_RW(uint uchar);
|6 h* _/ m" u, J' F7 {uchar SPI_Read(uchar reg);
3 H# s; S$ W0 m" K( ^: X" Z# j: W! mvoid SetRX_Mode(void); 8 J' `) i9 n+ `5 w
uint SPI_RW_Reg(uchar reg, uchar value); * v Y& d! _- n
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
# Y7 r' T5 t4 J2 M7 s$ ~9 w1 k7 g. kuint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
: |, |7 A. @( k. C& Y# V! funsigned char NRF24L01_RxPacket(unsigned char* rx_buf); : l* `) n% q1 X4 R, ?. P0 x9 v
& E+ W% r5 s& W6 L8 ]
//******************************************************************************************
8 c( E& j# X/ h4 F- i5 u+ W$ t" muint bdata sta; //状态标志 % |! w; `1 i- ~( h, N
sbit RX_DR =sta^6; # D, V" ?, ?( h* k2 [
sbit TX_DS =sta^5;
! h* V! l/ d" Z- U* esbit MAX_RT =sta^4;- j; i9 u( }% _1 T- x& {
4 c. Z+ z9 P* V. o1 Ouint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //发送出去的地址 # n$ {: F, Y/ G3 e
/****************************************************************************************** 6 z: L* q7 ]3 B# S$ \9 q9 C4 q; K
/*延时函数 % S% T% W, I- p& B6 \9 S
/******************************************************************************************/
0 e) \# v- w4 k* Dvoid InerDelay_us(unsigned char n)
- h9 O8 s% f& |0 F; H# |, R{ " P Q) B0 D+ a$ p/ M
for(;n>0;n--)
( d7 Q0 ?: w( e0 p" t, J {
/ ]: i# @# h! D/ I f) E5 x' ^ _nop_();
( b) _- ?/ y% i/ s g, x9 y }: C8 I+ s( J6 I2 B/ C
}
8 D" D( {0 J( p+ @# R: n% Y- s$ R% j' Z
//*****************************************长延时*****************************************
& J+ z( a1 f# k: Xvoid Delay(unsigned int x)
9 S8 r8 O! J1 x9 t9 @. M# Q8 b{
" ?' Q# n& j* S# s5 t$ S unsigned int i,j;
% a& ]) K) F, S2 @* @ H for(i=x; i>0; i--)* A9 p; A: U* i6 k+ V% H" m! r
{
5 j: v: N; q2 M( f for(j=110; j>0; j--);
( {' p& p; y2 } {* q }
' ?4 X Y/ o2 |( E3 s6 E}
) l' {# d" r! \3 D e5 I" P4 f8 I7 k- |
/**************************************************************************************** 1 r4 `5 B: z0 i- m
/*NRF24L01初始化
' U( V9 u; z. q# I* Y//***************************************************************************************/
u$ r- }6 `6 \$ b+ lvoid Init_NRF24L01(void)
6 @8 p* {# @( N& z3 q* f# `0 F; X{ ( S% P' i# Z0 m9 y# k4 k
InerDelay_us(100); 5 Y; ^# Y" n" h/ Q) i" p
CE=0;
8 ]; Q0 ~' R+ S0 U1 O8 _ CSN=1;
* K6 R; v: C5 r SCK=0;
1 q! R( @ {. @6 h6 d' X9 |/ _ IRQ=1;
E* K5 u% E8 O! C9 y: v3 i SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送端地址 , u p/ T# C7 E( e' v; F
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // 写自动应答频道0地址
( M; z: w9 j0 C0 v7 r1 d# Y0 S9 Z SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动 ACK应答禁止 18 G" T/ S6 P1 T
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); // 频道0接收禁止 2, O' \* d7 [! p
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //禁止自动重发 3 调试时注意这三点" y5 I" g: ?1 n% K. p
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致 - {1 I4 Z: m ^
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节 / w1 S1 Q. C3 g1 M' j3 \
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
+ j: d$ I. F' E4 ^2 f}7 P/ _; i: k* S z% V1 D# j6 s% J' O
- h* I% w+ q7 Y4 \2 p# x/****************************************************************************************************
* X8 W% z' L5 d$ f* r8 w |* Y/*函数:uint SPI_RW(uint uchar)
/ @/ G/ P! ^* Q) m% [) T! w/ V/*功能:NRF24L01的SPI写时序
" ?5 d2 p3 L* K E2 V7 [/****************************************************************************************************/
3 ?4 t/ p: G0 d* I; Y7 I$ Kuint SPI_RW(uint uuchar)
2 S1 q7 R7 R. W4 a( Q I) A{
" W/ {: X% z0 U3 v8 }) ~, u uint bit_ctr;
) w- z+ f8 h" A, I/ u1 ]8 i for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit & o3 C2 x/ }2 K( `9 J: u: w6 w% s* C" \
{ . f- O3 i5 O- f5 I( S
MOSI = (uuchar & 0x80); // output 'uchar', MSB to MOSI # D$ H3 D4 y4 f0 y
uuchar = (uuchar << 1); // shift next bit into MSB..
' t4 \$ l+ D# Q SCK = 1; // Set SCK high.. / A4 i0 f" {, _( e: b6 L& s
uuchar |= MISO; // capture current MISO bit
8 C, }& Z; P! [6 o: e9 G" K3 G SCK = 0; // ..then set SCK low again
% y, x" e0 w, X* M }
d. ~; G+ h6 R8 R4 p! j return(uuchar); // return read uchar
7 P [! ?! W% v, C* a9 D6 A}2 B3 B0 J# E- v( p9 ?
/ W2 w( h0 ~& C! |( @' w! E' y4 B/**************************************************************************************************** % l P/ r6 ~, j) C; O
/*函数:uchar SPI_Read(uchar reg) ; R0 e# x: C9 j7 ~ ?0 j2 y
/*功能:NRF24L01的SPI时序 / I5 K+ W' F* A- o1 e
/****************************************************************************************************/
! n1 o. p8 c+ h0 Q1 f: L$ d& tuchar SPI_Read(uchar reg)
& c# ^( x w2 P, h4 |) @/ u- ]{ 2 h5 T# x! {6 r4 k0 f+ c
uchar reg_val;
: F# V, _7 ^1 l8 G& g1 u# t( s
) S- v) j# X4 T CSN = 0; // CSN low, initialize SPI communication...
! i: u. N L7 d: ]' Y SPI_RW(reg); // Select register to read from.. 4 X$ ]3 e* Q$ y1 w. B2 q. y
reg_val = SPI_RW(0); // ..then read registervalue
# J4 x, F- e, c' i) L CSN = 1; // CSN high, terminate SPI communication
+ n0 g7 ~4 a9 J, V. N- M
6 U$ o- y. ?( N1 D+ m: A+ Z+ @: g return(reg_val); // return register value 4 X9 H* r0 r7 \) g
}
) y j1 X+ x1 y4 p- J' r
3 X+ g; Y3 N- E3 X; [/****************************************************************************************************/
9 M: ?" [0 m. X( {$ r/*功能:NRF24L01读写寄存器函数
6 x' ]/ `, n0 \9 g& H; ^6 C% e9 J/****************************************************************************************************/
& Y. _2 ?) t3 r) q+ p. Uuint SPI_RW_Reg(uchar reg, uchar value) 1 x( E d* G- J, x k0 ~
{ & Z8 `' U, x9 a8 F0 \ n. ^+ {
uint status;
4 A y. x5 N( A" M0 c$ |- c; s, L" T @) r; ]
CSN = 0; // CSN low, init SPI transaction " T( I" Y: m( V1 _# ?5 M
status = SPI_RW(reg); // select register
8 j+ e, ^6 T/ @8 O SPI_RW(value); // ..and write value to it.. : q( C+ k$ g- g: Y+ E6 @# K
CSN = 1; // CSN high again & A7 c5 @6 g2 x% l/ |" a& k
: P Y$ }$ R# g1 c' c! K return(status); // return nRF24L01 status uchar , J, B7 d6 N( e" R- y, B
}
" `1 o7 [% m2 N1 h* ?2 R4 V) `" e6 I+ u R
/********************************************************************************************************* - w! [' B0 h% r2 {0 j
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) * P/ m A" R( k2 ^9 g& p
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数 . y3 }" D* n D. O5 C# }3 ]) I
/*********************************************************************************************************/ # G0 u0 _0 f" d% y! E" J9 ~8 s# i
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) , c, p# |; j0 S8 |- P
{
+ S) C0 e! `( s8 x4 T( J: k% a uint status,uchar_ctr; 5 m+ a# F3 R9 [6 @, ]2 L
$ |2 ~* |5 {% r6 z
CSN = 0; //SPI使能 0 {. c6 I- _9 P& G
status = SPI_RW(reg); : M0 ?2 V2 f- \' X; M( J
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
, ?8 z1 K- }$ ] {
% T' V7 z6 K& N" I2 ] m SPI_RW(*pBuf++);* }3 \, O' C! _: T7 @1 M. V* `
} 5 r {) j# H' L* p1 X
CSN = 1; //关闭SPI 6 K5 x# S; \$ }( K
return(status); // : I6 V5 h$ U; J- V
}
, T- ^, u m/ a, Z0 | C3 o6 N7 |, t2 c- C0 U
/*********************************************************************************************************** $ [/ n" X8 }6 `( T$ R( q
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
3 e3 i$ {0 r# n7 U, W/ r2 [/*功能:发送 tx_buf中数据 - o1 `* W. I {. c; Y
/**********************************************************************************************************/
; B/ ~) a4 ~6 l5 l& @8 W2 P# Pvoid nRF24L01_TxPacket(unsigned char * tx_buf) " ]8 [6 }8 }- t0 K6 r
{ 9 _5 p; F# J1 D0 Z7 `% ~4 ^6 r" Q# C# c
CE = 0; //StandBy I模式 ! E: z% }4 Z9 m
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
" U8 r y7 I) G# A: w, y SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 5 y4 I4 {+ L" [- l
CE = 1; //置高CE,激发数据发送 + i) E9 ?9 v* X; i4 w
InerDelay_us(50);
- t; \ R C) b% {}! A& c- V ^% \; F1 J& N
; L4 _0 R/ L/ b6 D% k0 @//************************************主函数************************************************************
0 x$ m$ f# r$ g6 G4 W% U7 ?void main() , }* ~7 \' [2 b: }# W$ ^
{ / `0 E% T. q5 f8 P6 F; f
unsigned char TxBuf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
. P4 P& L3 {1 l 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
0 l9 b8 l! V9 L$ K9 w+ d( o$ N% R Init_NRF24L01(); n. x- S- ]! ]# Q
nRF24L01_TxPacket(TxBuf);
8 V4 P3 l( x7 j+ |1 Z' K! o+ G3 ^9 d while(1)
/ s3 w) N" _7 b2 A1 K9 y9 q8 f {
0 c1 l U- B) h0 J d& c nRF24L01_TxPacket(TxBuf); ) C# @! K1 F$ o- P; ~
sta = SPI_Read(STATUS);& |3 t/ t) {+ _8 B l
if(sta == 0x2e) //查看是否发送成功
# e4 a, d$ k# H7 o {
+ y( ]4 w: G- w, P3 U1 f( r P1 = 0xfe; + @. l0 Q2 C5 K: ~% N
}
1 X6 a! \* `; | w' A$ c) @ SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器 0 Q. j5 ]; i$ ^: F g5 i& W# Y! d0 w
Delay(1000); //延时 * T- ?/ T' } q- S( a5 \
} 9 L& {$ P. P b% S( ~8 h$ Z, {4 H; Y
} ) Z* ~1 u2 I1 P( ^$ x% w
*6 ]. R9 K7 R. [! u. r- @
9 X1 O' W0 x0 L0 B/ V5 Y
|
|