254|0

27

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第3期】+项目总结 [复制链接]

  本帖最后由 superw 于 2025-1-13 12:37 编辑

一、视频介绍


 

二、任务实现详情

入门任务:搭建环境,下载调试示例程序,Blink,按键
物料清单:EK-RA6M5
设计思路:
根据出厂示例程序,通过按键外部中断控制LED灯的亮度(占空比)和闪烁快慢(频率),将按键的GPIO配置为外部中断模式,每当按下时跳转到中断服务函数中,进行占空比和频率的切换。按键默认状态下被外部电阻上拉,当按下按键时,IO为低电平,因此要配置为下降沿触发中断。
对于占空比和频率的输出,通过配置内部定时器实现输出。
软件流程图:
 
代码片段:
/**********************************************************************************************************************
 * Function Name: button_irq10_callback
 * Description  : SW1 Interrupt handler.
 * Argument     : p_args
 * Return Value : None
 *********************************************************************************************************************/
void button_irq10_callback(external_irq_callback_args_t *p_args)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    BaseType_t xResult = pdFAIL;
    EventBits_t uxBits;

    /* Void the unused args */
    FSP_PARAMETER_NOT_USED(p_args);

    uxBits = xEventGroupGetBitsFromISR (g_update_console_event);

    if ((uxBits & (STATUS_UPDATE_INTENSE_INFO)) != (STATUS_UPDATE_INTENSE_INFO))
    {
        /* Cast, as compiler will assume calc is int */
        g_board_status.led_intensity = (uint16_t) ((g_board_status.led_intensity + 1) % 5);
        xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_INTENSE_INFO,
                                            &xHigherPriorityTaskWoken);

        /* Was the message posted successfully? */
        if (pdFAIL != xResult)
        {
            /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
             switch should be requested.  The macro used is port specific and will
             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
             the documentation page for the port being used. */
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
    }
}
/**********************************************************************************************************************
 End of function button_irq10_callback
 *********************************************************************************************************************/

/* SW 2 */
/**********************************************************************************************************************
 * Function Name: button_irq9_callback
 * Description  : SW2 interrupt handler.
 * Argument     : p_args
 * Return Value : None
 *********************************************************************************************************************/
void button_irq9_callback(external_irq_callback_args_t *p_args)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    BaseType_t xResult = pdFAIL;
    EventBits_t uxBits;

    /* Void the unused args */
    FSP_PARAMETER_NOT_USED(p_args);

    uxBits = xEventGroupGetBitsFromISR (g_update_console_event);

    if ((uxBits & (STATUS_UPDATE_FREQ_INFO)) != (STATUS_UPDATE_FREQ_INFO))
    {
        /* Cast, as compiler will assume calc is int */
        g_board_status.led_frequency = (uint16_t) ((g_board_status.led_frequency + 1) % 5);
        xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_FREQ_INFO, &xHigherPriorityTaskWoken);

        /* Was the message posted successfully? */
        if (pdFAIL != xResult)
        {
            /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
             switch should be requested.  The macro used is port specific and will
             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
             the documentation page for the port being used. */
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
    }
}
/**********************************************************************************************************************
 End of function button_irq9_callback
 *********************************************************************************************************************/
uint32_t g_pwm_dcs[5] =
{ LED_INTENSITY_10, LED_INTENSITY_30, LED_INTENSITY_50, LED_INTENSITY_70, LED_INTENSITY_90 };
uint32_t g_pwm_rates[5] =
{ BLINK_FREQ_1HZ, BLINK_FREQ_3HZ, BLINK_FREQ_5HZ, BLINK_FREQ_7HZ, BLINK_FREQ_10HZ };

st_board_status_t g_board_status =
{ };

uint8_t g_pwm_dcs_data[] =
{ 10, 30, 50, 70, 90 };
uint8_t g_pwm_rates_data[] =
{ 1, 3, 5, 7, 10 };

功能展示:

 
基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试
物料清单:EK-RA6M5
设计思路:
EK-RA6M5板载有QSPI和OSPI存储器,QSPI Flash对应型号为MX25L25645G,采用四线SPI模式操作;OSPI Flash对应型号为MX25LM51245GM,采用八线SPI模式操作。开发板上内部已连接好线路,无需额外硬件连接。
关于QSPI的引脚和外设配置如下
关于OSPI的引脚和外设配置如下
同时,官方针对EK-RA6M5提供的fsp开发包里面也有关于QSPI和OSPI的相关例程,可以进行学习。
RA6M5芯片具有一个DAC外设,两个通道,可以分别输出不同的电压值或者波形。关于DAC的引脚和外设配置如下
软件流程图:
 
代码片段:
block_size_actual = value;

    if ((MENU_ENTER_RESPONSE_CRTL == c) && (0 != block_size_actual))
    {
        fsp_err_t      fsp_err;
        uint32_t       ospi_read_result  = 0;
        uint32_t       ospi_write_result = 0;
        uint32_t       qspi_read_result  = 0;
        uint32_t       qspi_write_result = 0;

        fsp_err = R_GPT_Open(g_memory_performance.p_ctrl, g_memory_performance.p_cfg);

        /* Handle error */
        if (FSP_SUCCESS != fsp_err)
        {
            /* Fatal error */
            SYSTEM_ERROR
        }

        sprintf(s_print_buffer, "\r\n\r\nGenerated a text block of %2lu KB in SRAM\r\n", block_size_actual);

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

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)
                "\r\nWriting the text block to external Quad-SPI and Octo-SPI flash memories...\r\n");

        uint32_t ospi_performance_write_result = 0;
        uint32_t ospi_performance_read_result = 0;
        uint32_t timer_frequency;


        R_GPT_InfoGet(g_memory_performance.p_ctrl, &timer_info);
        timer_frequency = timer_info.clock_frequency;

        ospi_performance_test (block_size_actual, &ospi_performance_write_result, &ospi_performance_read_result);

        /* Multiply uSec calcs by 100, to avoid losses due to small results in integer maths
         * Scaled to fit within uint32_t */
        ospi_write_result = ((100000000 / timer_frequency) * ospi_performance_write_result) / 100;
        qspi_write_result  = ((100000000 / timer_frequency) * qspi_write_test(block_size_actual)) / 100;

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"Writing to flash completed\r\n");

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\nReading the text block from external Quad-SPI and Octo-SPI flash memories...\r\n");

        ospi_read_result  = ((100000000 / timer_frequency) * ospi_performance_read_result) / 100;
        qspi_read_result  = ((100000000 / timer_frequency) * qspi_read_test(block_size_actual)) / 100;

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"Reading from flash completed\r\n");

        R_GPT_Close(g_memory_performance.p_ctrl);

        /* Handle error */
        if (FSP_SUCCESS != fsp_err)
        {
            /* Fatal error */
            SYSTEM_ERROR
        }

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\n-------------------------------------------------");

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\nOperation/Flash     Quad-SPI       Octa-SPI");

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\n-------------------------------------------------");
        sprintf(s_print_buffer, "\r\nWrite                %6ld         %6ld", qspi_write_result , ospi_write_result);

        /* 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, "\r\nRead                 %6ld         %6ld", qspi_read_result , ospi_read_result);

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

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\n-------------------------------------------------");

        /* ignoring -Wpointer-sign is OK for a constant string */
        print_to_console((uint8_t *)"\r\nNote: Times are in microseconds");
        sprintf(s_print_buffer, MENU_RETURN_INFO);

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

    while ((CONNECTION_ABORT_CRTL != c))
    {
        if ((MENU_EXIT_CRTL == c) || (0x00 == c))
        {
            break;
        }
        c = input_from_console();
    }

功能展示:

分别对QSPI和OSPI写入32KB数据并读出,测试结果如下
 
进阶任务:示例程序中新增命令打印信息
物料清单:EK-RA6M5
设计思路:
官方提供的出厂demo中已经预置了7条测试命令,包括USB、以太网等等,对于新增命令打印信息,找到官方实现的函数,依葫芦画瓢即可。
软件流程图:
 
代码片段:
/* Table of menu functions */
static st_menu_fn_tbl_t s_menu_items[] =
{
    {"Kit Information"                         , kis_display_menu},
    {"Web Server"                              , eth_emb_display_menu},
    {"Network Name Lookup"                     , eth_www_display_menu},
    {"Quad-SPI and Octo-SPI Speed Comparison"  , ext_display_menu},
    {"Cryptography and USB High speed (MSC)"   , enc_display_menu},
    {"DAC & DDS Test"   , dds_display_menu},
    {"Next Steps", ns_display_menu },
    {"", NULL }
};

功能展示:

 
扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息
物料清单:EK-RA6M5
设计思路:
扩展任务将和进阶任务中新增的命令、基础任务中使用DAC生成波形结合,共同实现通过串口命令行发送相应指令,开发板输出对应的波形。具体配置前面任务已经介绍过,不再介绍。
软件流程图:
 
代码片段:
#include <math.h>

#define M_PI        3.14159265358979323846
uint16_t dac_val = 0;
uint8_t change_flag = 0;

/**********************************************************************************************************************
 * Function Name: gpt_blue_callback
 * Description  : Callback function for driver g_gpt_blue.
 * Argument     : p_args
 * Return Value : .
 *********************************************************************************************************************/
void gpt_blue_callback(timer_callback_args_t * p_args)
{
    /* Void the unused params */
    FSP_PARAMETER_NOT_USED(p_args);


    static double w = 0.0;
    w += M_PI / 30;
    if(w >= M_PI*2)
    {
        w = 0.0;
    }
    dac_val = (sin(w)+1) /2 * 4095;
    change_flag = 1;

    //R_DAC_Write(&g_dac0_ctrl, dac_val);

    switch (s_blueled_flashing)
    {
        case ON:
        {
            if ((s_intense++ ) < s_duty)
            {
                TURN_BLUE_ON
            }
            else
            {
                TURN_BLUE_OFF
            }

            if (s_intense >= 100)
            {
                s_intense = 0;
                s_duty = g_pwm_dcs[g_board_status.led_intensity];
            }
            break;
        }
        default:
        {
            TURN_BLUE_OFF
            s_intense = 0;
            s_duty = g_pwm_dcs[g_board_status.led_intensity];
        }
    }
}
test_fn dds_display_menu(void)
{
    int8_t c = -1;

    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, DDS_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, DDS_SUB_OPTIONS);
    print_to_console((void*)s_print_buffer);

    /* 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, MENU_RETURN_INFO);

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

    /* provide small delay so board_status should be up to date */
    vTaskDelay (s_ticks_to_wait);
    xEventGroupSetBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);

    while (CONNECTION_ABORT_CRTL != c)
    {
        c = input_from_console ();
        if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c))
        {
            break;
        }
        if(MENU_SIN_CRTL == c)
        {
            while(1)
            {

                    R_DAC_Write(&g_dac0_ctrl, dac_val);

            }


        }
        else if(MENU_SQUARE_CRTL == c)
        {

        }
        else if(MENU_TRIANGULAR_CRTL == c)
        {

        }
    }

    xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);
    return (0);
}

功能展示:

进入DAC&DDS Test测试界面后,输入键盘上的小写字母a、b、c将分别通过DAC输出正弦波、方波、三角波。
示波器观察到的波形
 
心得体会
非常感谢活动主办方提供这么棒的开发板供大家学习,个人感觉这次的难度是今年四期中最难的了,但是啃硬骨头啃完的感觉真爽,未来争取不让这块开发板吃灰,板载这么多外设,争取让它继续发光发热。
 
三、可编译下载的代码

点赞 关注
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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