找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2329|回复: 5
打印 上一主题 下一主题
收起左侧

两片NRF24L01无法实现通信 大神们帮我看看,两天了!

[复制链接]
跳转到指定楼层
楼主
ID:225049 发表于 2017-8-5 19:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
两片NRF24L01无法实现通信
  1. #include <STC12C5A60S2.H>

  2. #include"LCD1602display.h"

  3. // Define interface to nRF24L01

  4. // Define SPI pinssbit qq=P3^4;

  5. sbit CE = P2^1; // Chip Enable pin signal (output)

  6. sbit CSN = P2^2; // Slave Select pin, (output to CSN, nRF24L01)

  7. sbit SCK = P2^3; // Master Out, Slave In pin (output)

  8. sbit MOSI = P2^4; // Serial Clock pin, (output)

  9. sbit MISO = P2^5; // Master In, Slave Out pin (input)

  10. sbit IRQ = P2^6; // Interrupt signal, from nRF24L01 (input)

  11. sbit P3_7=P3^2;

  12. // SPI(nRF24L01) commands

  13. #define READ_REG 0x00 // Define read command to register

  14. #define WRITE_REG 0x20 // Define write command to register

  15. #define RD_RX_PLOAD 0x61 // Define RX payload register address

  16. #define WR_TX_PLOAD 0xA0 // Define TX payload register address

  17. #define FLUSH_TX 0xE1 // Define flush TX register command

  18. #define FLUSH_RX 0xE2 // Define flush RX register command

  19. #define REUSE_TX_PL 0xE3 // Define reuse TX payload register command

  20. #define NOP 0xFF // Define No Operation, might be used to read status register

  21. // SPI(nRF24L01) registers(addresses)

  22. #define CONFIG 0x00 // 'Config' register address

  23. #define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address

  24. #define EN_RXADDR 0x02 // 'Enabled RX addresses' register address

  25. #define SETUP_AW 0x03 // 'Setup address width' register address

  26. #define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address

  27. #define RF_CH 0x05 // 'RF channel' register address

  28. #define RF_SETUP 0x06 // 'RF setup' register address

  29. #define STATUS 0x07 // 'Status' register address

  30. #define OBSERVE_TX 0x08 // 'Observe TX' register address

  31. #define CD 0x09 // 'Carrier Detect' register address

  32. #define RX_ADDR_P0 0x0A // 'RX address pipe0' register address

  33. #define RX_ADDR_P1 0x0B // 'RX address pipe1' register address

  34. #define RX_ADDR_P2 0x0C // 'RX address pipe2' register address

  35. #define RX_ADDR_P3 0x0D // 'RX address pipe3' register address

  36. #define RX_ADDR_P4 0x0E // 'RX address pipe4' register address

  37. #define RX_ADDR_P5 0x0F // 'RX address pipe5' register address

  38. #define TX_ADDR 0x10 // 'TX address' register address

  39. #define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address

  40. #define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address

  41. #define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address

  42. #define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address

  43. #define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address

  44. #define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address

  45. #define FIFO_STATUS 0x17 // 'FIFO Status Register' register address

  46. #define uchar unsigned char



  47. /***************************************************/

  48. #define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址

  49. #define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度

  50. uchar code table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

  51. uchar code

  52. TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};

  53. // 定义一个静态发送地址,该地址是指通道0的地址吗??

  54. uchar RX_BUF[TX_PLOAD_WIDTH]; //是否以确定发送与接收的数据宽度一样??

  55. uchar TX_BUF[TX_PLOAD_WIDTH]; //是否以确定发送与接收的数据宽度一样??

  56. uchar flag; //该字符的作用???

  57. uchar x=0,y=0,z=0,m=0; //为什么设置为这个数字

  58. uchar bdata sta;

  59. sbit RX_DR        = sta^6;

  60. sbit TX_DS        = sta^5;

  61. sbit MAX_RT = sta^4;

  62. /**************************************************/

  63. /**************************************************

  64. 函数:delay_ms()

  65. 描述:

  66. 延迟x毫秒

  67. /**************************************************/

  68. void delay_ms(uchar x)

  69. {

  70. uchar i, j;

  71. i = 0;

  72. for(i=0; i<x; i++)

  73. {

  74. j = 250;

  75. while(--j);

  76. j = 250;

  77. while(--j);

  78. }

  79. }

  80. /**************************************************/

  81. /**************************************************

  82. 函数:SPI_RW()

  83. 描述:

  84. 根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01

  85. 读出一字节

  86. /**************************************************/

  87. //是不是接收端与发射端都要用到这个函数,读出的字节是否为状态字

  88. uchar SPI_RW(uchar byte)

  89. {

  90. uchar i;

  91. for(i=0; i<8; i++) // 循环8次

  92. {

  93. MOSI = (byte & 0x80); // byte最高位输出到MOSI

  94. byte <<= 1; // 低一位移位到最高位

  95. SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据

  96. byte |= MISO; // 读MISO到byte最低位

  97. SCK = 0; // SCK置低

  98. }

  99. return(byte); // 返回读出的一字节

  100. }

  101. /**************************************************/

  102. /**************************************************

  103. 函数:SPI_RW_Reg()

  104. 描述:写数据value到reg寄存器

  105. 是不是通过写地址确定寄存器,然后向其写数据??

  106. /**************************************************/

  107. uchar SPI_RW_Reg(uchar reg, uchar value)

  108. {

  109. uchar status;

  110. CSN = 0; // CSN置低,开始传输数据

  111. status = SPI_RW(reg); // 选择寄存器,同时返回状态字

  112. SPI_RW(value); // 然后写数据到该寄存器

  113. CSN = 1; // CSN拉高,结束数据传输

  114. return(status); // 返回状态寄存器

  115. }

  116. /**************************************************/

  117. /**************************************************

  118. 函数:SPI_Read()

  119. 描述:

  120. 从reg寄存器读一字节

  121. /**************************************************/

  122. uchar SPI_Read(uchar reg)

  123. {

  124. uchar reg_val;

  125. CSN = 0; // CSN置低,开始传输数据

  126. SPI_RW(reg); // 选择寄存器

  127. reg_val = SPI_RW(0); // 然后从该寄存器读数据 为什么送一个0就可以读回一个数据

  128. CSN = 1;

  129. // CSN拉高,结束数据传输

  130. return(reg_val); // 返回寄存器数据

  131. }

  132. /**************************************************/

  133. /**************************************************

  134. 函数:SPI_Read_Buf()

  135. 描述:

  136. 从reg寄存器读出bytes个字节,通常用来读取接收通道

  137. 数据或接收/发送地址

  138. /**************************************************/

  139. uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes)

  140. {

  141. uchar status, i;

  142. CSN = 0; // CSN置低,开始传输数据

  143. status = SPI_RW(reg); // 选择寄存器,同时返回状态字

  144. for(i=0; i<bytes; i++)

  145. pBuf[ i] = SPI_RW(0); // 逐个字节从nRF24L01读出

  146. CSN = 1; // CSN拉高,结束数据传输

  147. return(status); // 返回状态寄存器

  148. }

  149. /**************************************************/

  150. /**************************************************

  151. 函数:SPI_Write_Buf()

  152. 描述:

  153. 把pBuf缓存中的数据写入到nRF24L01,通常用来写入发

  154. 射通道数据或接收/发送地址

  155. /**************************************************/

  156. uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes)

  157. {

  158. uchar status, i;

  159. CSN = 0; // CSN置低,开始传输数据

  160. status = SPI_RW(reg); // 选择寄存器,同时返回状态字

  161. for(i=0; i<bytes; i++)

  162. SPI_RW(pBuf[ i]); // 逐个字节写入nRF24L01

  163. CSN = 1; // CSN拉高,结束数据传输

  164. return(status); // 返回状态寄存器

  165. }

  166. /**************************************************/

  167. /**************************************************

  168. 函数:RX_Mode()

  169. 描述:

  170. 这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包

  171. /**************************************************/

  172. void RX_Mode(void)

  173. {

  174. CE = 0;

  175. SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);

  176. // CRC使能,16位CRC校验,上电,接收模式

  177. CE = 1; // 拉高CE启动接收设备

  178. }

  179. /**************************************************/

  180. /**************************************************

  181. 函数:TX_Mode()

  182. 描述:

  183. 这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),

  184. 130us后启动发射,数据发送结束后,发送模块自动转入接收

  185. 模式等待应答信号。

  186. /**************************************************/

  187. void TX_Mode(uchar * BUF)

  188. {

  189. CE = 0;

  190. SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);

  191. // 写入发送地址 (与接收地址一样)

  192. SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH);

  193. // 写数据包到TX FIFO(前以定义BUF数组发送数据4字节,写数据用于发送模式)

  194. SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);

  195. // CRC使能,16位CRC校验,上电

  196. CE = 1;

  197. }

  198. /**************************************************/

  199. /*********

  200. *****************************************

  201. 函数: init_io()

  202. 描述:

  203. 初始化IO

  204. /**************************************************/

  205. void init_io(void)

  206. {

  207. CE = 0; // 待机

  208. CSN = 1; // SPI禁止

  209. SCK = 0; // SPI时钟置低

  210. IRQ = 1; // 中断复位

  211. SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);

  212. // 写入发送地址 (与接收地址一样)

  213. SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);

  214. // 为了应答接收设备,接收通道0地址和发送地址相同 (发射端设置0通道接收应答信号)

  215. SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答

  216. SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0

  217. SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);

  218. // 自动重发延时等待250us+86us,自动重发10次

  219. SPI_RW_Reg(WRITE_REG + RF_CH, 10);

  220. // 选择射频通道0x40

  221. SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);

  222. // 接收通道0选择和发送通道相同有效数据宽度

  223. SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);

  224. // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益

  225. }

  226. /**************************************************/

  227. /**************************************************

  228. 函数:CheckButtons()

  229. 描述:

  230. 检查按键是否按下,按下则发送一字节数据

  231. /**************************************************/

  232. void CheckButtons()

  233. {

  234. if(!P3_7)        // 读取P3^0状态

  235. {

  236. delay_ms(10);

  237. if(!P3_7)        // 读取P3^0状态

  238. {

  239. TX_BUF[0]=x ; // 数据送到缓存 (uchar DATA = 0x01;)

  240. TX_BUF[1]=y;

  241. TX_BUF[2]=z ; // 数据送到缓存 (uchar DATA = 0x01;)

  242. TX_BUF[3]=m;

  243. DisplayOneChar(4,0,table[x%16]);

  244. DisplayOneChar(4,1,table[y%16]);

  245. x++;y++;z+=2;m+=3;

  246. RX_Mode();        // 设置为接收模式

  247. while(!P3_7);

  248. }

  249. }

  250. }

  251. /**************************************************/

  252. void Init_T0 (void)

  253. {

  254. TMOD = 0x01;

  255. TH0 = (65536-50000) /256;

  256. TL0 = (65536-50000) %256;

  257. EA = 1;

  258. ET0 = 1;

  259. TR0 = 1;

  260. }

  261. /**************************************************

  262. 函数:main()

  263. 描述:

  264. 主函数

  265. /**************************************************/

  266. void main(void)

  267. { qq=0;init_io();        // 初始化IO

  268. LCDInit();

  269. Init_T0();

  270. RX_Mode();        // 设置为接收模式

  271. DisplayListChar(1,0,"Xt=");

  272. DisplayListChar(1,1,"Yt=");

  273. DisplayListChar(7,0,"Xr=");

  274. DisplayListChar(7,1,"Yr=");

  275. while(1)

  276. {

  277. CheckButtons();



  278. }

  279. }

  280. /**************************************************/

  281. void Time0_ISR(void) interrupt 1

  282. {

  283. TH0 = (65536-30000) /256;

  284. TL0 = (65536-30000) %256;

  285. SPI_RW(FLUSH_TX);

  286. TX_Mode(TX_BUF);        // 把nRF24L01设置为发送模式并发送数据

  287. //        Check_ACK(1); // 等待发送完毕,清除TX FIFO

  288. //        SPI_RW(FLUSH_TX);

  289. sta = SPI_Read(STATUS);        // 读状态寄存器

  290. if(RX_DR)        // 判断是否接受到数据

  291. {

  292. SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH);

  293. // 从RX FIFO读出数据

  294. flag = 1;

  295. }

  296. SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除RX_DS中断标志

  297. if(flag)        // 接受完成

  298. {

  299. flag = 0;        // 清标志

  300. DisplayOneChar(10,0,table[RX_BUF[1]%16]);

  301. DisplayOneChar(10,1,table[RX_BUF[2]%16]);

  302. }

  303. }
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2017-8-5 21:57 | 只看该作者
程序是自己写的?
NRF24L01通讯原理清楚?
回复

使用道具 举报

板凳
ID:225049 发表于 2017-8-6 09:32 | 只看该作者
yzwzfyz 发表于 2017-8-5 21:57
程序是自己写的?
NRF24L01通讯原理清楚?

nrf24l01是网上找的,自己根据自己的理解改了一部分,lcd显示自己写的
回复

使用道具 举报

地板
ID:225125 发表于 2017-8-6 10:17 | 只看该作者
先看看有没有发送出来。把其中一个设置成接收模式,初始化后中断脚为高,接收到数据中断为低。
回复

使用道具 举报

5#
ID:225145 发表于 2017-8-6 11:00 | 只看该作者
LCD显示能用吗?用用其他程序试试,或者先不用显示,用几个小灯接在扣上看看,数据是不是传输成功了
回复

使用道具 举报

6#
ID:225145 发表于 2017-8-6 11:02 | 只看该作者
回复我怎么看不到啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表