2.4g无线跳频(二)
一、主从连接过程分析
整个通讯过程最难搞的就是主从双方建立连接的策略。 假设我们的产品是无线鼠标,一个适配器对应一个鼠标,不可混用。鼠标为主机,适配器为从机,两者可互通数据。为了让多套产品同时使用而不会导致互相干扰至无法正常通讯,必须要建立一个良好的连接策略;
1、最简单有效的策略是为每套产品设立唯一的通道地址,相当于MAC,可以在硬件层面过去掉不需要的信息;但由于我使用的无线IC是NRF24L01,通道地址最大只有40位,若要为每套产品设立单独的通道地址,要么在烧录方面费些功夫,要么在硬件上加ID芯片,这都不是解决问题好办法,暂时不想这样做。
2、允许各套产品使用相同的通道地址, 这样就要求在软件上过滤信息;主机上电后,生成随机序列,遍历所有规定的频道,我这里使用0-31频道,循环发送特定信息,每个频道发送信息后转为接收模式等待一段时间;若接收到特定信息则代表有目标从机在线,这时跳出循环,转为发送模式,启动定时器;从机上电后,随机选择一个频道,转为接收模式,一旦接收到规定的信息,随机退避一个规定区间内的时间,然后转为发送规定的信息给主机,再转回接收模式,启动定时器。建立连接过程完成。
3、上面过程出现了3个“随机”,都是为了减少无线信号的空中碰撞概率;特别是最后一个,是针对多个从机的应答干扰而设计。
4、我生成随机数的方法是利用MCU的悬空AD脚,采样16次每次只取后两位移位合成32Bit;这是真随机数;
二、主要代码
#define NRF24LXX_MASTER
#define NRF_CH_SIZE 32 //频道数目
#pragma pack( push)
#pragma pack(4)
u8 tmp_Tbuf[ NRF_CH_SIZE]; //发送缓存
u8 tmp_Rbuf[ NRF_CH_SIZE]; //接收缓存
#pragma pack( pop)
all_init(); //初始化所有
# ifdef NRF24LXX_MASTER //从机代码
NRF24L01_SET_rfch( get_random()%32 ) ; //随机选择频道
NRF24L01_RX_Mode(0); //接收模式,禁止自动应答
while (1)
{
NRF24L01_RxPacket( tmp_Rbuf); //接收
if( *(u32*)( tmp_Rbuf) == 0x12121212) break;
}
NRF24L01_TX_Mode(0);//发送模式,禁止自动应答重发
*(u32*)( tmp_Tbuf) = *(u32*)( tmp_Rbuf+4); //数据转发回去
delay_ms(get_random()%15+1); //延时转发,区间[1,16]毫秒
NRF24L01_TxPacket( tmp_Tbuf) ;
rsq_st.seed = *(u32*)( tmp_Rbuf+4) ; //获取主机的随机种子
TIM_Cmd( TIM3, ENABLE);//开始计时
NRF24L01_RX_Mode(1);
#else //主机代码
u8 i=0;
*(u32*)( tmp_Tbuf) = 0x12121212; //识别码
mySequence(); //生成随机数并装载发送内存
BuildRandomSequence( rsq_st.rsq, NRF_CH_SIZE, rsq_st.seed); //生成序列
while(1) // 轮询各个频道
{
if(i>= NRF_CH_SIZE)i=0;
g_rfch = rsq_st.rsq[i]; //频道赋值
NRF24L01_TX_Mode(0); //发送模式,不自动应答重发
NRF24L01_TxPacket( tmp_Tbuf) ; //发送数据
NRF24L01_RX_Mode(0); //发送模式,不自动应答重发
delay_ms(20); //等待从机回应
NRF24L01_RxPacket( tmp_Rbuf) ; //接收
if( *(u32*)( tmp_Rbuf) == *(u32*)( tmp_Tbuf+4) ) { break;} //判断是否接收到规定数据
i++;
}
i=0;
delay_ms(3);
TIM_Cmd( TIM3, ENABLE); //开始计时
NRF24L01_TX_Mode(1);
#endif
三、验证
没毛病
————————————————
版权声明:本文为CSDN博主「林子xxx」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangzibigan/article/details/77488630