king86

  • 2025-01-11
  • 回复了主题帖: 【回顾2024,展望2025】新年抢楼活动来啦!

    最想关注的是AI技术的发展。 新年flag:学会FreeRTOS、STM32CubemaxIDE软件的使用、Linux等。

  • 回复了主题帖: 【回顾2024,展望2025】新年抢楼活动来啦!

    最想关注的是AI技术的发展。 新年flag:学会FreeRTOS、STM32CubemaxIDE软件的使用、Linux等。

  • 回复了主题帖: 【回顾2024,展望2025】新年抢楼活动来啦!

    最想关注的是AI技术的发展。 新年flag:学会FreeRTOS、STM32CubemaxIDE软件的使用、Linux等。

  • 2025-01-07
  • 加入了学习《【Follow me第二季第3期】+ EK_RA6M5作品展示视频》,观看 Follow me第二季第3期 EK_RA6M5作品视频

  • 加入了学习《【Follow me第二季第3期】任务汇总视频》,观看 follow me2-3活动任务提交视频

  • 2024-12-15
  • 发表了主题帖: 【Follow me第二季第3期】EK-RA6M5+任务提交贴

    [localvideo]4d128b2efcc49008598513fd3d151838[/localvideo] 入门任务:搭建环境,下载调试示例程序,Blink,按键; 一、准备工作 下载FSP安装包: 前往Renesas(瑞萨电子)的官方网站,在MCU或开发工具页面找到FSP的下载区域。 下载连接: https://github.com/renesas/fsp/releases/tag/v5.5.0 选择FSP V5.6版本,并下载适用于Windows系统的安装包。     安装FSP V5_6版本。 安装环境: 在Windows系统上安装FSP(Flexible Software Package)V5.6版本,你可以按照以下步骤进行:   这个是V5.5V的下载连接: https://github.com/renesas/fsp/releases/tag/v5.5.0   二、安装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()); } } } } 六、视频 [localvideo]5f9d027a7f0f08a944d03325d6c276b5[/localvideo]     基础任务: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 数据寄存器按顺序写入逐渐增大的数字值,电压会呈线性上升趋势,形成一条斜率固定的直线段不断上升,直到达到输出范围的上限电压后,又快速跳回下限电压或者按需求设置循环起始点等情况,然后重复这个过程,形成一个个锯齿状的周期波形,波形的周期取决于写入一轮完整数字值的时间间隔,而锯齿的斜率与每次写入数字值的增量大小等配置有关。   视频: [localvideo]04e8264bc8418fccf20b92ba319da4aa[/localvideo]   进阶任务:示例程序中新增命令打印信息;   导入示例程序: 在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引脚的波形,在测量波形时,需要对示波器进行波形校准一下,不然出现的波形就会有失真。 方波:     三角波:   输入命令:     测量逻辑图:     输视频: [localvideo]c9b5e65f987106f88b4846cfbb47d3a6[/localvideo]   软件工作过程图:   总结: 总结一下我这些天弄这个6M5的心得,说一下个人的感受,瑞萨的环境装了有七八天,没有成功,最后请了其它的工程师也没有装成功,还请了野火的工程师帮助了我,无解,最后还是用虚拟机搞成功了。 从入门到进阶的MCU开发任务,包括环境搭建、基础配置与测试,以及进阶功能的实现。通过下载并安装FSP软件包,配置开发环境,成功运行了LED Blink示例程序,掌握了基础的开发流程。进行了quad-spi flash和octo-spi flash的配置及读写速度测试,这一步骤对于理解高速存储器的应用至关重要。还进行了DAC配置,生成了波形并进行了性能测试,为模拟信号的处理提供了基础。在进阶任务中,示例程序中新增了命令打印信息,提高了程序的可读性和可调试性。扩展任务设计了一个类似信号发生器功能的例程,通过命令或按键设置DAC输出波形,并可通过flash存储历史波形等信息,这一设计不仅提升了程序的实用性,也为后续的信号处理应用提供了有力支持。整个开发过程涵盖了从基础到进阶的多个层面,为MCU开发打下了坚实基础。        

  • 2024-02-03
  • 回复了主题帖: 测评入围名单(最后一批):年终回炉,FPGA、AI、高性能MCU、书籍等42个测品

    个人信息无误,可以完成评测

最近访客

< 1/1 >

统计信息

已有26人来访过

  • 芯积分:77
  • 好友:--
  • 主题:3
  • 回复:10

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言