stc51单片机硬件SPI驱动nrf24l01程序
stc51系类单片机大多数带SPI模块,例如STC12C5608AD,就带有SPI口,可以直接用此SPI口驱动nrf24l01,省去模拟SPI的麻烦。
spi初始化代码如下:
void SPI_Init(void) { ?? ?SPSTAT |= 0XC0; // 清高两位, ?? ?SPCTL = 0XD0; // 设置为主模式,开SPI }
spi收发数据代码如下:
uchar SPI_RW(uchar tr_data) { uchar i=0; SPSTAT |= 0Xc0; // 清高两位, SPDAT=tr_data; while(((SPSTAT&0X80)!=0X80)&&(i<20)) { i++; delay_ms(1); } return SPDAT; }
spi写nrf24l01寄存器代码:
/*********************************************/ /* 函数功能:给24L01的寄存器写值(一个字节) */ /* 入口参数:reg?? 要写的寄存器地址????????? */ /*?????????? value 给寄存器写的值??????????? */ /* 出口参数:status 状态值?????????????????? */ /*********************************************/ uchar NRF24L01_Write_Reg(uchar reg,uchar value) { ?? ?uchar status; ?? ?NRF_CSN=0;????????????????? //CSN=0;? ? ? ?? ?status = SPI_RW(reg);//发送寄存器地址,并读取状态值 ?? ?SPI_RW(value); ?? ?NRF_CSN=1;????????????????? //CSN=1; ?? ?return status; } /**********************************************/ /* 函数功能:给24L01的寄存器写值(多个字节)? */ /* 入口参数:reg? 要写的寄存器地址??????????? */ /*?????????? *pBuf 值的存放数组?????????????? */ /*?????????? len?? 数组字节长度?????????????? */ /**********************************************/ uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len) { ?? ?uchar status,u8_ctr; ?? ?NRF_CSN=0; ? ?? ?status = SPI_RW(reg);//发送寄存器值(位置),并读取状态值 ? ?? ?for(u8_ctr=0; u8_ctr<len; u8_ctr++) ?? ?SPI_RW(*pBuf++); //写入数据 ?? ?NRF_CSN=1; ? ?? ?return status;????????? //返回读到的状态值 }
spi读nrf24l01寄存器代码:
/*************************************************/ /* 函数功能:读24L01的寄存器值 (一个字节)????? */ /* 入口参数:reg? 要读的寄存器地址?????????????? */ /* 出口参数:value 读出寄存器的值??????????????? */ /*************************************************/ uchar NRF24L01_Read_Reg(uchar reg) { ??? ?uchar value; ?? ?NRF_CSN=0;????????????? //CSN=0;? ? ? ?? ?SPI_RW(reg);//发送寄存器值(位置),并读取状态值 ?? ?value = SPI_RW(NOP); ?? ?NRF_CSN=1;???????????? //CSN=1; ?? ?return value; } /*********************************************/ /* 函数功能:读24L01的寄存器值(多个字节)?? */ /* 入口参数:reg?? 寄存器地址??????????????? */ /*?????????? *pBuf 读出寄存器值的存放数组??? */ /*?????????? len?? 数组字节长度????????????? */ /* 出口参数:status 状态值?????????????????? */ /*********************************************/ uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len) { ?? ?uchar status,u8_ctr; ?? ?NRF_CSN=0;?????????????????? //CSN=0????? ? ? ?? ?status=SPI_RW(reg);//发送寄存器地址,并读取状态值? ??? ?? ? ??? ?for(u8_ctr=0;u8_ctr<len;u8_ctr++) ?? ?pBuf[u8_ctr]=SPI_RW(0XFF);//读出数据 ?? ?NRF_CSN=1;???????????????? //CSN=1 ? ?? ?return status;??????? //返回读到的状态值 }
初始化nrf24l01,配置为接收数据模式:
void NRF24L01_RT_Init(void) {?? ? ?? ?NRF_CE=0;?? ??? ? ? ? NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 ?? ?NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器?? ? ?? ?NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 ?? ?NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK?? ? ? ?? ?NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);???? //使能通道0的自动应答?? ? ?? ?NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 ? ?? ?NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 ?? ?NRF24L01_Write_Reg(WRITE_REG+RF_CH,20);?????? //设置RF通道为0 ?? ?NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x27);? //设置TX发射参数,7db增益,512Kbps,低噪声增益开启? ? ?? ?NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f);??? //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 ?? ?NRF_CE=1;?? ?//CE置高,使能发送 }