(玩电子) 电子技术学习与研究
当前位置:单片机教程网 >> STM32 >> 浏览文章

STM8学习之nRF24L01

作者:佚名   来源:本站原创   点击数:x  更新时间:2014年08月20日   【字体:

nRF24L01是收发双方都要编程的,同时调试一旦出错,不易判断哪方出错,所以可以采用分开调试。

收发过程:
发送 - 等待应答 - (自动重发)- 产生中断
接收 - 等待应答 - 产生中断
取消等待应答便可以实现单独调试发送方了,等发送方调试成功再调接收方。

SPI模拟函数:
 
u8 SPI_RW(u8 byte)
{       
        u8 i;
        for(i=0;i < 8;i++)
        {
                if((byte & 0x80) == 0)   //数据从最高位一位一位地输出到nRF24L01的MOSI
                {       MOSI = 0;       }
                else
                {       MOSI = 1;       }
                
                byte = (byte << 1);      //向左循环8次,完成从高位输出,低位输入一个字节的同步模拟         
                SCK = 1;   //上升沿输入nRF24L01的MOSI
                
                if(MISO == 1)
                {       byte |= 1;      }
                else
                {       byte |= 0;      }     //可以不写,没有实际作用,方便查看与理解
                SCK = 0;                     //下降沿输入单片机MISO
        }
        return (byte);
        
}
 
u8 SPI_RW_Reg(u8 reg, u8 value)
{
u8 status;
        CSN = 0;                    // CSN置低,开始传输数据
status = SPI_RW(reg);  // 选择寄存器,同时返回状态字
SPI_RW(value);            // 然后写数据到该寄存器
CSN = 1;                    // CSN拉高,结束数据传输
return(status);             // 返回状态寄存器
}
 
u8 SPI_Read(u8 reg)
{
u8 reg_val;
CSN = 0;                     // CSN置低,开始传输数据
SPI_RW(reg);               // 选择寄存器
reg_val = SPI_RW(0);    // 然后从该寄存器读数据
CSN = 1;                     // CSN拉高,结束数据传输
return(reg_val);            // 返回寄存器数据
}

 
u8 SPI_Read_Buf(u8 reg, u8 *pBuf, u8 bytes)
{
u8 status, i;
CSN = 0;                    // CSN置低,开始传输数据
status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
for(i=0; i
    pBuf[i] = SPI_RW(0);    // 逐个字节从nRF24L01读出
CSN = 1;                    // CSN拉高,结束数据传输
return(status);             // 返回状态寄存器
}
 
u8 SPI_Write_Buf(u8 reg, u8 *pBuf, u8 bytes)
{
u8 status, i;
CSN = 0;                    // CSN置低,开始传输数据
status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
delay_us(10);
for(i=0; i
SPI_RW(*pBuf++);        // 逐个字节写入nRF24L01
CSN = 1;                    // CSN拉高,结束数据传输
return(status);             // 返回状态寄存器
}
 
void SetRX_Mode(void)
{
//CE=0; //可以不进行拉低操作,考虑此时的效率
//SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);  // IRQ收发完成中断响应,16位CRC ,主接收
        CE = 1;             // 从Standby I模式进入RX模式,开始接受数据
delay_us(1500); // 需要一定的延时,具体时间等待验证(手册上写的是130us)
}

// 接受数据函数
u8 RxPacket(u8* rx_buf)
{
        u8 revale=0;
sta = SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR)         // 判断是否接收到数据
{
                CE = 0; // SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer
                //SPI_RW_Reg(FLUSH_RX, 0Xff);
revale =1; // 读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);   // 接收到数据后RX_DR置高,写1清中断标志,同时清除RX FIFOS?
        //SPI_RW_Reg(FLUSH_RX, 0Xff);
return revale; // 是否接受到数据的标志位
}
 
// 发送数据函数
void TxPacket(u8* tx_buf)
{
CE=0;                                      //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);             // 装载数据
//SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);    // IRQ收发完成中断响应,16位CRC,主发送
CE=1;                                             //置高CE,激发数据发送
delay_us(1000);                                              //延时时间待最小确定,是否是130us?
}
 
// 初始化TX or RX Mode
void init_nRF(void)
{
delay_us(1000);
CE=0;      // chip enable
CSN=1;   // Spi disable 
SCK=0;   // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);      // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);           // 频道0自动 ACK应答允许 
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // 允许接收地址只有频道0,如果需要多频道可以参考Page21  
SPI_RW_Reg(WRITE_REG + RF_CH, 0);                // 设置信道工作为2.4GHZ,收发必须一致      
//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0X00); // disable the retr  (TX mode)
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); // 设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // 设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0X0F);     // 0x0f for RX (0x0e for TX mode)
delay_ms(1);
}
 
第一步:
寄存器的读写操作。写进(如CONFIG)一个值,然后读出,可以检查nRF24L01是否正常,引脚配置与连接是否正确,SPI模拟时序函数是否可用等。
第二步:
然后再只调发送端。把自动应答关闭。
SPI_RW_Reg(WRITE_REG + EN_AA, 0X00); //取消通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0X00);  //无接收通道
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0X00);  //取消自动重发功能
第三步:
最后调接收端,同样先把自动应答关闭。
SPI_RW_Reg(WRITE_REG + EN_AA, 0X00); //取消通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0X01);  //使能接收通道0

文章评论

相关文章

快乐飞艇怎样稳赚 快乐赛车计划下载 快乐飞艇是什么 快乐飞艇 快乐飞艇免费计划app 快乐飞艇全天计划图片 快乐飞艇哪里开的 快乐赛车平台官网 快乐飞艇用哪个计划 快乐飞艇怎么样稳赚