C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 1 C51 COMPILER V9.53.0.0, COMPILATION OF MODULE NRF24L01 OBJECT MODULE PLACED IN .\Output\nrf24l01.obj COMPILER INVOKED BY: D:\Keil_v5\C51\BIN\C51.EXE ..\..\Code\User\Driver\nrf24l01.c LARGE OPTIMIZE(0,SPEED) BROWSE INCDIR( -../../Code/Include;../../Code/User;../../Code/User/Common;../../Code/User/Driver) DEFINE(FOSC_160000=1) DEBUG OBJECTEXTE -ND PRINT(.\Output\LST\nrf24l01.lst) TABS(2) OBJECT(.\Output\nrf24l01.obj) line level source 1 #include "nrf24l01.h" 2 const u8 TX_ADDRESS [TX_ADR_WIDTH]={0x60,0x20,0x30,0x40,0x50}; //发送地址 3 4 const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0x10,0x20,0x30,0x40,0x50}; //接收地址 5 const u8 RX_ADDRESS1[RX_ADR_WIDTH]={0x20,0x20,0x30,0x40,0x50}; //接收地址 6 const u8 RX_ADDRESS2[1 ]={0x30}; //接收地址 7 const u8 RX_ADDRESS3[1 ]={0x40}; //接收地址 8 const u8 RX_ADDRESS4[1 ]={0x50}; //接收地址 9 const u8 RX_ADDRESS5[1 ]={0x60}; //接收地址 10 11 12 13 /************************************************* 14 * 函数名称:InitNrf24L01 15 * 功能描述:初始NRF24L01,包括对IRQ引脚的初始化 16 * 输入参数:无 17 * 输出参数:无 18 * 返回值: 返回0成功,返回1失败 19 **************************************************/ 20 u8 InitNrf24L01(void) 21 { 22 1 #if 0 GPIO_InitTypeDef GPIO_InitStructure; //使能GPIO 的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); #endif 35 1 //芯片失能 36 1 NRF_CE_H; 37 1 //没有中断 38 1 IRQ_H; 39 1 //SPI失能 40 1 CSN_H; 41 1 //MUC对nrf的中断配置 42 1 NrfIsrCfg(); 43 1 return Nrf24L01Check(); 44 1 } 45 46 /************************************************* 47 * 函数名称:SpiReadWriteByte 48 * 功能描述:主、从机交换8位数据 49 * 输入参数:- TxData:主机发送的数据 50 * 输出参数:无 51 * 返回值: 从机发送的数据 52 **************************************************/ 53 #if 0 C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 2 u8 SpiReadWriteByte(u8 TxData) { u8 i; NRF_SCK_L;//拉低时钟 for(i=0;i<8;i++) { if(TxData & 0x80) MOSI_H; else MOSI_L; //移空最低位,丢弃最高位 TxData = (TxData << 1); //写从设备 NRF_SCK_H; //读从设备 if(READ_MISO) //保存读取的数据 TxData |= 0x01; //拉低时钟线.完成一次数据交换(SR和BUF) NRF_SCK_L; } return(TxData); } #else 78 unsigned char SpiReadWriteByte ( unsigned char byte ) 79 { 80 1 unsigned char i; 81 1 SPDR = byte; //写寄存器 82 1 83 1 for ( i = 0; i < 255; i++ ) 84 1 { 85 2 if ( SPSR & SET_BIT7 ) 86 2 { 87 3 break; //等待传输 88 3 } 89 2 } 90 1 91 1 SPSR &= ~SET_BIT7; 92 1 byte = SPDR; //读寄存器 93 1 return byte; 94 1 } 95 #endif 96 97 /************************************************* 98 * 函数名称:Nrf24l01ReadWriteBus 99 * 功能描述:主、从机交换多个字节数据 100 * 输入参数:- cmd:指令; 101 - data:主机发送的数据 102 * 输出参数:- data:从机发送的数据 103 * 返回值: 无 104 **************************************************/ 105 void Nrf24l01ReadWriteBus(u8 cmd,u8 Data[],u8 cnt) 106 { 107 1 //1、使能SPI传输 108 1 //2、发送指令 109 1 //3、发送、接收数据 110 1 //4、失能SPI传输 111 1 u8 i; 112 1 CSN_L; 113 1 SpiReadWriteByte(cmd); 114 1 for(i = 0; i < cnt; i++) 115 1 { C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 3 116 2 Data[i] = SpiReadWriteByte(Data[i]); 117 2 } 118 1 CSN_H; 119 1 } 120 /************************************************* 121 * 函数名称:Nrf24L01Check 122 * 功能描述:检测NRF24L01是否存在 123 * 输入参数:无 124 * 输出参数:无 125 * 返回值: 返回0存在,返回1不存在 126 **************************************************/ 127 u8 Nrf24L01Check(void) 128 { 129 1 u8 a[5]={0XA0,0XA1,0XA2,0XA3,0XA4}; 130 1 u8 b[5]; 131 1 u8 i; 132 1 for(i=0;i<5;i++)b[i]=a[i]; 133 1 //写入5个字节. 134 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+TX_ADDR,a,5); 135 1 //读出写入的5个字节 136 1 Nrf24l01ReadWriteBus(SPI_READ_REG+TX_ADDR,a,5); 137 1 for(i=0;i<5;i++) 138 1 { 139 2 if(a[i]!=b[i]) break; 140 2 } 141 1 if(i!=5) return 1; //NRF24L01不在位 142 1 return 0; //NRF24L01在位 143 1 } 144 /************************************************* 145 * 函数名称:Nrf24L01SendPacket 146 * 功能描述:启动NRF24L01发送一次数据 147 * 输入参数:- tx_buf:要发送的数据 148 * 输出参数:无 149 * 返回值: 无 150 **************************************************/ 151 void Nrf24L01SendPacket(u8 *tx_buf) 152 { 153 1 u8 result,Data[TX_PLOAD_WIDTH]; 154 1 //失能芯片,进入配置模式 155 1 NRF_CE_L; 156 1 //数据复制,不希望原数据被更改 157 1 for(result=0;result>1); 179 1 //读取数据 180 1 Nrf24l01ReadWriteBus(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH); 181 1 //清除中断标志位 182 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+STATUS,&result,1); 183 1 //清空接收FIFO,读取之后自动清空,若不读取,必须清空, 否则nrf24l01无法正常工作:不能产生中断信号 184 1 //Nrf24l01ReadWriteBus(FLUSH_RX,&result,1); 185 1 //返回接收的通道号 186 1 return channel; 187 1 } 188 189 /************************************************* 190 * 函数名称:Nrf24l01SendSuccessHandler 191 * 功能描述:发送数据成功中断处理函数 192 * 输入参数:无 193 * 输出参数:无 194 * 返回值: 无 195 **************************************************/ 196 void Nrf24l01SendSuccessHandler(void) 197 { 198 1 u8 Data; 199 1 //读取状态寄存器 200 1 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,&Data,1); 201 1 //清除所有中断标志位 202 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+STATUS,&Data,1); 203 1 //清除TX FIFO寄存器,发送成功,自动清除 204 1 // Nrf24l01ReadWriteBus(FLUSH_TX,&data,1); 205 1 } 206 207 /************************************************* 208 * 函数名称:Nrf24l01SendFailHandler 209 * 功能描述:发送数据失败中断处理函数 210 * 输入参数:无 211 * 输出参数:无 212 * 返回值: 无 213 **************************************************/ 214 void Nrf24l01SendFailHandler(void) 215 { 216 1 u8 Data; 217 1 //读取状态寄存器 218 1 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,&Data,1); 219 1 //清除所有中断标志位 220 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+STATUS,&Data,1); 221 1 //清除TX FIFO寄存器,发送失败,必须手动清除,否则nrf24l01不能正常工作 222 1 Nrf24l01ReadWriteBus(FLUSH_TX,&Data,1); 223 1 } 224 225 /************************************************* 226 * 函数名称:Nrf24l01GetMode 227 * 功能描述:配置NRF24L01到接收模式 228 * 输入参数:无 229 * 输出参数:无 230 * 返回值: 无 231 **************************************************/ 232 void Nrf24l01GetMode(void) 233 { 234 1 u8 Data[RX_ADR_WIDTH],i; 235 1 //芯片失能,模块进入配置模式 236 1 NRF_CE_L; 237 1 //写RX节点地址,注意,是先写低位地址的,通道0可以拥有独立的40位地址。通道1-5的最低位字节地址不一样,其 -他必须一样 238 1 for(i=0;i2Mbps 0->1Mbps 289 1 Data[0]|=1<<3; 290 1 //bit2-bit1:发射功率, 291 1 //00:-18dBm 01:-12dBm 10:-6dBm 11:0dBm 292 1 Data[0]|=0<<1; 293 1 //bit0:低噪声放大器增益,1开启0关闭 294 1 Data[0]|=0<<0; 295 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+RF_SETUP,Data,1); 296 1 Data[0]=0; 297 1 //bit6:接收中断,1屏蔽,0不屏蔽 298 1 Data[0]|=0<<6; 299 1 //bit5:发送中断,1屏蔽,0不屏蔽 300 1 Data[0]|=0<<5; C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 6 301 1 //bit4:达到最大重发中断,1屏蔽,0不屏蔽 302 1 Data[0]|=0<<4; 303 1 //bit3:CRC使能,1使能,0不使能 304 1 Data[0]|=1<<3; 305 1 //bit2:CRC模式,1->16位CRC校验,0->8位CRC校验 306 1 Data[0]|=1<<2; 307 1 //bit1:1上电0掉电 308 1 Data[0]|=1<<1; 309 1 //bit0:1接收模式0发送模式 310 1 Data[0]|=1<<0; 311 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+CONFIG, Data,1); 312 1 //必须先清空接收FIFO否则nrf不能产生中断信号 313 1 //如果此时mcu使用接收中断的方式处理,就无法进 314 1 //入中断,IRQ一直保持低电平或高电平,若清除了 315 1 //标志位,就一直保持高电平,否则一直保持低电 316 1 //平。若使用查询方式,那么不必执行清空接收 317 1 //FIFO但有可能第一次接收到错误的数据 318 1 Nrf24l01ReadWriteBus(FLUSH_RX,Data,1); 319 1 //读取状态寄存器的值 320 1 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,Data,1); 321 1 //清除所有的标志位,否则进入工作模式后IRQ一直为低 322 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+STATUS,Data,1); 323 1 //芯片使能,进入接收模式 324 1 NRF_CE_H; 325 1 } 326 327 /************************************************* 328 * 函数名称:Nrf24l01SendMode 329 * 功能描述:配置NRF24L01到发送模式 330 * 输入参数:无 331 * 输出参数:无 332 * 返回值: 无 333 **************************************************/ 334 void Nrf24l01SendMode(void) 335 {// 336 1 u8 Data[TX_ADR_WIDTH],i; 337 1 //地址复制,不希望原数据被更改 338 1 for(i=0;i2Mbps 0->1Mbps 368 1 Data[0]|=1<<3; 369 1 //bit2-bit1:发射功率, 370 1 //00:-18dBm 01:-12dBm 10:-6dBm 11:0dBm 371 1 Data[0]|=0<<1; 372 1 //bit0:低噪声放大器增益,1开启0关闭 373 1 Data[0]|=0<<0; 374 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+RF_SETUP,Data,1); 375 1 Data[0]=0; 376 1 //bit6:接收中断,1屏蔽,0不屏蔽 377 1 Data[0]|=0<<6; 378 1 //bit5:发送中断,1屏蔽,0不屏蔽 379 1 Data[0]|=0<<5; 380 1 //bit4:达到最大重发中断,1屏蔽,0不屏蔽 381 1 Data[0]|=0<<4; 382 1 //bit3:CRC使能,1使能,0不使能 383 1 Data[0]|=1<<3; 384 1 //bit2:CRC模式,1->16位CRC校验,0->8位CRC校验 385 1 Data[0]|=1<<2; 386 1 //bit1:1上电0掉电 387 1 Data[0]|=1<<1; 388 1 //bit0:1接收模式0发送模式 389 1 Data[0]|=0<<0; 390 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+CONFIG,Data,1); 391 1 //清空发送FIFO 392 1 Nrf24l01ReadWriteBus(FLUSH_TX,Data,1); 393 1 //读取状态寄存器 394 1 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,Data,1); 395 1 //清除所有中断标志位 396 1 Nrf24l01ReadWriteBus(SPI_WRITE_REG+STATUS,Data,1); 397 1 //芯片使能,进入发送模式 398 1 NRF_CE_H; 399 1 } 400 401 /************************************************* 402 * 函数名称:NrfIsrCfg 403 * 功能描述:配置NRF24L01 IRQ引脚中断io 404 * 输入参数:无 405 * 输出参数:无 406 * 返回值: 无 407 **************************************************/ 408 void NrfIsrCfg(void) 409 { 410 1 #if 0 //1、时钟使能。 //2、muc外部中断引脚的配置 //3、中断优先级的配置 GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; //清除中断标志位 EXTI_ClearITPendingBit(0x1f<<5); //开启复用功能时钟和io时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6; GPIO_Init(GPIOA,&GPIO_InitStructure); //配置中断源 C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 8 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource6); //外部中断线配置 EXTI_InitStruct.EXTI_Line=EXTI_Line6; EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿触发 EXTI_Init( &EXTI_InitStruct); //优先级配置 NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0x3; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0x3; NVIC_Init(&NVIC_InitStruct); #else 439 1 /* 440 1 NRF24L01_Interrupt_P03 441 1 442 1 PIPEN 中断使能 443 1 PINEN 正反向特性 444 1 PICON 触发方式(电平或边沿检测) 445 1 PIF 中断标志 446 1 */ 447 1 //P0M1|=SET_BIT3;P0M2&=~SET_BIT3; //input 448 1 PICON &= ~ ( SET_BIT0 | SET_BIT1 ); 449 1 PICON |= ( 0x00 ); //[1:0]=0.端口0 450 1 PICON |= SET_BIT5; //通道3=1.边沿触发 451 1 PINEN |= SET_BIT3; // 1 = 低电平/ 下降沿触发中断 452 1 PIPEN &= ~SET_BIT3; //0 = 关闭中断(高电平/ 上升沿触发中断) 453 1 EIE |= SET_BIT1; //管脚中断,最多8个,中断号7 454 1 EA = 1; // 总中断 455 1 #endif 456 1 } 457 458 459 460 static u8 rx_data[33]; 461 static u8 channel; 462 #if 0 void EXTI9_5_IRQHandler() { u8 Data; //判断中断源 if(RESET != EXTI_GetITStatus(EXTI_Line6)) { //读取nrf24l01的状态寄存器 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,&data,1); if(Data&(1<<4)) { Nrf24l01SendFailHandler(); printf("达到最大重发数中断\r\n"); } if(Data&(1<<5)) { printf("数据发送完成中断\r\n"); Nrf24l01SendSuccessHandler(); } if(Data&(1<<6)) { channel = Nrf24l01GetPacketHandler(rx_data); printf("接收数据中断 接收的数据威:%s 接收通道为%d\r\n",rx_data,channel); } } C51 COMPILER V9.53.0.0 NRF24L01 09/28/2018 11:35:59 PAGE 9 //清除EXTI中断标志位 EXTI_ClearITPendingBit(EXTI_Line6); } #else 491 //NRF24L01中断处理:当状态寄存器中 TX_DS、 RX_DR 或 MAX_RT 为高时触发中断。 492 #ifdef N76E003_IAR #pragma vector=0x3B __interrupt void NRF24L01_Handler ( void ) #else 496 void NRF24L01_Handler ( void ) interrupt 7 //interrupt address is 0x001B 497 #endif 498 { 499 1 u8 Data; 500 1 clr_EPI; //关闭管脚中断7 501 1 502 1 //判断中断源 503 1 if(PIF&SET_BIT3) 504 1 { 505 2 //读取nrf24l01的状态寄存器 506 2 Nrf24l01ReadWriteBus(SPI_READ_REG+STATUS,&Data,1); 507 2 if(Data&(1<<4)) 508 2 { 509 3 Nrf24l01SendFailHandler(); 510 3 //printf("达到最大重发数中断\r\n"); 511 3 } 512 2 if(Data&(1<<5)) 513 2 { 514 3 Nrf24l01SendSuccessHandler(); 515 3 //printf("数据发送完成中断\r\n"); 516 3 } 517 2 if(Data&(1<<6)) 518 2 { 519 3 channel = Nrf24l01GetPacketHandler(rx_data); 520 3 //printf("接收数据中断 接收的数据威:%s 接收通道为%d\r\n",rx_data,channel); 521 3 } 522 2 } 523 1 PIF = 0x00; //清除全部标志 524 1 525 1 set_EPI; //开启管脚中断7 526 1 } 527 #endif MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 2037 ---- CONSTANT SIZE = 5 ---- XDATA SIZE = 128 ---- PDATA SIZE = ---- ---- DATA SIZE = ---- ---- IDATA SIZE = ---- ---- BIT SIZE = ---- ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)