stc51单片机硬件SPI驱动nrf24l01程序

  • 学习10252次

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置高,使能发送
}