- 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个测品
个人信息无误,可以完成评测