nRF24L01_API.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include "nRF24L01_API.h"
  2. static uchar TX_ADDRESS[TX_ADR_WIDTH] = {0x00, TR_ADDR_B1, TR_ADDR_B2, TR_ADDR_B3, TR_ADDR_B4}; //发送地址
  3. static uchar RX_ADDRESS[RX_ADR_WIDTH] = {0x00, TR_ADDR_B1, TR_ADDR_B2, TR_ADDR_B3, TR_ADDR_B4}; //接收地址
  4. /*
  5. 00 配置寄存器
  6. [7]
  7. [6]可屏蔽中断 RX_RD
  8. [5]可屏蔽中断 TX_DS
  9. [4]可屏蔽中断 MAX_RT
  10. [3]CRC 使能
  11. [2]CRC 模式
  12. [1]1:上电0:掉电
  13. [0]1:接收模式0:发射模式
  14. 01 使能“自动应答”功能
  15. [7:6]
  16. [5:0]数据通道 5 ~0自动应答允许
  17. 02 接收地址允许
  18. [7:6]
  19. [5:0]接收数据通道 5 ~0允许
  20. 03 设置地址宽度(所有数据通道)
  21. [7:2]
  22. [1:0]0.无效 1.3byte 2.4byte 3.5byte 宽度
  23. 04 建立自动重发
  24. [7:4]自动重发延时:'0000'-等待 250+86us '1111'-等待 4000+86us
  25. [3:0]自动重发计数:'0000'-禁止自动重发 '1111'-自动重发 15 次
  26. 05 射频通道
  27. [7]
  28. [6:0]设置 nRF24L01 工作通道频率
  29. 06 射频寄存器
  30. .....
  31. .....
  32. */
  33. #define delay_ms(ms) Timer3_Delay1ms(ms)
  34. #define delay_us(us) Timer3_Delay1us(us) //{u8 i; for(i=0;i<us;i++) {nop;}}
  35. /***************************************************************/
  36. /*******************************************************************/
  37. //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
  38. #if 0
  39. uchar SPI_RW ( uchar byte )
  40. {
  41. uchar bit_ctr;
  42. for ( bit_ctr = 0; bit_ctr < 8; bit_ctr++ ) // 输出8位
  43. {
  44. NRF_MOSI = ( byte & 0x80 ); // MSB TO MOSI
  45. byte = ( byte << 1 ); // shift next bit to MSB
  46. NRF_SCK = 1;
  47. byte |= NRF_MISO; // capture current MISO bit
  48. NRF_SCK = 0;
  49. }
  50. return byte;
  51. }
  52. #else
  53. uchar SPI_RW ( uchar byte )
  54. {
  55. uchar i;
  56. SPDR = byte; //写寄存器
  57. for ( i = 0; i < 255; i++ )
  58. {
  59. if ( SPSR & SET_BIT7 )
  60. {
  61. break; //等待传输
  62. }
  63. }
  64. SPSR &= ~SET_BIT7;
  65. byte = SPDR; //读寄存器
  66. return byte;
  67. }
  68. #endif
  69. /*********************************************/
  70. /* 函数功能:给24L01的寄存器写值(一个字节) */
  71. /* 入口参数:reg 要写的寄存器地址 */
  72. /* value 给寄存器写的值 */
  73. /* 出口参数:status 状态值 */
  74. /*********************************************/
  75. uchar NRF24L01_Write_Reg ( uchar reg, uchar value )
  76. {
  77. uchar status;
  78. NRF_CSN = 0; //CSN=0;
  79. status = SPI_RW ( reg ); //发送寄存器地址,并读取状态值
  80. SPI_RW ( value );
  81. NRF_CSN = 1; //CSN=1;
  82. return status;
  83. }
  84. /*************************************************/
  85. /* 函数功能:读24L01的寄存器值 (一个字节) */
  86. /* 入口参数:reg 要读的寄存器地址 */
  87. /* 出口参数:value 读出寄存器的值 */
  88. /*************************************************/
  89. uchar NRF24L01_Read_Reg ( uchar reg )
  90. {
  91. uchar value;
  92. NRF_CSN = 0; //CSN=0;
  93. SPI_RW ( reg ); //发送寄存器值(位置),并读取状态值
  94. value = SPI_RW ( NOP );
  95. NRF_CSN = 1; //CSN=1;
  96. return value;
  97. }
  98. /*********************************************/
  99. /* 函数功能:读24L01的寄存器值(多个字节) */
  100. /* 入口参数:reg 寄存器地址 */
  101. /* *pBuf 读出寄存器值的存放数组 */
  102. /* len 数组字节长度 */
  103. /* 出口参数:status 状态值 */
  104. /*********************************************/
  105. uchar NRF24L01_Read_Buf ( uchar reg, uchar *pBuf, uchar len )
  106. {
  107. uchar status, u8_ctr;
  108. NRF_CSN = 0; //CSN=0
  109. status = SPI_RW ( reg ); //发送寄存器地址,并读取状态值
  110. for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ )
  111. {
  112. pBuf[u8_ctr] = SPI_RW ( 0XFF ); //读出数据
  113. }
  114. NRF_CSN = 1; //CSN=1
  115. return status; //返回读到的状态值
  116. }
  117. /**********************************************/
  118. /* 函数功能:给24L01的寄存器写值(多个字节) */
  119. /* 入口参数:reg 要写的寄存器地址 */
  120. /* *pBuf 值的存放数组 */
  121. /* len 数组字节长度 */
  122. /**********************************************/
  123. uchar NRF24L01_Write_Buf ( uchar reg, uchar *pBuf, uchar len )
  124. {
  125. uchar status, u8_ctr;
  126. NRF_CSN = 0;
  127. status = SPI_RW ( reg ); //发送寄存器值(位置),并读取状态值
  128. for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ )
  129. {
  130. SPI_RW ( *pBuf++ ); //写入数据
  131. }
  132. NRF_CSN = 1;
  133. return status; //返回读到的状态值
  134. }
  135. /*********************************************/
  136. /* 函数功能:24L01接收数据 */
  137. /* 入口参数:rxbuf 接收数据数组 */
  138. /* 返回值: 0 成功收到数据 */
  139. /* 1 没有收到数据 */
  140. /*********************************************/
  141. uchar NRF24L01_RxPacket ( uchar *rxbuf, uchar rxlen )
  142. {
  143. uchar state;
  144. uchar res = 0;
  145. state = NRF24L01_Read_Reg ( STATUS ); //读取状态寄存器的值
  146. if ( state & RX_DR ) //接收到数据
  147. {
  148. state &= ~RX_DR;
  149. NRF_CE = 0; //配置前
  150. rxlen = ( rxlen < RX_PLOAD_WIDTH ) ? ( rxlen ) : ( RX_PLOAD_WIDTH );
  151. NRF24L01_Read_Buf ( RD_RX_PLOAD, rxbuf, RX_PLOAD_WIDTH ); //读取数据
  152. NRF24L01_Write_Reg ( FLUSH_RX, 0xff ); //清除RX FIFO寄存器
  153. NRF_CE = 1; //配置完,使能收发
  154. delay_us ( 150 );
  155. res = 1;
  156. }
  157. NRF24L01_Write_Reg ( WRITE_REG + STATUS, state ); //清除TX_DS或MAX_RT中断标志
  158. return res;//没收到任何数据
  159. }
  160. /**********************************************/
  161. /* 函数功能:设置24L01为发送模式 */
  162. /* 入口参数:txbuf 发送数据数组 */
  163. /* 返回值; 0x10 达到最大重发次数,发送失败*/
  164. /* 0x20 成功发送完成 */
  165. /* 0xff 发送失败 */
  166. /**********************************************/
  167. uchar NRF24L01_TxPacket ( uchar *txbuf, uchar txlen )
  168. {
  169. uchar res = 1;
  170. uchar state;
  171. uint16 i;
  172. NRF_CE = 0; //CE拉低,使能24L01配置
  173. txlen = ( txlen < TX_PLOAD_WIDTH ) ? ( txlen ) : ( TX_PLOAD_WIDTH );
  174. NRF24L01_Write_Buf ( WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH ); //写数据到TX BUF 32个字节
  175. NRF_CE = 1; //CE置高,使能发送
  176. for ( i = 0; i < 60; i++ ) //(500+86)us*10
  177. {
  178. delay_us(100);
  179. if ( NRF_IRQ == 1 )
  180. {
  181. break; //等待发送完成
  182. }
  183. }
  184. state = NRF24L01_Read_Reg ( STATUS ); //读取状态寄存器的值
  185. if ( state & MAX_RT ) //达到最大重发次数
  186. {
  187. NRF24L01_Write_Reg ( FLUSH_TX, 0xff ); //清除TX FIFO寄存器
  188. state &= ~MAX_RT;
  189. res = 0;
  190. }
  191. if ( state & TX_DS ) //发送完成
  192. {
  193. state &= ~TX_DS;
  194. res = 0;
  195. }
  196. NRF24L01_Write_Reg ( WRITE_REG + STATUS, state ); //清除TX_DS或MAX_RT中断标志
  197. return res; //发送失败
  198. }
  199. /********************************************/
  200. /* 函数功能:检测24L01是否存在 */
  201. /* 返回值; 1 存在 */
  202. /* 0 不存在 */
  203. /********************************************/
  204. uchar NRF24L01_Check ( void )
  205. {
  206. uchar res = 0;
  207. uchar check_in_buf[5] = {0x11, 0x22, 0x33, 0x44, 0x55};
  208. uchar check_out_buf[5] = {0x00};
  209. NRF_SCK = 0;
  210. NRF_CSN = 1;
  211. NRF_CE = 0;
  212. NRF24L01_Write_Buf ( WRITE_REG + TX_ADDR, check_in_buf, 5 );
  213. NRF24L01_Read_Buf ( READ_REG + TX_ADDR, check_out_buf, 5 );
  214. if ( ( check_out_buf[0] == 0x11 ) && \
  215. ( check_out_buf[1] == 0x22 ) && \
  216. ( check_out_buf[2] == 0x33 ) && \
  217. ( check_out_buf[3] == 0x44 ) && \
  218. ( check_out_buf[4] == 0x55 ) )
  219. {
  220. res = 1;
  221. }
  222. return res;
  223. }
  224. uint16 NRF24L01_Wait_Check ( void )
  225. {
  226. uint16 i;
  227. for ( i = 0; i < 50; i++ )
  228. {
  229. if ( NRF24L01_Check() )
  230. {
  231. break; //等待发送完成
  232. }
  233. Timer3_Delay10us ( 10 );
  234. }
  235. return i;
  236. }
  237. /**********************************************/
  238. /* 函数功能:24L01初始化 */
  239. /* 入口参数:PLOAD_WIDTH 有效数据宽度 */
  240. /* TX_ADR 发送地址 */
  241. /* TX_ADDR_WIDTH 发送地址宽度 */
  242. /* RX_ADR 接收发送地址 */
  243. /* RX_ADDR_WIDTH 接收地址宽度 */
  244. /* RATE 有效数据宽度 */
  245. /* 返回值 ;无 */
  246. /**********************************************/
  247. void NRF24L01_RT_Init ( void )
  248. {
  249. NRF_CE = 0;
  250. NRF24L01_Write_Reg ( WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH ); //设置接收数据长度,本次设置为32字节
  251. NRF24L01_Write_Reg ( FLUSH_RX, 0xff ); //清除RX FIFO寄存器
  252. NRF24L01_Write_Buf ( WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH ); //写TX节点地址
  253. NRF24L01_Write_Buf ( WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH ); //设置RX节点地址,主要为了使能ACK
  254. NRF24L01_Write_Reg ( WRITE_REG + EN_AA, 0x05 ); //使能通道0的自动应答
  255. NRF24L01_Write_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); //使能通道0的接收地址
  256. NRF24L01_Write_Reg ( WRITE_REG + FEATURE, 0x00 ); //使能动态数据包长度,AUTO_ACK模式
  257. NRF24L01_Write_Reg ( WRITE_REG + DYNPD, 0x01 ); //选择通道0动态数据包长度
  258. NRF24L01_Write_Reg ( WRITE_REG + SETUP_RETR, 0x1a ); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10(a)次
  259. NRF24L01_Write_Reg ( WRITE_REG + RF_CH, 40 ); //设置RF通道为40 收发必须一致,0为2.4GHz + 40
  260. NRF24L01_Write_Reg ( WRITE_REG + RF_SETUP, 0x0f ); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
  261. NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0f ); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
  262. NRF_CE = 1; //CE置高,使能发送
  263. delay_us ( 130 );
  264. }
  265. /**********************************************/
  266. /* 函数功能:发射函数 */
  267. /* 入口参数:buf 发送寄存器 */
  268. /* 返回值 ;无 */
  269. /**********************************************/
  270. /*
  271. nRF24L01 可以设置为以下几种主要的模式,
  272. 模式 PWR_UP PRIM_RX CE FIFO 寄存器状态
  273. 接收模式 1 1 1 -
  274. 发送模式 1 0 1 数据在 TX FIFO 寄存器中
  275. 发送模式 1 0 1→0 停留在发送模式,直至数据发送完
  276. 待机模式II 1 0 1 TX FIFO 为空
  277. 待机模式I 1 - 0 无数据传输
  278. 掉电模式 0 - - -
  279. CONFIG[0] PRIM_RX: 1:接收模式 0:发射模式
  280. CONFIG[1] PWR_UP: 1:上电 0:掉电
  281. */
  282. uchar SEND_BUF ( uchar *buf, uchar len )
  283. {
  284. uchar state;
  285. NRF_CE = 0;
  286. NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0e ); //CONFIG[0] PRIM_RX=0.发射
  287. NRF_CE = 1;
  288. delay_us ( 10 );
  289. state = NRF24L01_TxPacket ( buf, len );
  290. NRF_CE = 0;
  291. NRF24L01_Write_Reg ( WRITE_REG + CONFIG, 0x0f ); //CONFIG[0] PRIM_RX=0.发射
  292. NRF_CE = 1;
  293. delay_us ( 130 );
  294. return state;
  295. }