御坂10032号

  • 2025-01-18
  • 回复了主题帖: 游戏玩家征集

    这个不就是支持宏的键盘一类吗

  • 回复了主题帖: EEWorld 2024年度人物:感恩相伴,共赴新程,携手努力!

    希望新的一年里EEWrold做大做强,再创辉煌!

  • 2025-01-17
  • 回复了主题帖: 【新年新挑战,任务打卡赢好礼!】第一批获奖名单公布

    已确认

  • 回复了主题帖: 回帖赢好礼 | 关于无线技术的那些事儿

     

  • 回复了主题帖: EEWorld 2024年度人物:感恩相伴,共赴新程,携手努力!

    感谢佬,感谢EEworld论坛,感谢各位工作人员。 一定再接再厉在今年继续分享高质量的内容!

  • 2025-01-14
  • 回复了主题帖: 新年新挑战,任务打卡赢好礼!

    本帖最后由 御坂10032号 于 2025-1-14 22:48 编辑 1-  2- 回复帖子       3- 大学堂学习   4 - 报名活动,得捷电子投票活动   5 - 资料下载      

  • 回复了主题帖: 【瓜分2500元红包】票选2024 DigiKey “感知万物,乐享生活”创意大赛人气作品TOP3!

    手机扫码已经投票!

  • 加入了学习《直播回放: 中星联华 - 高速信号完整性分析与测试》,观看 高速信号完整性分析与测试

  • 加入了学习《自己动手写嵌入式操作系统》,观看 时间片轮转和上下文切换

  • 加入了学习《自己动手写嵌入式操作系统》,观看 高级操作系统特性

  • 回复了主题帖: 【STM32H7S78-DK测评】3.转轮动效菜单的实现

    真流畅啊

  • 回复了主题帖: 关于TL431的使用问题

    不是太懂TL431不就是一个电压基准芯片吗? 好像就是输出2.5的参考电压

  • 回复了主题帖: DIY 耳机盒爆改随身音响(一)

    0.8元爆炸了我都夸它炸的响

  • 2025-01-13
  • 回复了主题帖: EEWORLD陪你过大年,新年积分兑换专场来啦~好物多多还有幸运盲盒!

    兑换了一个开发板盲盒,求中大奖!

  • 2025-01-11
  • 回复了主题帖: 【测评入围名单(第一批)】年终回炉:FPGA、AI、高性能MCU、书籍等65个测品邀你来~

    已经收到单号,感谢各位工作人员!

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

    ⑴遇到过什么技术问题: 今年一直在尝试着入门学习机器学习和深度学习, 感谢论坛的动手学pytorch 读书活动,使我受益匪浅 ⑵实现了哪些目标,达成了什么成就?: 今年最主要的收获在嵌入式方面上就是学习到了各种的软件知识, 和入门了PCB设计 在崭新的2025年 ⑶最想关注什么技术? :AI ⑷最想要什么支持?比如更多的某方面教程、资料、活动? : 希望论坛多举办一些AI方面的活动和测评学习机会。 ⑸立一个新年Flag : 希望,大家身体健健康康。家庭幸福美满!

  • 2025-01-08
  • 回复了主题帖: 【测评入围名单(第一批)】年终回炉:FPGA、AI、高性能MCU、书籍等65个测品邀你来~

    个人信息无误, 确认可以完成测评计划

  • 2024-12-25
  • 回复了主题帖: 2025年测评中心,DigiKey得捷赞助继续,欢迎跟帖推你期待的上线的测品啦~

    希望多出一些AI系列难度中等的开发板测评或者活动

  • 2024-12-13
  • 加入了学习《Follow me 第二季第3期成果视频》,观看 成果展示

  • 发表了主题帖: [Follow me第二季第3期] 作品提交

    本帖最后由 御坂10032号 于 2024-12-13 00:12 编辑 简介   大家好,接下来我将对项目的所有任务进行整合和汇总,并且介绍每个任务功能的核心代代码。   任务/项目介绍   本次项目采用的开发板是来自瑞萨电子的EK-RA6M5开发板, 它基于Arm®Cortex®-M33内核, 最高主频可以跑到200MHZ. 它一共有176个引脚。它不仅本身性能强悍,同时预留了很多其他生态的接口。 比如说 2个Seeed Grove®系统(I2C/模拟)连接器 ,SparkFun®Qwiic®连接器, 2个Digilent PmodTM(SPI和UART)连接器,ArduinoTM(Uno R3)连接器,和MikroElektronikaTM mikroBUS连接器。     本期一共有四个任务, 分别是下述。 入门任务:搭建环境,下载调试示例程序,Blink,按键; 基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试; 进阶任务:示例程序中新增命令打印信息; 扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。 实现思路: 入门任务:入门任务的主要实现思路是学习如何搭建环境信息, 以及如何使用E2studio创建工程,并且将示例程序使用debug接口下载到开发板上。 同时学习如何调整Demo的代码信息, 比如说增加额外的LED频率和占空比等等,以及如何读取IO输入。 基础任务:基础任务的Q-SPI falsh 和O-SPI flash的配置和读写速度测试,我们可以参照官方提供的函数进行实现。 对于DAC的配置如果不想在原本的项目上改的话, 可以在configuration.yml 中来快速配置, 并且快速的生成stack。然后使用Developer Assistance 来辅助我们快速完成。 进阶任务:进阶任务需要我们自己来创建一个菜单选项,并且集成在主菜单界面中。使其打印自定义的数据信息。 扩展任务:拓展任务实现起来相对复杂一点,但是其功能则是整合了上述所有的功能在一起。通过命令或者按键来生成不同的波形,同时可以将波形数据保存到Flash里,进行历史数据的保存或者直接输出。 软件流程图         由于上述的程序主要是在RTOS中运行的, 现在我来简单的解释一下上面的流程图。 首先在程序的初始化完成之后。 显示程序的菜单界面。 之后根据用户的输入进入到不同的子菜单选项。比如说板载的信息显示。 自定义命令。 或者QSPI操作DAC输出等。 而对于某些非本次任务的子菜单选项这次并没有额外的画出。 比如说Webserver的子菜单。 USB相关的等以便于理解。     主要功能、核心代码展示   入门任务核心代码及其功能演示:   入门任务的核心在于如何来追踪已经有的LED的频率和占空比信息等。我们可以非常方便的使用e2 studio 对 menu_kit.c 中相关的变量进行追踪和修改。       修改LED的相关信息       效果演示     基础任务核心代码及其功能演示:   基础任务的核心在于读懂如何使用官方的SPI-flash的读写测试部分, 虽然测试代码我们并不需要自己直接写,但是在后续的SPI flash 数据保存环节我们还需要继续使用。 所以能够看懂官方的代码也是至关重要的一项。 对于DAC的测试的重点有两个 ,1 如何使用FSP结合stack快速生成对应的库文件和初始化文件。 2 - 如何使用DAC相关的函数输出。   SPI-Flash 测试核心代码   static uint32_t qspi_write_test(uint32_t block_size) { fsp_err_t fsp_err; uint32_t qspi_write_result = 0; timer_status_t status = {}; fsp_err_t err = FSP_SUCCESS; spi_flash_protocol_t current_spi_mode; /* Convert from kB */ block_size *= 1024; /* The comms mode is EXTENDED_SPI by default */ current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI; /* 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; } uint32_t page_write_count = 0; uint8_t * p_mem_addr; /* Cast to req type */ p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS; while (((page_write_count * SECTOR_SIZE) < block_size) && ( FSP_SUCCESS == err ) ) { /* Erase Flash for one sector */ err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE); if (FSP_SUCCESS != err) { sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n"); } else { err = get_flash_status(); if (FSP_SUCCESS != err) { sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n"); } /* Verify the erased block data */ uint32_t count; for (count = 0; count < SECTOR_SIZE; count++ ) { if (DEFAULT_MEM_VAL != p_mem_addr[count]) { /* Verification failed, perhaps the ERASE failed */ err = FSP_ERR_NOT_ERASED; } } } p_mem_addr += SECTOR_SIZE; page_write_count++; } /* Start the test timer */ fsp_err = R_GPT_Start(g_memory_performance.p_ctrl); /* Handle error */ if (FSP_SUCCESS != fsp_err) { /* Fatal error */ SYSTEM_ERROR } /* Cast to req type */ p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS; page_write_count = 0; while (((page_write_count * PAGE_WRITE_SIZE) < block_size) && (FSP_SUCCESS == err)) { if (FSP_SUCCESS == err) { /* Write data to QSPI Flash */ /* Each block begins one character shifted along the source text. To avoid regular striping in memory */ err = R_QSPI_Write(&g_qspi_ctrl, &(sp_source[page_write_count]), p_mem_addr, PAGE_WRITE_SIZE); if (FSP_SUCCESS != err) { sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n"); } else { err = get_flash_status(); if (FSP_SUCCESS != err) { sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n"); } } } p_mem_addr += PAGE_WRITE_SIZE; page_write_count++; } /* close QSPI module */ deinit_qspi(current_spi_mode); fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl); /* Handle error */ if (FSP_SUCCESS != fsp_err) { /* Fatal error */ SYSTEM_ERROR } fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status); /* Handle error */ if (FSP_SUCCESS != fsp_err) { /* Fatal error */ SYSTEM_ERROR } fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl); /* Handle error */ if (FSP_SUCCESS != fsp_err) { /* Fatal error */ SYSTEM_ERROR } qspi_write_result = status.counter; return (qspi_write_result); }   相关的DAC配置信息       效果如下所示:     DAC输出的效果     进阶任务核心代码及其功能演示   进阶任务的核心在于如何读懂原本的命令菜单方面的代码。 如果读懂了的话,我们可以非常方便的在原本的功能上面进行拓展。   主菜单核心代码 /* Table of menu functions */ static st_menu_fn_tbl_t s_menu_items[] = { {"Kit Information" , kis_display_menu}, {"Hello world" , ns_display_hello_world}, {"QSPI Operation" , ns_display_qspi_write}, {"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 } };   子菜单核心代码   /* * menu_text.c * * Created on: 2024年12月1日 * Author: 23391 */ #include "FreeRTOS.h" #include "FreeRTOSConfig.h" #include "semphr.h" #include "queue.h" #include "task.h" #include "common_init.h" #include "common_utils.h" #include "menu_text.h" #define CONNECTION_ABORT_CRTL (0x00) #define MENU_EXIT_CRTL (0x20) static char_t s_print_buffer[BUFFER_LINE_LENGTH] = {}; #define MODULE_NAME "\r\n%d. Hello world!\r\n" test_fn ns_display_hello_world (void) { int8_t c = -1; print_to_console((void*)s_print_buffer); sprintf (s_print_buffer, MODULE_NAME, g_selected_menu); print_to_console((void*)s_print_buffer); sprintf (s_print_buffer, MENU_RETURN_INFO); while ((CONNECTION_ABORT_CRTL != c)) { c = input_from_console (); if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c)) { break; } } return (0); }   效果演示       拓展任务核心代码及其功能演示   拓展任务实际上是将上述的所有任务整合在了一起,通过将上述的所有任务进行整合,从而来达到我们任务的目的。 拓展任务中我们需要将历史波形信息保存到Flash, 然后根据从Flash里读取的波形来驱动DAC输出不同的波形(正弦波和三角波等)   生成正弦波代码   void generate_sine_wave(uint16_t *sine_wave_array, size_t size) { for (size_t i = 0; i < size; i++) { // Generate sine wave: scale to 0 - MAX_AMPLITUDE sine_wave_array[i] = (uint16_t) ((sin ((double) i * 2.0 * 3.1415926 / size) + 1.0) * (MAX_AMPLITUDE / 2.0)); } }   生成三角波代码   void generate_triangle_wave(uint16_t *triangle_wave_array, size_t size) { size_t half_period = size / 2; // Half period of the triangle wave for (size_t i = 0; i < size; i++) { if (i < half_period) { // Rising edge: 0 to MAX_AMPLITUDE triangle_wave_array[i] = (uint16_t) ((double) i / (half_period - 1) * MAX_AMPLITUDE); } else { // Falling edge: MAX_AMPLITUDE to 0 triangle_wave_array[i] = (uint16_t) ((double) (size - i - 1) / (half_period - 1) * MAX_AMPLITUDE); } } }   SPI Flash 的保存和读取   void saveToFlash(uint8_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; p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS; 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, 4096U); if (FSP_SUCCESS != err) { sprintf (s_print_buffer, "Failed to erase QSPI flash\r\n"); print_to_console ((void*) s_print_buffer); return; } /* 等待擦除完成 */ err = get_flash_status (); if (FSP_SUCCESS != err) { sprintf (s_print_buffer, "Failed to get flash status after erase\r\n"); print_to_console ((void*) s_print_buffer); 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"); print_to_console ((void*) s_print_buffer); } else { err = get_flash_status (); if (FSP_SUCCESS != err) { sprintf (s_print_buffer, "Failed to get flash status after write\r\n"); print_to_console ((void*) s_print_buffer); } } deinit_qspi (current_spi_mode); } void readFromFlash(uint8_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; /* 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; } memcpy (&buffer[0], p_mem_addr, 1); deinit_qspi (current_spi_mode); }   效果展示       所有功能的实现思路和效果演示请查看每个帖子,或者是总结视频,总结视频中详细讲解了每个任务的实现步骤。     总结和建议   非常感谢得捷电子和电子工程世界提供的这次来之不易的活动机会。 我个人觉得本次的活动安排的非常好, 每个任务和衔接非常严谨。最后又通过一个完成的demo设计将上述所有的任务整合在了一起, 让我在本次活动中所学到的知识都联系了起来。 希望得捷电子和电子工程世界越办越好。再次感谢!     成功视频展示     代码附件信息   代码下载链接(点击跳转, 已经包含了每个部分的完整代码实现)  

最近访客

< 1/6 >

统计信息

已有193人来访过

  • 芯积分:704
  • 好友:2
  • 主题:64
  • 回复:129

留言

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


现在还没有留言