御坂10032号 发表于 2024-12-1 05:10

[Follow me第二季第3期] [基础任务] Q-spi 和O-spi 读写速度测试 + DAC输出和性能测试

本帖最后由 御坂10032号 于 2024-12-1 06:13 编辑

<p><strong><span style="font-size:24px;">简介</span></strong></p>

<p>&nbsp;</p>

<p>本章节我们来完成基础任务, 即QSPI 和 OSPI的配置以及读写测试, 和DAC的输出和精度测试。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size: 24px;"><b>任务1:&nbsp;Q-spi 和O-spi 读写速度测试&nbsp;</b></span></p>

<p>&nbsp;</p>

<p>从下图我们可以看到,这块开发板板载了一块32MB的QSPI flash 和一块64MB的OSPI flash。接下来我们可以对其进行配置和读写测试。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>在创建项目的时候如果我们选择是基于board的方式创建的话,那么针对当前开发板的所有的外设资源都会被正确的初始化。 我们可以在configuration.xml 中进行检查。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong>下图为QSPI的PIN配置</strong></p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p><strong>下图为OSPI的PIN配置</strong></p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>QUICK_Start 项目中提供了一份完整的QSPI和OSPI的对比测试。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>OSPI的方法定义在<strong>ospi-test.h</strong>里, 而它的上层调用在menu_ext.c 里。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>当程序调用测试方法之后, 会将OSPI的测试结果返回,然后进行QSPI的写测试,同时得到两者的时间, 读操作类似。所以我们可以在menu中来进行这个测试</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>输入 4, 进行对比测试。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>输入最大的测试块大小。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>下图为测试结果, 可以看出, 在64KB的读写测试中OSPI的速度明显要更胜一筹。无论是在读写的方面</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<hr />
<p>&nbsp;</p>

<p><span style="font-size:24px;"><b>任务2:&nbsp;DAC输出和性能测试</b></span></p>

<p>&nbsp;</p>

<p><span style="font-size: 16px;">E2- studio 对RA系列的程序集成的非常好, 所有的功能等是处于可选的, 当你不选择生成的时候,这些对应外设的库文件并不会为你生成,但是当你初始化完PIN之后, 并且配置stack,那么这些库文件才会被生成到IDE里。</span></p>

<p>&nbsp;</p>

<p><span style="font-size: 16px;">下面我将演示如何配置</span>FSP生成DAC的库函数和PIN的初始化。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>1-&nbsp; 在基于board的项目创建完毕后,点击configuration.yml 选择PIN</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><span style="color:#e74c3c;">在上述PIN的地方初始化DAC0或者1, 但是在enable的时候会出现error,原因是这个PIN已经被使用为了ADC. 所以需要在ADC处将这个PIN给取消占用。</span></p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>之后点击下面的<strong>Stacks</strong>选项</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>逐次点击, New Stack, Analog , DAC, 然后点击Generate Project content. 这样的话DAC的初始化配置已经完成了。 我们可以检查Ra 的 hal_data 内已经有了DAC的相关配置。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>下图为DAC的相关库(FSP)</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>接下来打开src下的hal_entry写下我们的代码。代码如下(使其DAC从0 输出到 4095, 然后4095 到0)</p>

<p>&nbsp;</p>

<pre>
<code class="language-cpp">#include "hal_data.h"
#include "r_dac.h"

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

void dac0_initialize(void);

/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif

    /* Initialize DAC0 */
    dac0_initialize();

    uint16_t dac_value = 0;      // Current DAC value
    int step = 1;                  // Step direction (1 for increment, -1 for decrement)

    /* Main loop */
    while (1)
    {
      /* Write the current DAC value */
      R_DAC_Write(&amp;g_dac0_ctrl, dac_value);

      /* Update the DAC value */
      dac_value += step;

      /* Check boundaries */
      if (dac_value == 4095)    // Maximum value for 12-bit DAC
      {
            step = -1;            // Switch to decrementing
      }
      else if (dac_value == 0) // Minimum value
      {
            step = 1;             // Switch to incrementing
      }

      /* Add a delay to control the update rate */
      R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
    }
}

/*******************************************************************************************************************//**
* DAC0 Initialization
**********************************************************************************************************************/
void dac0_initialize(void)
{
    /* Open DAC0 */
    fsp_err_t err = R_DAC_Open(&amp;g_dac0_ctrl, &amp;g_dac0_cfg);
    if (FSP_SUCCESS != err)
    {
      /* Handle error */
      __BKPT(0);
    }

    /* Start DAC0 */
    err = R_DAC_Start(&amp;g_dac0_ctrl);
    if (FSP_SUCCESS != err)
    {
      /* Handle error */
      __BKPT(0);
    }

    /* Optional: Set the initial DAC value to 0 */
    err = R_DAC_Write(&amp;g_dac0_ctrl, 0);
    if (FSP_SUCCESS != err)
    {
      /* Handle error */
      __BKPT(0);
    }
}

/*******************************************************************************************************************//**
* This function is called at various points during the startup process.This implementation uses the event that is
* called right before main() to set up the pins.
*
* @paramevent    Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0
      /* Enable reading from data flash. */
      R_FACI_LP-&gt;DFLCTL = 1U;

      /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
      /* C runtime environment and system clocks are setup. */

      /* Configure pins. */
      R_IOPORT_Open(&amp;g_ioport_ctrl, g_ioport.p_cfg);

#if BSP_CFG_SDRAM_ENABLED
      /* Setup SDRAM and initialize it. Must configure pins first. */
      R_BSP_SdramInit(true);
#endif
    }
}

#if BSP_TZ_SECURE_BUILD

FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable()
{

}
FSP_CPP_FOOTER

#endif
</code></pre>

<p>&nbsp;</p>

<p>进行编译和烧录,然后使用万用表测试P014</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>将万用表的 负极接到GND, 正极接到DAC的输出 P014.</p>

<p>&nbsp;</p>

<p><strong>视频效果如下所示</strong></p>

<p>&nbsp;</p>

<p>9176f38e2c1ae7b2f33928304561f6db<br />
&nbsp;</p>

<p>&nbsp;</p>

<p><strong>代码如下</strong></p>

<p>&nbsp;</p>

<div></div>

Jacktang 发表于 2024-12-1 16:17

<p>虽然三用表精度不够,但效果已经到位了,谢谢分享</p>

御坂10032号 发表于 2024-12-1 17:48

Jacktang 发表于 2024-12-1 16:17
虽然三用表精度不够,但效果已经到位了,谢谢分享

<p>我还有个51单片机的示波器, 今天晚点我补充一下波形</p>
页: [1]
查看完整版本: [Follow me第二季第3期] [基础任务] Q-spi 和O-spi 读写速度测试 + DAC输出和性能测试