DW1000的CCA例程

发布时间 2023-09-05 13:44:36作者: 不回本不改名

DW1000的CCA例程

介绍

​ 对于无线传感器网络应用,大多数的MAC协议都依赖于Clear Channel Assessment (CCA)来避免冲突。这包括对空中信号进行采样,检测信道是否空闲。一般的无线电可以通过检测载波信号来实现,但是对于UWB技术来说是不行的。对于UWB技术来说,一种可行的方案是只寻找前导码来避免冲突,因为在数据期间发送前导码通常不会干扰那些在数据模式下解调的接收机。如果没有检测到空中有前导码在传输,则自身启动发送,否则发射机将进行随机延时回退(random back-off )延时,延时后再次尝试使用CCA判断信道是否空闲,可否进行发送。

​ 在DW1000的官方SDK中,有一个CCA的例程,指导如何使用CCA方式:

代码分析

​ 核心源码如下:

void main()
{
    //some initial code
    //................
    
    while(1)
    {
        /* local variables for LCD output, this holdes the result of the most recent channel assessment y pseudo CCA algorithm,
        * 1 (channel is clear) or 0 (preamble was detected) */
        int channel_clear;

        /* Write frame data to DW1000 and prepare transmission. See NOTE 6 below.*/
        dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); /* Zero offset in TX buffer. */
        dwt_writetxfctrl(sizeof(tx_msg), 0, 0); /* Zero offset in TX buffer, no ranging. */

        /* Activate RX to perform CCA. */
        dwt_rxenable(DWT_START_RX_IMMEDIATE);
        /* Start transmission. Will be delayed (the above RX command has to finish first)
         *  until we get the preamble timeout or canceled by TRX OFF if a preamble is detected. */
        dwt_starttx(DWT_START_TX_IMMEDIATE);

        /* Poll DW1000 until preamble timeout or detection. See NOTE 7 below. */
        while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXPRD | SYS_STATUS_RXPTO)));

        if (status_reg & SYS_STATUS_RXPTO)
        {
            channel_clear = 1;
            /* Poll DW1000 until frame sent, see Note 8 below. */
            while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS));

            tx_sleep_period = TX_DELAY_MS; /* sent a frame - set interframe period */
            next_backoff_interval = INITIAL_BACKOFF_PERIOD; /* set initial backoff period */
            /* Increment the blink frame sequence number (modulo 256). */
            tx_msg[BLINK_FRAME_SN_IDX]++;
        }
        else
        {
            /* if DW IC detects the preamble, as we don't want to receive a frame we TRX OFF
               and wait for a backoff_period before trying to transmit again */
            dwt_forcetrxoff();

            tx_sleep_period = next_backoff_interval; /* set the TX sleep period */
            next_backoff_interval++; /* If failed to transmit, increase backoff and try again.
                               * In a real implementation the back-off is typically a randomised period
                               * whose range is an exponentially related to the number of successive failures.
                               * See https://en.wikipedia.org/wiki/Exponential_backoff */
            channel_clear = 0;
        }

        /* Note in order to see cca_result of 0 on the LCD, the backoff period is artificially set to 400 ms */
        sprintf(lcd_str, "CCA=%d   %d  ", channel_clear, tx_sleep_period);
        lcd_display_str(lcd_str);

        /* Execute a delay between transmissions. */
        sleep_ms(tx_sleep_period);

    }
}

伪代码逻辑简化版本如下

void main()
{
    //初始化代码
    //。。。。。
    
    while(1)
    {
        启动接收();
        启动接收();
        //这里虽然同时启动接收和发射,但是只有接收结束后,发射才会启动
        
        while(接收到前导码 || 接收超时);
        if(接收超时)
        {
            //说明信道空闲,不对发射进行中断
            重新初始化延时参数();
                  
        }else
        {
            //检测到前导码,信道不空闲
            终止发射();
            更新随机延时参数();
            
        }
        延时();
        
    }
    
}

实际测试

该CCA程序如果需要进行测试的话,可以找台发射机使用Continuous Frame程序,对空中进行连续发帧。以此来确认信道空闲和占用时,CCA是否有用。