2.4g无线跳频(三)
一、跳频过程分析
1.主从建立连接,开启定时器。
2.对于主机,每个定时周期内,前部分处于发送模式,后部分处于接收模式;
   对于从机,每个定时周期内,前部分处于接收模式,后部分处于发送模式;发送时间应安排小于接收时间;
3.主机发送数据后,在规定的时间后转换为接收模式;从机接收到数据后马上调整自身时间,以达到同步的目的;
   主机发送数据的时间要求准时,因为从机接收到信息后会马上调整定时器的计数,同步从机与主机的时间;
4.定时时间一到便开始跳频,注意设法让接收方先于发送方跳。
   跳频示意图:


  带序列的跳频示意图:

二、代码

#define TIMXCNT TIM3->CNT
#define NRF_CH_SIZE 32      //频道数目
typedef struct 
{
    u8 rsq[NRF_CH_SIZE];   //序列
    u32 seed ;  //随机种子
    u32 rsqval; //当前序列值
} _rsq_st ;         //与随机序列有关的变量
_rsq_st rsq_st;
 
 
u8 semflag=0;      //全局标志变量,用于同步线程
u8 print_flag=0;   //用于串口打印输出的标志变量
/*字节对齐,方便读写*/
#pragma pack(push)
#pragma pack(4)
u8 tmp_Tbuf[NRF_CH_SIZE]; 
u8 tmp_Rbuf[NRF_CH_SIZE];  
#pragma pack(pop)
 
u8 pdatas[255]={0}; //用于打印测试
 
TIM3_Int_Init(50000-1 ,72-1 );  // 定时arr=50000

#ifdef NRF24LXX_MASTER       //主机代码
void TIM3_IRQHandler(void)   //TIM3中断
{
            static u8 i=0 ;
            if ( TIM_GetITStatus( TIM3, TIM_IT_Update) != RESET)    //检查中断源 
        {
            TIM_ClearITPendingBit( TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位
 
 
            if( NRF_CH_SIZE == i)  //序列周期到了
            {
                i=0;  
                revflag=1;
                rsq_st.seed = *(u32*)(tmp_Rbuf+4) ;   //接收种子 
                BuildRandomSequence( rsq_st.rsq, NRF_CH_SIZE, rsq_st.seed);//利用种子生成特定序列
            }
            
            rsq_st.rsqval = rsq_st.rsq[i];
            tmp_Tbuf[0] = i+'@';
            tmp_Tbuf[1] = i+'@';
            semflag = 0;//  
            i++;     
        }
}
#else  //从机代码
void TIM3_IRQHandler(void)   
{
    static u8 i=0  ;
    if (TIM_GetITStatus( TIM3, TIM_IT_Update) != RESET)  
    {
       TIM_ClearITPendingBit( TIM3, TIM_IT_Update  );   
        
          if( NRF_CH_SIZE == i )
            {
                i=0;
                revflag=1;
                BuildRandomSequence( rsq_st.rsq, NRF_CH_SIZE, rsq_st.seed);//利用种子生成特定序列
            }
            
            NRF24L01_SET_rfch( rsq_st.rsq[i] ) ;  //根据序列跳频
            NRF24L01_TX_Mode(1); 
            tmp_Tbuf[0] = i+'@'; //改变其中一个发射值
            tmp_Tbuf[1] = i+'@'; //改变其中一个发射值
            NRF24L01_TxPacket( tmp_Tbuf);
            semflag = 0;  
            i++;        
    }
}
#endif
 
 
/*生成随机种子并装载至发生内存*/
u32 mySequence()
{
    rsq_st.seed = get_random();//随机种子
    *(u32*)(tmp_Tbuf+4) = rsq_st.seed;
    return rsq_st.seed;
}

# ifdef NRF24LXX_MASTER    //主机代码
                static u8 i=0;
        NRF24L01_RX_Mode(1);//接收模式,开启自动应答
        BuildRandomSequence( rsq_st.rsq, NRF_CH_SIZE, rsq_st.seed);//利用种子生成特定序列
        while(1)
        {        
          switch( semflag)
            {
                case 0:                         
                    NRF24L01_SET_rfch( rsq_st.rsqval ) ;  //根据序列跳频
                    NRF24L01_RX_Mode(1);  
                    semflag++;
                break ;
                case 1:
                    if( print_flag )//打印数据
                       {
                        print_flag=0;
                        fz+= i;fm+=NRF_CH_SIZE;
                        printf (" %d:%d:%.4f:", temp, i, fz/ fm);
                        pdatas[ i]='\r',pdatas[ i+1]='\n';
                        myUSART_Sendarr( USART1, pdatas  , i+2) ;
                        i=0; 
                        }
                    semflag++;
                break ;
                case 2:
                    if( TIMXCNT <30000)
                       {    
                        if(NRF24L01_RxPacket( tmp_Rbuf)==0)//接收到信息 
                        {
                            temp= TIM3->CNT ;
                            TIM3->CNT=1800 ;
                            pdatas[ i]= tmp_Rbuf[0];
                            i++;    
                        }
                    }
                    else 
                    semflag++;
                break ;
                case 3:
                    NRF24L01_TX_Mode(1);  //发送模式,开启自动应答自动从发  
                        semflag++;
                break ;
                case 4:
                     NRF24L01_TxPacket( tmp_Tbuf);
                         if( semflag==4) semflag++;
                         mySequence();//生成随机种子并装载发送内存,为下一周期准备
                break ;
                        case 5:     
                break ;
            }                   
        }    
    }
#else  //从机代码
    {                    
        static u16 temp ;
        static u8 i=0;
 
 
        NRF24L01_TX_Mode(1);//发送模式,开启自动应答自动从发
        mySequence(); //生成随机数并装载发送内存,为下周期准备
        while(1)
        {
            if( TIMXCNT >20000) //时间到了开始接收模式
            {
               if( semflag == 0) 
                 { 
                    NRF24L01_RX_Mode(1);  //接收模式,开启自动应答
                    semflag++;  
                 }
                 else if(TIMXCNT <49500)
                 {
                     if(NRF24L01_RxPacket( tmp_Rbuf)==0) //接收到信息 
                    {
                        temp=TIM3->CNT ;       //用于观察计数器
                        pdatas[i]= tmp_Rbuf[0];//取第一个数装载至pdatas ,用来测试
                        i++;    
                    }                         
                 }
            }
                
            if( print_flag )  //打印数据
            {    
                print_flag=0;
                fz+= i;fm+= NRF_CH_SIZE;
                printf ("%d:%d:%.4f:", temp, i, fz/ fm);//串口打印
                pdatas[i]='\r',pdatas[i+1]='\n';
                myUSART_Sendarr( USART1, pdatas, i+2); //串口打印数组
                i=0;
            }            
        };
    }
#endif

以上代码,注意主函数进程与定时器中断服务进程之间的同步,绝不要让两个进程同时访问相同的硬件(这里是无线IC)。

三、验证

两个模块,串口接收如下;

注意第一个数据是各自接收到数据时的定时器读数,而后面1.0000代表丢失率为0,数据接收质量还不错。

————————————————
版权声明:本文为CSDN博主「林子xxx」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangzibigan/article/details/77510187

2.4g无线跳频(三)相关推荐

  1. 2.4g无线跳频(一)

    2.4g无线跳频(一) 这里是针对一对一无线通信的简单定时跳频. 一.随机种子与序列 无线跳频首选要生成一个随机的频道序列,让通信的双方按照这个序列跳频.利用C语言库函数rand()与srand(SE ...

  2. 2.4G无线麦克风无线音频传输模块

    模块概述 M01主要是一个2.4G无线音频传输模块,模组RF电路设计配合独有的软件跳频机制,有效提高了RF的抗干扰能力及传输距离.模组内置高性能的音频转换器,支持48K/24bit高品质的音频采样.支 ...

  3. 《高级无线网络—4G技术》——1.3 混合4G无线网络协议

    本节书摘来自异步社区<高级无线网络-4G技术>一书中的第1章,第1.3节,作者: [芬]Savo G. Glisic 更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  4. 7620a路由mysql_MT7620A路由刷DDWRT 及2.4G无线设置经验

    本帖最后由 overthink 于 2015-6-15 15:10 编辑 MT7620A路由刷DDWRT 及2.4G无线设置经验 用了N久的buffalo WHR-HP-G54,刷了DDWRT,以前做 ...

  5. 2.4g 无线键鼠对码软件_RK526无线键鼠套装开箱体验

    不愧是你,RK.那个把性价比这一块拿捏得死死的.先前,才刚推出300出头的RK84三模无线机械键盘,具备2.4G.蓝牙.有线三种连接方式,还是搭载使用CHERRY MX轴体,可以说,这价位84键机械键 ...

  6. 2.4G无线音频双向传输技术运用

    2.4G无线音频双向传输技术运用 1.产品描述 A8810S1 是一对远距离的 2.4G 无线音频传输模组.模组专业的 RF 电路设计配合独有的软件跳频机制,有效提高了 RF 的抗干扰能力及传输距离. ...

  7. 2.4G无线麦克风领夹麦一拖二_全双工_杰理JL6976M单芯片方案

    目录 一.简介 二.详细说明 2.1 目前杰理的无线麦方案 2.2 主控芯片脚位图 2.3 系统框架图 2.4 方案参数低延时无线麦功能支持以下三种组合配置:(1)一发一收a)    无线麦(单收发) ...

  8. 无线调度台服务器,矿用4G无线通信系统_煤矿融合综合调度系统

    矿用4G无线通信系统_煤矿融合综合调度系统 一.系统介绍 无线通信技术的发展也先后经历了模拟通信.2G.3G技术.4G目前已开始正式商用.2G技术较好的解决了语音通信问题,单是无线数据传输带宽局限性太 ...

  9. 水库防汛泄洪抢险应急广播系统建设4G无线广播模式分析

    水库防汛泄洪抢险应急广播系统建设4G无线广播模式分析 北京海特伟业科技有限公司 文/任洪卓发布于:2022-06-02 一.水库防汛泄洪抢险应急广播系统建设必要性 从河南郑州等地极端暴雨侵袭.陕西安康 ...

最新文章

  1. socket编程:I/O模型
  2. websocket session超时_SSE(ServerSent Events):替代websocket完成服务器推送
  3. CentOS中安装的Gitlab忘记管理员密码怎样重置密码
  4. 6410 linux内核移植
  5. php socket的一些问题
  6. Bash Shell学习笔记三
  7. 打造史上最小尺寸.Net Core单文件应用程序
  8. 函数式编程在Redux/React中的应用
  9. Job 存储和持久化 (第一部分)
  10. 移动设备安全隐患分析
  11. 我真的还是18岁的那个我
  12. 查看计算机数字证书,数字证书认不到怎么办?
  13. 软件设计师教程---第一章计算机系统知识
  14. 基于 vue-element-admin 基础模板实现侧边栏菜单动态渲染
  15. form 表单提交后,使页面不跳转
  16. 基于geoserver的伪三维地图制作
  17. 被“傲慢”击溃的国外大牌们,终于轮到他们抄袭了?
  18. 正则匹配所有的a标签
  19. Hantek6022BE 虚拟示波器 (二)方波 采样率 带宽
  20. Java 8中Collectors.toMap空指针异常源码分析

热门文章

  1. 【Django-CI系统】JSON的使用-20220509
  2. 系统运维:北京某金融公司中级系统运维笔试题-2020年9月份
  3. linux通过钩子阻断端口,用钩子钩住你的中断处理函数
  4. 【mysql】mysql调优时必须掌握的慢查询语句排查命令
  5. Linux下软件源码包安装问题解决方法
  6. 基于机器学习组合模型的个人信用评估
  7. centos7搭建 mysql 主从数据库
  8. 信息系统集成及服务管理(ITSS)和审计要点
  9. 【报错】面试沟通,要运行ruoyi 框架截图,之前没接触过
  10. 如何用Python实现将照片转化为手绘图片