143|1

6873

帖子

11

TA的资源

版主

楼主
 

【Follow me第二季第3期】 [扩展任务] DAC输出不同波形,FLASH保存和读取历史数据 [复制链接]

  本帖最后由 lugl4313820 于 2024-12-14 14:09 编辑

在前面几期的前提下,我增加了DAC的配置,以及flash写入与读取的代码。

1、dac的配置:如前面分享的【Follow me第二季第3期】DAC波形生成 - DigiKey得捷技术专区 - 电子工程世界-论坛

2、在menu_adc.c中增加一组生成正弦波的数组:

//正弦波数据数组变量
uint16_t custom_var[32] = {
    2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668,
    3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127,
    310, 564, 878, 1240, 1636, 2048
};

3、增加初始化ADC:

void DAC_Init()
{
    R_DAC_Open(&g_dac0_ctrl, &g_dac0_cfg);
    R_DAC_Start(&g_dac0_ctrl);
}

4、增加写入与读取的函数:

/**
 * [url=home.php?mod=space&uid=159083]@brief[/url]  调整波形数据
 * @param new_value 按键输入的值
 * @retval 无
 */
void Adjust_Waveform(int32_t step)
{
    for (uint32_t i = 0; i < sizeof(custom_var) / sizeof(custom_var[0]); i++)
    {
        // 调整值,限制范围在 MIN_VALUE 和 MAX_VALUE 之间
        if (custom_var[i] + step > MAX_VALUE)
        {
            custom_var[i] = MAX_VALUE;
        }
        else if (custom_var[i] + step < MIN_VALUE)
        {
            custom_var[i] = MIN_VALUE;
        }
        else
        {
            custom_var[i] += step;
        }
    }
}

/**
 * @brief 从 Quad Flash 读取波形数据
 * @param buffer 存储波形的缓冲区
 * @retval 无
 */
void Read_Waveform_From_Flash(uint16_t *buffer)
{
    fsp_err_t err = FSP_SUCCESS;
    uint32_t page_read_count = 0;
    uint8_t *p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
    spi_flash_protocol_t current_spi_mode;

    /* The comms mode of the FLASH device is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
    /* 打开 QSPI 模块 */
//    err = R_QSPI_Open(&g_qspi_ctrl, &g_qspi_cfg);
//    if (FSP_SUCCESS != err)
//    {
//        sprintf(s_print_buffer, "Failed to open QSPI module\r\n");
//        return;
//    }
    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    /* 逐页读取波形数据 */
    while ((page_read_count * PAGE_WRITE_SIZE) < sizeof(custom_var))
    {
        memcpy(&buffer[page_read_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
        p_mem_addr += PAGE_WRITE_SIZE;
        page_read_count++;
    }
//    /* 关闭 QSPI 模块 */
//    err = R_QSPI_Close(&g_qspi_ctrl);
//    if (FSP_SUCCESS != err)
//    {
//        sprintf(s_print_buffer, "Failed to close QSPI module\r\n");
//    }
    /* close QSPI module */
    deinit_qspi(current_spi_mode);
}

/**
 * @brief 将波形数据存储到 Quad Flash
 * @param buffer 需要存储的波形
 * @retval 无
 */
void Write_Waveform_To_Flash(uint16_t *buffer)
{
    fsp_err_t err = FSP_SUCCESS;
    uint32_t page_write_count = 0;
    uint8_t *p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
    spi_flash_protocol_t current_spi_mode;

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
    /* 打开 QSPI 模块 */
//    err = R_QSPI_Open(&g_qspi_ctrl, &g_qspi_cfg);
//    if (FSP_SUCCESS != err)
//    {
//        sprintf(s_print_buffer, "Failed to open QSPI module\r\n");
//        return;
//    }
    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }
    /* 擦除 QSPI 的指定扇区 */
    err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
    if (FSP_SUCCESS != err)
    {
        sprintf(s_print_buffer, "Failed to erase QSPI flash\r\n");
        return;
    }
    /* 等待擦除完成 */
    err = get_flash_status();
    if (FSP_SUCCESS != err)
    {
        sprintf(s_print_buffer, "Failed to get flash status after erase\r\n");
        return;
    }

    /* 逐页写入波形数据 */
    while (((page_write_count * PAGE_WRITE_SIZE) < sizeof(custom_var)) && (FSP_SUCCESS == err))
    {
        err = R_QSPI_Write(&g_qspi_ctrl, &buffer[page_write_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
        if (FSP_SUCCESS != err)
        {
            sprintf(s_print_buffer, "Failed to write data to QSPI flash\r\n");
        }
        else
        {
            err = get_flash_status();
            if (FSP_SUCCESS != err)
            {
                sprintf(s_print_buffer, "Failed to get flash status after write\r\n");
            }
        }
        p_mem_addr += PAGE_WRITE_SIZE;
        page_write_count++;
    }
    /* 关闭 QSPI 模块 */
//    err = R_QSPI_Close(&g_qspi_ctrl);
//    if (FSP_SUCCESS != err)
//    {
//        sprintf(s_print_buffer, "Failed to close QSPI module\r\n");
//    }

    /* close QSPI module */
    deinit_qspi(current_spi_mode);
}

这里有些函数是引用menu_ext.c中的函数,有些是私有的,需要修改为全局的,并添加到muenu_ext.h中:

#ifndef MENU_EXT_H_
#define MENU_EXT_H_

extern test_fn ext_display_menu (void);
fsp_err_t qpi_init (void);
void deinit_qspi (const spi_flash_protocol_t spi_protocol_mode);
fsp_err_t get_flash_status(void);
#endif /* MENU_KIS_H_ */

5、添加对数组的波形的设置:

/**
 * @brief 调整波形数据
 * @param new_value 按键输入的值
 * @retval 无
 */
void Adjust_Waveform(int32_t step)
{
    for (uint32_t i = 0; i < sizeof(custom_var) / sizeof(custom_var[0]); i++)
    {
        // 调整值,限制范围在 MIN_VALUE 和 MAX_VALUE 之间
        if (custom_var[i] + step > MAX_VALUE)
        {
            custom_var[i] = MAX_VALUE;
        }
        else if (custom_var[i] + step < MIN_VALUE)
        {
            custom_var[i] = MIN_VALUE;
        }
        else
        {
            custom_var[i] += step;
        }
    }
}

6、在接收函数中添加各个功能模块的功能:

* Function Name: ext_display_menu
test_fn dac_display_menu(void)
{
    DAC_Init();         // DAC 初始化



    int32_t c = -1;
    uint32_t block_size_actual = 0;
    int32_t block_sz_ndx = 0;
    int32_t block_sz_limit = (INPUT_BUFFER - 2);
    bool_t response_flag = false;


    sprintf(s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);
    sprintf(s_print_buffer, MODULE_NAME, g_selected_menu);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);
    sprintf(s_print_buffer, SUB_OPTIONS);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    /* Keep trying to read a valid text block size
     * complete the loop in one of two ways:
     * [1] Valid block size is entered (2K boundary range 2-64K) followed by TAB
     * [2] Space Bar is pressed at any stage
     */
    block_sz_ndx = 0;
    memset(&s_block_sz_str, 0, INPUT_BUFFER);
    while (false == response_flag)
    {
        print_to_console("input: ");
        vTaskDelay(1);
        while ((CONNECTION_ABORT_CRTL != c))
        {
            c = input_from_console();

                if (c == 'a')
                {
                    sprintf(s_print_buffer, "\r\nIncrease waveform parameters\r\n");
                    print_to_console((void*)s_print_buffer);
                    Adjust_Waveform(STEP_SIZE); // 增加波形值
                    sprintf(s_print_buffer, "custom_var contains:\r\n");
                    print_to_console((void *)s_print_buffer);
                    for (uint32_t i = 0; i < 32; i++)
                    {
                        sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
                        print_to_console((void *)s_print_buffer);
                    }
                }
                if (c == 's')
                {
                    sprintf(s_print_buffer, "\r\nDecrease waveform parameters\r\n");
                    print_to_console((void*)s_print_buffer);
                    Adjust_Waveform(-STEP_SIZE); // 减少波形值
                    sprintf(s_print_buffer, "custom_var contains:\r\n");
                    print_to_console((void *)s_print_buffer);
                    for (uint32_t i = 0; i < 32; i++)
                    {
                        sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
                        print_to_console((void *)s_print_buffer);
                    }
                }
                if (c == 'r') // 读取波形数据
                {
                    sprintf(s_print_buffer, "\r\nRead the waveform data from Quad-SPI flash into memory buffer\r\n");
                    print_to_console((void*)s_print_buffer);
                    Read_Waveform_From_Flash(custom_var);
                    is_custom_wave = true;
                    sprintf(s_print_buffer, "After Reading, custom_var contains:\r\n");
                    print_to_console((void *)s_print_buffer);
                    for (uint32_t i = 0; i < 32; i++)
                    {
                        sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
                        print_to_console((void *)s_print_buffer);
                    }

                }
                else if (c == 'w') // 写入波形数据
                {
                    sprintf(s_print_buffer, "\r\nWrite the current waveform data to Quad-SPI flash storage\r\n");
                    print_to_console((void*)s_print_buffer);
                    sprintf(s_print_buffer, "Before Writing, var contains:\r\n");
                    print_to_console((void *)s_print_buffer);
                    for (uint32_t i = 0; i < 32; i++)
                    {
                        sprintf(s_print_buffer, "var[%u] = %u\r\n", i, custom_var[i]);
                        print_to_console((void *)s_print_buffer);
                    }
                    Write_Waveform_To_Flash(custom_var);
                }
                else if (c == 'g') // 写入波形数据
                {
                    sprintf(s_print_buffer, "\r\nStart Generator...\r\n");
                    print_to_console((void *)s_print_buffer);
                    dac_start_flag = !dac_start_flag;
                }

                block_sz_ndx = 0;
                memset(&s_block_sz_str, 0, INPUT_BUFFER);
               // break;
            if (MENU_EXIT_CRTL == c)
            {
                response_flag = true;
                block_size_actual = 0;
                break;
            }

            if (CARRAGE_RETURN != c)
            {
                sprintf(s_print_buffer, "%c", (char_t)c);
                print_to_console((void*)s_print_buffer);
            }
            // 输出波形

        }
        if ((MENU_EXIT_CRTL == c) || (0x00 == c))
        {
            break;
        }

    }

    return (0);
}

函数中,按键按下'g'开始输出波形,再按一次停止波形。使用了一个全局的标志dac_start_flag,来做为输出的开关。

7、在blinky_thread_entry任务中,来对DAC进行波形的输出。

/***********************************************************************************************************************
* Copyright (c) 2021 - 2024 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
***********************************************************************************************************************/
#include <blinky_thread.h>

extern uint16_t custom_var[32];
extern uint8_t dac_start_flag;
/**********************************************************************************************************************
 * Function Name: blinky_thread_entry
 * Description  : .
 * Argument     : pvParameters (contains TaskHandle_t)
 * Return Value : .
 *********************************************************************************************************************/
void blinky_thread_entry(void *pvParameters)
{
    static int count;
    FSP_PARAMETER_NOT_USED (pvParameters);

    /* TODO: add your own code here */
    while (1)
    {
        if(dac_start_flag)
        {
            count ++;
            count = count%32;
            R_DAC_Write(&g_dac0_ctrl, custom_var[count]);
        }
        vTaskDelay (1);
    }
}
/**********************************************************************************************************************
 End of function blinky_thread_entry

【效果】

当我们进入菜单,按下g时,就开始输出波形,按下a,波形的电压值升高,按下s键波形缩小,按下w键,向flash写入当前波形数据,按下r,读取存取的数据。

 

 

【总结】

本次学习了DAC与按键输入,flash的读取。做了一个综合的例程。

 

最新回复

menu_ext.c中的函数,需要修改为全局的这个是技巧点   详情 回复 发表于 3 天前
点赞 关注
 
 

回复
举报

6694

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

menu_ext.c中的函数,需要修改为全局的这个是技巧点

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表