如何从重复的代码中创建一个函数?

How to make a single function from repetitive code?

我正在为我的嵌入式系统编写一些代码。当我添加相同外围设备的更多不同通道时,我得到的代码确实是重复的。例如:

void pos1_write_read(int *pwriteData)
{
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf0, 0, m_length0);
    spi0_xfer_done = false;

    nrfx_spi_xfer_desc_t m_pos1_write;
    m_pos1_write.p_tx_buffer = pwriteData;
    m_pos1_write.tx_length = m_length0;
    m_pos1_write.p_rx_buffer = m_rx_buf0;
    m_pos1_write.rx_length = m_length0;

    nrf_gpio_pin_clear(SPI0_CS0_PIN);   //Set CS0 to 0 (on)
    APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));

    while (!spi0_xfer_done){}           //Wait until the tranfser is done

    nrf_gpio_pin_set(SPI0_CS0_PIN);     //Set CS0 to 1 (off)

}

void pos2_write_read(int *pwriteData)
{
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf0, 0, m_length0);
    spi0_xfer_done = false;

    nrfx_spi_xfer_desc_t m_pos2_write;
    m_pos2_write.p_tx_buffer = pwriteData;
    m_pos2_write.tx_length = m_length0;
    m_pos2_write.p_rx_buffer = m_rx_buf0;
    m_pos2_write.rx_length = m_length0;

    nrf_gpio_pin_clear(SPI0_CS1_PIN);   //Set CS1 to 0 (on)
    APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));

    while (!spi0_xfer_done){}           //Wait until the tranfser is done

    nrf_gpio_pin_set(SPI0_CS1_PIN);     //Set CS1 to 1 (off)

}

我如何编写一个可以在两个示例中使用的函数?是否有避免重复相同代码的通用良好做法?

找到正确的设计取决于它的用途、您认为合适的通用性等等。没有单一的正确方法可以做到这一点。但是仅基于您的代码片段的天真的解决方案是这样的:

void write_read(int *pwriteData, int pin)
{
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf0, 0, m_length0);
    spi0_xfer_done = false;

    nrfx_spi_xfer_desc_t m_pos1_write;
    m_pos1_write.p_tx_buffer = pwriteData;
    m_pos1_write.tx_length = m_length0;
    m_pos1_write.p_rx_buffer = m_rx_buf0;
    m_pos1_write.rx_length = m_length0;

    nrf_gpio_pin_clear(pin);   //Set CS0 to 0 (on)
    APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));

    while (!spi0_xfer_done){}           //Wait until the tranfser is done

    nrf_gpio_pin_set(pin);     //Set CS0 to 1 (off)

}
void pos1_write_read(int *pwriteData)
{
    write_read(pwriteData, SPI0_CS0_PIN);
}

void pos2_write_read(int *pwriteData)
{
    write_read(pwriteData, SPI0_CS1_PIN);
}

我们的想法是只采用通用代码,然后参数化它们之间的任何不同之处。

唯一真正的区别是 SC 引脚,您可以将其作为参数传递:

void pos_write_read(int *pwriteData, uint32_t pin)
{
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf0, 0, m_length0);
    spi0_xfer_done = false;

    nrfx_spi_xfer_desc_t m_pos_write;
    m_pos_write.p_tx_buffer = pwriteData;
    m_pos_write.tx_length = m_length0;
    m_pos_write.p_rx_buffer = m_rx_buf0;
    m_pos_write.rx_length = m_length0;

    nrf_gpio_pin_clear(pin);   //Set CS to 0 (on)
    APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));

    while (!spi0_xfer_done){}           //Wait until the tranfser is done

    nrf_gpio_pin_set(pin);     //Set CS to 1 (off)
}

/* This allows you to do the following: */

void pos1_write_read(int *pwriteData)
{
    pos_write_read(pwriteData, SPI0_CS0_PIN);
}


void pos2_write_read(int *pwriteData)
{
    pos_write_read(pwriteData, SPI0_CS1_PIN);
}