2fe076ea67609355207aeeac78f3a595374f7cef.svn-base 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "NRF24L01.H"
  2. unsigned char RF_CH = 0x40; //RF频道
  3. unsigned char NRF24L01_FLAG = 0; //NRF24L01当前状态标志
  4. //DB7; 1接收模式 0发射模式
  5. //DB6; 1有任务 0空闲
  6. //DB5; 1发送成功 0发送失败(配合DB6检测是否发送成功)
  7. //DB4; 1NRF正常连接 0 检测不到连接
  8. //DB3; 1接收到数据包 0 缓冲区无数据
  9. //DB2; 1 ACK模式 0 NOACK模式
  10. //DB1; 1发送完自动进入接收模式 0关闭自动切换模式
  11. unsigned char DYNPD_LEN = 0; //用于存放动态数据包长度
  12. unsigned char TX_ADDRESS[NRF24L01_ADR_LEN] = {0x12, 0x34, 0x56, 0x78, 0x90}; //本地地址
  13. unsigned char RX_ADDRESS[NRF24L01_ADR_LEN] = {0x12, 0x34, 0x56, 0x78, 0x90}; //接收地址
  14. //向从机发送一个字节数据并返回接收数据
  15. /**************************************************/
  16. unsigned char SPI_WriteRead ( unsigned char byte )
  17. {
  18. unsigned char bit_ctr;
  19. for ( bit_ctr = 0; bit_ctr < 8; bit_ctr++ ) // 输出8位
  20. {
  21. NRF_MOSI = ( byte & 0x80 ); // MSB TO MOSI
  22. byte = ( byte << 1 ); // shift next bit to MSB
  23. NRF_SCK = 1;
  24. byte |= NRF_MISO; // capture current MISO bit
  25. NRF_SCK = 0;
  26. }
  27. return byte;
  28. }
  29. //写NRF24L01寄存器,返回状态值
  30. unsigned char NRF24L01_Write_Reg ( unsigned char reg, unsigned char value )
  31. {
  32. unsigned char BackDate;
  33. NRF_CSN = 0;
  34. SPI_WriteRead ( reg );
  35. BackDate = SPI_WriteRead ( value );
  36. NRF_CSN = 1;
  37. return ( BackDate );
  38. }
  39. //读NRF24L01寄存器,返回寄存器值
  40. unsigned char NRF24L01_Read_Reg ( unsigned char reg )
  41. {
  42. unsigned char BackDate;
  43. NRF_CSN = 0;
  44. SPI_WriteRead ( reg );
  45. BackDate = SPI_WriteRead ( 0x00 );
  46. NRF_CSN = 1;
  47. return ( BackDate );
  48. }
  49. //读取缓冲区数据
  50. void NRF24L01_Read_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char bytes )
  51. {
  52. unsigned char byte_ctr;
  53. NRF_CSN = 0;
  54. SPI_WriteRead ( reg );
  55. for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ )
  56. {
  57. pBuf[byte_ctr] = SPI_WriteRead ( 0x00 );
  58. }
  59. NRF_CSN = 1;
  60. }
  61. //向缓冲区写入数据
  62. unsigned char NRF24L01_Write_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char bytes )
  63. {
  64. unsigned char status, byte_ctr;
  65. NRF_CSN = 0;
  66. status = SPI_WriteRead ( reg );
  67. for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ )
  68. {
  69. SPI_WriteRead ( *pBuf++ );
  70. }
  71. NRF_CSN = 1;
  72. return ( status );
  73. }
  74. /*
  75. PIPEN 中断使能
  76. PINEN 正反向特性
  77. PICON 触发方式(电平或边沿检测)
  78. PIF 中断标志
  79. */
  80. void NRF24L01_Interrupt_P03 ( void )
  81. {
  82. //P0M1|=SET_BIT3;P0M2&=~SET_BIT3; //input
  83. PICON &= ~ ( SET_BIT0 | SET_BIT1 );
  84. PICON |= ( 0x00 ); //[1:0]=0.端口0
  85. PICON |= SET_BIT5; //通道3=1.边沿触发
  86. PINEN |= SET_BIT3; // 1 = 低电平/ 下降沿触发中断
  87. PIPEN &= ~SET_BIT3; //0 = 关闭中断(高电平/ 上升沿触发中断)
  88. EIE |= SET_BIT1; //管脚中断,最多8个,中断号7
  89. EA = 1; // 总中断
  90. }
  91. //NRF24L01初始化函数
  92. void NRF24L01_Init ( void )
  93. {
  94. #if BK2423
  95. NRF_CE = 0;
  96. NRF24L01_Write_Reg ( ACTIVATE_CMD, 0x73 );
  97. NRF_CE = 1;
  98. #endif
  99. NRF_CSN = 1; // Spi disable
  100. NRF_SCK = 0; // Spi clock line init high
  101. NRF_CE = 0;
  102. //配置寄存器
  103. NRF24L01_FLAG |= NRF24L01_AUTO_ACK; //是否开启应答模式
  104. NRF24L01_FLAG |= NRF24L01_AUTO_RX; //发送完是否自动进入接收模式
  105. //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_SETUP_RETR, 0x25); // [3:0]'0101'-重发5次 [7:4]'0010'-750+86us
  106. //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_RF_CH, 0x00); // [6:0]射频通道(工作频率)
  107. //NRF24L01_Write_Reg(NRF24L01_WRITE_REG + NRF24L01_RF_SETUP, 0x0e); // [0]低噪声放大器增益 [2:1]'11'-0dBm [3]'1'-2 Mbps
  108. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_SETUP_AW, NRF24L01_ADR_LEN - 2 ); //设置地址长度为 NRF24L01_ADR_LEN
  109. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_CH, RF_CH ); //设置RF通道为RFCH [6:0]
  110. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_SETUP, 0x07 ); //设置TX发射参数,7db增益,1Mbps,低噪声增益开启
  111. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_EN_AA, 0x01 ); //使能通道0的自动应答
  112. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_EN_RXADDR, 0x01 ); //使能通道0的接收地址
  113. //RX模式配置
  114. NRF24L01_Write_Buf ( NRF24L01_WRITE_REG | NRF24L01_RX_ADDR_P0, RX_ADDRESS, NRF24L01_ADR_LEN ); //写RX节点地址
  115. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FEATURE, 0x05 ); //使能动态数据包长度,AUTO_ACK模式
  116. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_DYNPD, 0X01 ); //选择通道0动态数据包长度
  117. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_RX, NRF24L01_NOP ); //清除RX FIFO寄存器
  118. //TX模式配置
  119. NRF24L01_Write_Buf ( NRF24L01_WRITE_REG | NRF24L01_TX_ADDR , TX_ADDRESS, NRF24L01_ADR_LEN ); //写TX节点地址
  120. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_SETUP_RETR, 0x1f ); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:15次
  121. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器
  122. NRF24L01_RxMode(); //默认进入接收模式
  123. NRF_CE = 1;
  124. //NRF24L01_Change_Ch(1); //更改通道0~5
  125. NRF24L01_Interrupt_P03();
  126. }
  127. //NRF24L01进入发送模式
  128. void NRF24L01_TxMode ( void )
  129. {
  130. NRF_CE = 0;
  131. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_CONFIG, 0x0e );
  132. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, 0x70 ); //清除中断标志
  133. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器
  134. NRF_CE = 1;
  135. NRF24L01_FLAG &= ~NRF24L01_MODE_RX; //修改状态标识为发射模式
  136. NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0
  137. NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志
  138. }
  139. //NRF24L01进入接收模式
  140. void NRF24L01_RxMode ( void )
  141. {
  142. NRF_CE = 0;
  143. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_CONFIG, 0x0f ); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
  144. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, 0x70 ); //清除中断标志
  145. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_RX, NRF24L01_NOP ); //清除RX FIFO寄存器
  146. NRF_CE = 1;
  147. NRF24L01_FLAG |= NRF24L01_MODE_RX; //修改状态标识为接收模式
  148. NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0
  149. DYNPD_LEN = 0; //清0动态数据包长度
  150. NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志
  151. }
  152. //NRF24L01 SPI通信检查
  153. void NRF24L01_Check ( void )
  154. {
  155. unsigned char i = 0;
  156. unsigned char Buff[5];
  157. NRF24L01_Read_Buf ( NRF24L01_TX_ADDR, Buff, NRF24L01_ADR_LEN );
  158. i = NRF24L01_Read_Reg ( NRF24L01_DYNPD ); //读取DYNPD监测是否正确写入
  159. if ( i == 0x01 ) //这里设置的是0x01,要与初始化的值相对应
  160. {
  161. for ( i = 0; i < NRF24L01_ADR_LEN; i++ )
  162. {
  163. if ( Buff[i] == TX_ADDRESS[i] )
  164. {
  165. NRF24L01_FLAG |= NRF24L01_CHECK;
  166. }
  167. else
  168. {
  169. NRF24L01_FLAG &= ~NRF24L01_CHECK;
  170. break;
  171. }
  172. }
  173. }
  174. else NRF24L01_FLAG &= ~NRF24L01_CHECK;
  175. }
  176. //NRF24L01发送数据
  177. void NRF24L01_SendFrame ( unsigned char *temp, unsigned char len )
  178. {
  179. if ( NRF24L01_FLAG & NRF24L01_MODE_RX )
  180. {
  181. NRF24L01_TxMode();
  182. }
  183. NRF24L01_FLAG |= NRF24L01_BUSY; //BUSY标志置1
  184. NRF24L01_FLAG &= ~NRF24L01_TX_ACCESS;//清除发送成功标志
  185. NRF_CE = 0;
  186. if ( NRF24L01_FLAG & NRF24L01_AUTO_ACK )
  187. {
  188. NRF24L01_Write_Buf ( NRF24L01_WR_TX_PLOAD, temp, len ); //写待发数据包,需要回应
  189. }
  190. else
  191. {
  192. NRF24L01_Write_Buf ( W_TX_PAYLOAD_NOACK_CMD, temp, len ); //写待发数据包,无须回应
  193. }
  194. NRF_CE = 1;
  195. }
  196. //NRF24L01接收数据
  197. void NRF24L01_RecvFrame ( unsigned char *temp )
  198. {
  199. DYNPD_LEN = NRF24L01_Read_Reg ( R_RX_PL_WID_CMD );
  200. if ( DYNPD_LEN > 32 )
  201. {
  202. NRF24L01_RxMode(); //重新初始化接收模式
  203. }
  204. else
  205. {
  206. NRF24L01_Read_Buf ( NRF24L01_RD_RX_PLOAD, temp, DYNPD_LEN ); //读取缓冲区数据
  207. }
  208. NRF24L01_FLAG &= ~NRF24L01_RECIVE;//清除有数据标志
  209. }
  210. //更改RF_CH
  211. void NRF24L01_Change_Ch ( unsigned char ch )
  212. {
  213. NRF_CE = 0;
  214. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_RF_CH, ch & 0x7F ); //设置RF频道
  215. RF_CH = ch & 0x7F; //同步设置到系统参数
  216. }
  217. //NRF24L01中断处理
  218. #ifdef N76E003_IAR
  219. #pragma vector=0x3B
  220. __interrupt void NRF24L01_Handler ( void )
  221. #else
  222. void NRF24L01_Handler ( void ) interrupt 7 //interrupt address is 0x001B
  223. #endif
  224. {
  225. unsigned char state, fifo_state, flag;
  226. clr_EPI; //关闭管脚中断7
  227. flag = PIF;
  228. PIF = 0x00; //清除全部标志
  229. state = NRF24L01_Read_Reg ( NRF24L01_STATUS ); //读NRF24L01状态寄存器
  230. fifo_state = NRF24L01_Read_Reg ( NRF24L01_FIFO_STATUS ); //读NRF24L01FIFO状态寄存器
  231. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_STATUS, state ); //清除中断
  232. //发送成功中断
  233. if ( state & NRF24L01_STATUS_TX_DS )
  234. {
  235. NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0
  236. NRF24L01_FLAG |= NRF24L01_TX_ACCESS;//发送成功标志置1
  237. if ( NRF24L01_FLAG & NRF24L01_AUTO_RX )
  238. {
  239. NRF24L01_RxMode(); //重新初始化接收模式
  240. }
  241. }
  242. //达到最大重发次数中断
  243. if ( state & NRF24L01_STATUS_MAX_RT )
  244. {
  245. NRF24L01_Write_Reg ( NRF24L01_WRITE_REG | NRF24L01_FLUSE_TX, NRF24L01_NOP ); //清除TX FIFO寄存器
  246. NRF24L01_FLAG &= ~NRF24L01_BUSY; //BUSY标志置0
  247. NRF24L01_FLAG &= ~NRF24L01_TX_ACCESS;//发送成功标志置0
  248. }
  249. //接收到数据中断
  250. if ( state & NRF24L01_STATUS_RX_DR )
  251. {
  252. NRF24L01_FLAG |= NRF24L01_RECIVE; //接收到数据标志位置1
  253. }
  254. //TX_FIFO满中断
  255. if ( state & NRF24L01_STATUS_TX_FULL )
  256. {
  257. NRF24L01_TxMode(); //重新初始化发射模式
  258. }
  259. //RX_FIFO满
  260. if ( fifo_state & NRF24L01_STATUS_RX_FULL )
  261. {
  262. NRF24L01_RxMode(); //重新初始化接收模式
  263. }
  264. state = NRF24L01_Read_Reg ( NRF24L01_STATUS ); //读NRF24L01状态寄存器
  265. set_EPI; //开启管脚中断7
  266. }