180|0

13

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第3期】EK-RA6M5+任务提交贴 [复制链接]

 

1月7日 (1)


入门任务:搭建环境,下载调试示例程序,Blink,按键;

一、准备工作

下载FSP安装包:

前往Renesas(瑞萨电子)的官方网站,在MCU或开发工具页面找到FSP的下载区域。

下载连接:

链接已隐藏,如需查看请登录或者注册

选择FSP V5.6版本,并下载适用于Windows系统的安装包。

 

 

安装FSP V5_6版本。

安装环境:

在Windows系统上安装FSP(Flexible Software Package)V5.6版本,你可以按照以下步骤进行:

 

这个是V5.5V的下载连接:

链接已隐藏,如需查看请登录或者注册

 

二、安装FSP

运行安装包:

双击下载的安装包文件,启动FSP的安装程序。

 

下面以4.4的为例进行安装流程截图:

 

 

阅读并接受许可协议:

在安装过程中,你需要阅读并接受FSP的许可协议。

如果同意协议条款,请继续下一步。

 

选择安装路径:

指定FSP的安装路径。默认情况下,安装程序会选择系统的默认程序文件夹。

你可以根据需要更改安装路径。

开始安装:

点击“安装”或“下一步”按钮,开始安装FSP。

安装过程中,安装程序可能会提示你确认某些设置或权限请求。

完成安装:

当安装程序提示安装完成时,点击“完成”或“关闭”按钮退出安装程序。

 

到这里就安装完成了。

三、配置和使用FSP

配置开发环境:

如果你使用的是特定的IDE(e² studio),你需要配置IDE以使用FSP。

这通常包括设置包含路径、库路径等,以便IDE能够正确识别和编译FSP的模块和函数。

创建和初始化工程:

在IDE中创建一个新的工程,并选择适当的MCU型号和FSP模块。

根据需要配置工程的各项参数,如时钟设置、引脚配置等。

编译和调试:

使用IDE的编译功能来编译你的工程,并生成可执行文件。

将可执行文件下载到你的MCU上进行调试和测试。

 

四、调试示例程序点灯LED

下面以导入示例进行截图讲解:

  导入示例:

 

构建项目:

右击项目名称,选择“Build Project”,编译项目。

 

调试项目:

连接EK-RA6M5开发板到电脑,选择调试配置(如Debug Configuration),设置串口通信波特率为115200(或其他适当的波特率)。

点击“Debug”按钮,开始调试程序。

 

五、实现LED Blink

找到LED引脚:

在开发板的原理图中找到板载LED的引脚连接情况,LED1可能连接在P006引脚。

 

配置引脚:

打开e2 studio中的配置xml文件,选中Pins一栏,输入引脚编号以自动定位到该引脚配置界面。

根据LED的接法,设置引脚默认输出电平。

 

添加闪烁代码:

在hal_entry函数中添加循环代码,使LED不断闪烁。

参加示例

void hal_entry(void) {
    while(1){
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, BSP_IO_LEVEL_HIGH); //LED1亮
        R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); //延时500ms
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, BSP_IO_LEVEL_LOW); //LED1灭
        R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); //延时500ms
    }
}

实际输出代码:

void blinky_thread_create(void)
{
    g_fsp_common_thread_count++;

#if 1
    blinky_thread = xTaskCreateStatic (
#else
                    BaseType_t blinky_thread_create_err = xTaskCreate(
                    #endif
                                       blinky_thread_func,
                                       (const char*) "Blinky Thread", 4096 / 4, // In words, not bytes
                                       (void*) &blinky_thread_parameters, //pvParameters
                                       6,
#if 1
                                       (StackType_t*) &blinky_thread_stack,
                                       (StaticTask_t*) &blinky_thread_memory
#else
                        & blinky_thread
                        #endif
                                       );
#if 1
    if (NULL == blinky_thread)
    {
        rtos_startup_err_callback (blinky_thread, 0);
    }
#else
                    if (pdPASS != blinky_thread_create_err)
                    {
                        rtos_startup_err_callback(blinky_thread, 0);
                    }
                    #endif
}
static void blinky_thread_func(void *pvParameters)
{
    rtos_startup_common_init ();

#if (1 == BSP_TZ_NONSECURE_BUILD) && (1 == 1)
                     portALLOCATE_SECURE_CONTEXT(0);
                    #endif
    blinky_thread_entry (pvParameters);
}


#define BUTTON_DEBOUNCE_RATE (500)

extern bool g_usb_configured;
extern adc_info_t g_adc_info_rtn;

uint32_t g_pwm_dcs[4] =
{ LED_INTENSITY_10, LED_INTENSITY_30, LED_INTENSITY_50, LED_INTENSITY_90 };
uint32_t g_pwm_rates[4] =
{ BLINK_FREQ_1HZ, BLINK_FREQ_3HZ, BLINK_FREQ_5HZ, BLINK_FREQ_10HZ };

st_board_status_t g_board_status =
{ };

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

按键引脚: 在开发板的原理图中找到按键的引脚连接情况,按键1可能连接在P005引脚,按键2可能连接在P004引脚。

 

 

配置引脚: 同样在配置xml文件中,设置按键引脚的默认状态。 添加按键扫描代码: 在hal_entry函数中添加按键扫描代码,用于检测按键状态并执行相应操作。

 

参考示例:

void KeyScan(bsp_io_port_pin_t key){
    bsp_io_level_t key_state;
    R_IOPORT_PinRead(&g_ioport_ctrl, key, &key_state);
    if(key_state==BSP_IO_LEVEL_LOW){ //按键按下
        R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS); //软件消抖
        //执行按键按下时的操作,如点亮另一个LED
        R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_HIGH); //假设LED2连接在另一个引脚
        //等待按键松开
        while(key_state==BSP_IO_LEVEL_LOW){
            R_IOPORT_PinRead(&g_ioport_ctrl, key, &key_state);
        }
        //按键松开后的操作,如熄灭LED2
        R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_LOW);
    }
}

实际代码:


//读取按键状态
bsp_io_level_t Read_Button()
{
    bsp_io_level_t button_value = BSP_IO_LEVEL_HIGH ;
    R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &button_value);
    return button_value;
}

void hal_entry(void)
{

    bsp_io_level_t LED_value = BSP_IO_LEVEL_HIGH ;

#if BSP_TZ_SECURE_BUILD

    R_BSP_NonSecureEnter();
#endif
    R_IOPORT_Open(&g_ioport_ctrl, &g_ioport.p_cfg);
    while(1)
    {
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, LED_value);
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_07, LED_value);
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, LED_value);
        if(BSP_IO_LEVEL_LOW==Read_Button())
        {
            R_BSP_SoftwareDelay(50,BSP_DELAY_UNITS_MILLISECONDS);
            if(BSP_IO_LEVEL_LOW==Read_Button())
            {
                //判断为真的按下 进行状态反转
                if(BSP_IO_LEVEL_HIGH==LED_value)
                {
                    LED_value=BSP_IO_LEVEL_LOW;
                }else
                {
                    LED_value=BSP_IO_LEVEL_HIGH;
                }
                while (BSP_IO_LEVEL_HIGH != Read_Button());
            }
        }
    }
}

六、视频

701818abf4e2a19a0d14c32b71763689

 

 

基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试;

 

一、quad-spi flash和octo-spi flash配置及读写速度测试

配置

quad-spi flash和octo-spi flash的配置通常涉及设置SPI接口的相关参数,时钟频率、数据位宽、传输模式读/写等,配置可以通过微控制器的寄存器或专用的SPI配置函数来完成。

在进行配置之前,需要确保微控制器的SPI接口已经正确初始化,并且与flash存储器的连接正确无误。

 

读写速度测试

读写速度测试的目的是评估quad-spi flash和octo-spi flash在实际应用中的性能表现。

使用微控制器向flash存储器写入一定量的数据,并记录写入所需的时间,再从flash存储器中读取这些数据,并记录读取所需的时间。

获得更准确的测试结果,多次进行测试,并取平均值作为最终结果,测试不同大小的数据块,以评估flash存储器在不同负载下的性能表现。

代码:

    {"Kit Information"                         , kis_display_menu},
    {"Added Demo Information For Test "        , Demo_Information}, //added
    {"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},
    {"Next Steps", ns_display_menu },
    {"", NULL }




    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, FULL_NAME);

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

    for (int8_t test_active = 0; NULL != s_menu_items[test_active].p_func; test_active++ )
    {
        sprintf (s_print_buffer, "\r\n %d. %s", (test_active + 1), s_menu_items[menu_limit++ ].p_name);

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

    while ((0 != c))
    {
        c = input_from_console ();
        if (0 != c)
        {
            /* Cast, as compiler will assume calc is int */
            c = (int8_t) (c - '0');
            g_selected_menu = c;

            if ((c > 0) && (c <= menu_limit))
            {
                s_menu_items[c - 1].p_func ();
                break;
            }
        }

 

SPI 接口初始化前提

微控制器的 SPI 接口是与 flash 存储器交互的关键通道,所以要确保其已经正确初始化。这包括配置 SPI 接口的基本引脚功能(如时钟线、数据线等引脚的模式设置),使能 SPI 模块等基础操作,还要检查与 flash 存储器之间的物理连接线路,保证线路连接正确、无断路或短路等问题,避免后续配置和读写操作出现通信故障。

 

 SPI 接口初始化前提

微控制器的 SPI 接口是与 flash 存储器交互的关键通道,所以要确保其已经正确初始化。这包括配置 SPI 接口的基本引脚功能(如时钟线、数据线等引脚的模式设置),使能 SPI 模块等基础操作,同时还要检查与 flash 存储器之间的物理连接线路,保证线路连接正确、无断路或短路等问题,避免后续配置和读写操作出现通信故障。

配置参数说明

时钟频率:决定了 SPI 数据传输的速率,一般可以根据 flash 存储器的规格以及实际应用对速度的需求来设置。有的应用要求快速读写,就可以适当提高时钟频率,但也要考虑到 flash 存储器和微控制器的支持能力,过高的频率可能导致数据传输错误。

数据位宽:确定了每次传输数据的位数,常见的有 8 位、16 位等。不同的 flash 存储器可能支持不同的数据位宽,要按照其手册要求进行合理设置,以便正确地进行数据收发。

传输模式(读 / 写):明确了当前操作是向 flash 存储器写入数据还是从中读取数据。这涉及到 SPI 接口的控制信号以及数据流向等设置,要根据具体的读写需求进行相应切换。

 

输出结果:

软件工作流程图:

 

 

 

二、DAC配置生成波形及性能测试

DAC配置

DAC的配置涉及设置其工作模式、分辨率、输出范围等参数,参数可以通过微控制器的寄存器或专用的DAC配置函数来完成。

DAC的工作模式通常包括正常模式和自动模式。DAC根据数据寄存器中的数字值输出对应的电压。

波形生成

波形生成是通过向DAC的数据寄存器写入一系列数字值来实现的。数字值可以表示不同的电压电平,从而在DAC的输出端产生相应的模拟信号。

为了生成特定的波形(正弦波、锯齿波等),需要按照波形的数学模型计算出一系列数字值,并将它们依次写入DAC的数据寄存器。可以通过微控制器的定时器中断或DMA直接存储器访问来实现。

连接实物图,连接P014引脚:

 

在实物连接图中,会展示微控制器的主体部分以及 DAC 相关电路模块,P014 引脚会用清晰的线条标识出来,它作为 DAC 输出引脚,连接到外部的测量设备或者后续需要接收模拟信号的电路部分。

在波形图上可以同时标注出这个 P014 引脚对应的波形,也就是经过 DAC 配置和波形生成操作后,从该引脚输出的实际模拟信号波形情况,以此表明波形图与实物连接之间的对应关系,让使用者能直观看到电路连接后的实际信号输出表现。

 

 

使用逻辑分析仪抓取输出波形:

 

正弦波生成波形图:

以时间为横轴,DAC 输出电压为纵轴。按照正弦波的数学模型对于 8 位分辨率,设定好满量程对应的电压幅值等参数,计算出一系列对应不同时刻的数字值,将这些值依次写入 DAC 数据寄存器后,在输出端就会生成一个周期性的正弦波形。波形呈现出平滑的、周期性的、以一定频率在设定的输出电压范围内上下波动的形状,从波峰到波谷再到波峰,符合正弦函数的曲线特征,并且这个波形的频率取决于向 DAC 写入数据的速度由定时器中断触发写入的频率等因素决定。

 

锯齿波生成波形图:

同样以时间为横轴,电压为纵轴,开始时电压从最低值输出范围的下限开始,随着向 DAC 数据寄存器按顺序写入逐渐增大的数字值,电压会呈线性上升趋势,形成一条斜率固定的直线段不断上升,直到达到输出范围的上限电压后,又快速跳回下限电压或者按需求设置循环起始点等情况,然后重复这个过程,形成一个个锯齿状的周期波形,波形的周期取决于写入一轮完整数字值的时间间隔,而锯齿的斜率与每次写入数字值的增量大小等配置有关。

 

视频:

2024-12-12 23-28-26

 

进阶任务:示例程序中新增命令打印信息;

 

导入示例程序:

在IDE(e²studio)中正确导入了 _quickstart 示例程序,在IDE中导入已下载的例程包中的“_quickstart”例程,并进行检查,是否有错误,需要把错误的地方进行更改。

 

打印函数:

在 _quickstart 示例程序中,查找与串口通信相关的部分,UART初始化代码和用于发送数据的函数,并进行移植并配置了 xprintf() 库类似于标准 printf() 的扩展,用于嵌入式系统,则可以直接使用它进行打印。

 

 

 

测试打印信息:

在进行调试时,一定要进行调试运行后,才会有端口显示,不然PC端无法进行端口显示。

通过串口调试工具或软件自带终端,观察输出的打印信息。

 

 

 

扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。

 

一、代码实现

配置好DAC、Flash存储器、USART(用于接收命令)和GPIO(用于按键输入)的外设。

初始化配置

生成初始化代码,包括DAC、Flash、USART和GPIO的配置。

DAC波形生成函数

创建不同的波形生成函数,正弦波、方波、三角波等。

参考示例      :

#include <math.h>  // 为了使用 sin() 函数
#include <stdint.h>
#include <string.h>  // 为了使用 memset()

// 假设这些宏和变量已经在其他地方定义
//#define QSPI_DEVICE_START_ADDRESS 0x...
//#define SECTOR_SIZE 0x...
//extern fsp_ctrl_t g_qspi_ctrl;
//extern qspi_cfg_t g_qspi_cfg;
//extern char s_print_buffer[];

// 正弦波生成函数
void GenerateSineWave(uint16_t *buffer, int num_samples, int amplitude, double frequency, int sample_rate) {
    for (int i = 0; i < num_samples; i++) {
        double theta = 2.0 * M_PI * frequency * i / sample_rate;
        buffer[i] = (uint16_t)(amplitude * (sin(theta) + 1.0) / 2.0 * 0xFFFF); // 转换到0-0xFFFF范围
    }
}

// 修改后的 SaveWaveToFlash 函数
void SaveWaveToFlash(uint16_t *buffer, int num_samples) {
    fsp_err_t err = FSP_SUCCESS;
    uint8_t *p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS;
    spi_flash_protocol_t current_spi_mode;

    /* 初始化 QSPI 和设置通信模式 */
    err = qpi_init();
    if (FSP_SUCCESS != err) {
        sprintf(s_print_buffer, "Failed to initialize QSPI module\r\n");
        return;
    }
    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");
        deinit_qspi(current_spi_mode);
        return;
    }

    /* 等待擦除完成 */
    err = get_flash_status();
    if (FSP_SUCCESS != err) {
        sprintf(s_print_buffer, "Failed to get flash status after erase\r\n");
        deinit_qspi(current_spi_mode);
        return;
    }

    /* 生成正弦波数据 */
    int amplitude = 0xFFFF; // 最大振幅
    double frequency = 1.0; // 正弦波频率(需要根据实际情况调整)
    int sample_rate = num_samples * 10; // 假设每个样本代表0.1秒(需要根据实际情况调整)
    memset(buffer, 0, num_samples * sizeof(uint16_t)); // 清空缓冲区
    GenerateSineWave(buffer, num_samples, amplitude, frequency, sample_rate);

    /* 写入正弦波数据到 QSPI 闪存 */
    err = R_QSPI_Write(&g_qspi_ctrl, buffer, p_mem_addr, num_samples * sizeof(uint16_t));
    if (FSP_SUCCESS != err) {
        sprintf(s_print_buffer, "Failed to write sine wave 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");
        }
    }

    /* 关闭 QSPI 模块 */
    deinit_qspi(current_spi_mode);
}

 实际输出代码:

void DAC_Wave(char wavetype)
{
        static int value=0;
        if(wavetype==1)        R_DAC_Write(&g_dac0_ctrl, value);                    //added 锯齿波
        if(wavetype==2)        R_DAC_Write(&g_dac0_ctrl, value > 2050 ? 4095 : 0);  //added 方波
        value=value+20;
        if(value>=4095) value=0;
}

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;

    /* 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;
    }

    err = R_QSPI_Write (&g_qspi_ctrl, &buffer[0], p_mem_addr, 1);
    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");
        }
    }



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

采用示波器抓取P014引脚的波形,在测量波形时,需要对示波器进行波形校准一下,不然出现的波形就会有失真。

方波:

 

 

三角波:

 

输入命令:

 

 

测量逻辑图:

 

 

输视频:

2030af231033c76c1181325435db4f50

 

软件工作过程图:

 

总结:

总结一下我这些天弄这个6M5的心得,说一下个人的感受,瑞萨的环境装了有七八天,没有成功,最后请了其它的工程师也没有装成功,还请了野火的工程师帮助了我,无解,最后还是用虚拟机搞成功了。

从入门到进阶的MCU开发任务,包括环境搭建、基础配置与测试,以及进阶功能的实现。通过下载并安装FSP软件包,配置开发环境,成功运行了LED Blink示例程序,掌握了基础的开发流程。进行了quad-spi flash和octo-spi flash的配置及读写速度测试,这一步骤对于理解高速存储器的应用至关重要。还进行了DAC配置,生成了波形并进行了性能测试,为模拟信号的处理提供了基础。在进阶任务中,示例程序中新增了命令打印信息,提高了程序的可读性和可调试性。扩展任务设计了一个类似信号发生器功能的例程,通过命令或按键设置DAC输出波形,并可通过flash存储历史波形等信息,这一设计不仅提升了程序的实用性,也为后续的信号处理应用提供了有力支持。整个开发过程涵盖了从基础到进阶的多个层面,为MCU开发打下了坚实基础。

 

DAC_test.zip (1.25 MB, 下载次数: 2)

 

 

 

20241215211142159.zip

48.47 MB, 下载次数: 3

2024121521122337.zip

48.47 MB, 下载次数: 7

点赞 关注
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表