当前位置 博文首页 > freemote的博客:LoRa节点开发:6、代码详解修改发射和接收信道(

    freemote的博客:LoRa节点开发:6、代码详解修改发射和接收信道(

    作者:[db:作者] 时间:2021-07-18 19:11

    本文来源公众号【物联网思考】

    本文主要结合LoRaNode SDK v4.4.2和LoRaWAN规范1.0.3来展开。

    查看《lorawan_regional_parameters_v1.0.3reva_0.pdf》文档,每个地区对应的信道都不一样,在SDK中,不同的地区以不同的文件实现:

    查看文档,CN470频段,支持96个上行通道,48个下行通道。

    ?

    国内主要是CN470,因此主要看RegionCN470这个文件。

    发送频率设置

    SDK在函数void RegionCN470InitDefaults( InitDefaultsParams_t* params )中初始化信道参数:

    void RegionCN470InitDefaults( InitDefaultsParams_t* params )
    {
        Band_t bands[CN470_MAX_NB_BANDS] =
        {
            CN470_BAND0
        };
    
        switch( params->Type )
        {
            case INIT_TYPE_INIT:
            {
                // Initialize bands
                memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS );
    
                // Channels
                // 125 kHz channels
                for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ )//CN470_MAX_NB_CHANNELS是一个宏定义,取值是96
                {
                    NvmCtx.Channels[i].Frequency = 470300000 + i * 200000;
                    NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
                    NvmCtx.Channels[i].Band = 0;
                }
    
                // Initialize the channels default mask
                NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
                NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
                NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
                NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
                NvmCtx.ChannelsDefaultMask[4] = 0xFFFF;
                NvmCtx.ChannelsDefaultMask[5] = 0xFFFF;
    
                // Update the channels mask
                RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
                break;
            }
            case INIT_TYPE_RESTORE_CTX:
            {
                if( params->NvmCtx != 0 )
                {
                    memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) );
                }
                break;
            }
            case INIT_TYPE_RESTORE_DEFAULT_CHANNELS:
            {
                // Restore channels default mask
                RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
                break;
            }
            default:
            {
                break;
            }
        }
    }

    可以看到,通过for循环给96个信道赋值,从470.3M开始,以200K的步长增加,并且把信道掩码全部赋值为0xffff。

    其中NvmCtx是一个结构体变量,查看其定义如下:

    // Definitions
    #define CHANNELS_MASK_SIZE              6
    
    /*!
     * Region specific context
     */
    typedef struct sRegionCN470NvmCtx
    {
        /*!
         * LoRaMAC channels
         */
        ChannelParams_t Channels[ CN470_MAX_NB_CHANNELS ];
        /*!
         * LoRaMac bands
         */
        Band_t Bands[ CN470_MAX_NB_BANDS ];
        /*!
         * LoRaMac channels mask
         */
        uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ];
        /*!
         * LoRaMac channels default mask
         */
        uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ];
    }RegionCN470NvmCtx_t;

    可以看到,CN470信道掩码是一个uint16_t的数组,数组有6个元素,16*6=96bit刚好对应96个上行信道,既就是每个信道对应一个bit。在上面初始化的时候,信道通过for循环遍历,信道掩码全部设置为了0xffff,既SDK中默认开启了所有的信道。

    通常情况下LoRaWAN网关(sx1301/2/8)只支持8个上行通道1个下行通道,既只可以同时接收8路数据。因此我们需要修改让节点只用8个信道上报数据,这8个信道与网关保持一致。

    我们参考上面的把不需要的信道频率设置为0,或对应的掩码位置设为0,剩下的就是我们需要的信道。

    假设,我们要设置的8个频点为:

    
    uint32_t UserFreq[8]={471900000,472100000,472300000,472500000,472700000,472900000,473100000,473300000};

    那么只需在void RegionCN470InitDefaults( InitDefaultsParams_t* params )函数默认的信道初始化后加入如下代码:

        NvmCtx.ChannelsDefaultMask[0] = 0x0000;
        NvmCtx.ChannelsDefaultMask[1] = 0x0000;
        NvmCtx.ChannelsDefaultMask[2] = 0x0000;
        NvmCtx.ChannelsDefaultMask[3] = 0x0000;
        NvmCtx.ChannelsDefaultMask[4] = 0x0000;
        NvmCtx.ChannelsDefaultMask[5] = 0x0000;
    			
        for( uint8_t i = 0,j=0; i < 8; i++ )
        {
    	j=(UserFreq[i].Frequency-470300000 )/200000;//计算信道号
    
            NvmCtx.Channels[j].Frequency = UserFreq[i].Frequency ;
            NvmCtx.Channels[j].DrRange.Value=( DR_5 << 4 ) | DR_0; 
    	NvmCtx.Channels[j].Band = 0;
    
    	NvmCtx.ChannelsDefaultMask[j/16]|=1<<(j%16);//相应的信道掩码位设置为1
        }
        // Update the channels mask
        RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );

    上面代码中,最关键的两句话,计算信道号相应的信道掩码位设置为1

    接收频率设置

    还是查看《lorawan_regional_parameters_v1.0.3reva_0.pdf》文档

    可以看出,下行通道rx1等于上行通道号与48取余,rx2是固定的,默认为505.3MHZ。

    SDK中在函数bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )实现了接收频率的设置:

    bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
    {
        int8_t dr = rxConfig->Datarate;
        uint8_t maxPayload = 0;
        int8_t phyDr = 0;
        uint32_t frequency = rxConfig->Frequency;
    
        if( Radio.GetStatus( ) != RF_IDLE )
        {
            return false;
        }
    
        if( rxConfig->RxSlot == RX_SLOT_WIN_1 )
        {
            // Apply window 1 frequency
            frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;
            //计算rx1的频率
        }
    	
        // Read the physical datarate from the datarates table
        phyDr = DataratesCN470[dr];
    
        Radio.SetChannel( frequency );
    
        // Radio configuration
        Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
    
        if( rxConfig->RepeaterSupport == true )
        {
            maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr];
        }
        else
        {
            maxPayload = MaxPayloadOfDatarateCN470[dr];
        }
        Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
    
        *datarate = (uint8_t) dr;
        return true;
    }

    其中,最重要的一句代码:

    // Apply window 1 frequency
            frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;
    //计算rx1的频率

    通过发射信道号,计算rx1的接收信道。可见,如果发射信道固定了,那么rx1(接收1)的信道也就固定了。

    因此,我们在CN470频段,只需要修改发射信道即可完成发射和接收的设置。

    ????????????????????????????????????????????????????????????????????????? ——————END——————

    关注公众号:“物联网思考”,获取更多开发资料、经验。

    ?

    cs
    下一篇:没有了