aramy

  • 2025-01-31
  • 回复了主题帖: 【Luckfox Pico Max评测】TMF8821驱动移植与测试

    大佬!牛逼!

  • 2025-01-22
  • 回复了主题帖: 《Hello算法》开卷有益——迭代和递归算法

    eew_Ya3s2d 发表于 2025-1-22 14:49 表达是挺简便的,但是计算的时候是不是会反复调用函数,是不是调用的数据越大,迭代的次数越大,消耗的时间 ... 迭代不会。迭代不会反复调用自身,如果有子函数,每次调用结束后就释放了资源。但是递归会,递归会重复调用自身,每次调用,都要将当前状态入栈,所以空间消耗比较大。

  • 发表了主题帖: 《Hello算法》开卷有益——迭代和递归算法

      计算机中算法是个奇怪的东西。首先是极其重要,生活中各种问题的解决都需要使用到算法,计算机软件就是一个由算法构成的庞大工程,但另一方面,它又暗暗隐藏,平时能看见的各种软件都已经将算法隐藏在其中了,可以无需了解算法的实现,而且使用各种软件。不了解算法也可以编程,但是想编写出优秀的程序,必须了解算法。 关于迭代和递归,书中给了个例子:给定一个斐波那契数列 0,1,1,2,3,5,8,13,… ,求该数列的第N个数字。 使用递归的例子:对于递归来说,终止条件至关重要,如果没有终止条件,则会陷入“鸡生蛋,蛋生鸡”的无限循环之中…… def fib(n: int) -> int: """斐波那契数列:递归""" # 终止条件 f(1) = 0, f(2) = 1 if n == 1 or n == 2: return n - 1 # 递归调用 f(n) = f(n-1) + f(n-2) res = fib(n - 1) + fib(n - 2) # 返回结果 f(n) return res 使用迭代则比较好理解,从初始条件出发,一直计算到满足终止条件即可。日常中解决问题的思路以迭代居多。 书中给出了迭代和递归的比较图。 迭代与递归特点对比   迭代 递归 实现方式 循环结构 函数调用自身 时间效率 效率通常较高,无函数调用开销 每次函数调用都会产生开销 内存使用 通常使用固定大小的内存空间 累积函数调用可能使用大量的栈帧空间 适用问题 适用于简单循环任务,代码直观、可读性好 适用于子问题分解,如树、图、分治、回溯等,代码结构简洁、清晰 通过对比可以看出,递归在时间效率和内存使用是都劣于迭代,但是迭代处理的问题,通常会在处理前对问题有清晰的路径和方法,算法中使用循环去解决问题。而递归则通常对问题只有收敛的条件,具体解决过程负责或冗长,使用递归不停地对函数自身进行调用,直至解决完问题,对于复杂问题有着优势。  

  • 2025-01-15
  • 回复了主题帖: 这个电源中78L05的上面电阻是什么作用?

    有没有一种可能,右边是一个简单的电阻负载,比如一个LED灯,串上电阻就能正常工作。7805只是设计时用来忽悠的,等生产了只保留个电阻了事。

  • 2025-01-14
  • 回复了主题帖: 读书活动入围名单:《hello算法》

    个人信息无误,确认可以完成阅读分享计划!

  • 2024-12-18
  • 回复了主题帖: 泰坦触觉 TITAN Core开发套件的示例工程代码给大家要来啦

    想玩,可惜机会好少,感觉渺茫!

  • 2024-12-08
  • 回复了主题帖: 【Follow me第二季第3期】EK-RA6M5任务提交

    御坂10032号 发表于 2024-12-8 18:30 这个树莓派有固件吗佬 应该是stm芯片的。

  • 回复了主题帖: 【Follow me第二季第3期】EK-RA6M5任务提交

    御坂10032号 发表于 2024-12-8 18:30 这个树莓派有固件吗佬 没有,按示波器购买的,到手就是这样,不过据说开源,没去找过源码。这个小东西叫 梅雀林

  • 2024-11-28
  • 加入了学习《FollowMe 第二季:3 - EK_RA6M5 开发板入门》,观看 EK-RA6M5 开发板入门

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

    本帖最后由 aramy 于 2024-12-3 20:32 编辑 很开心参加“Follow me第二季第3期”活动,这次板子是瑞萨的EK-RA6M5 。这款开发板超级大的。还配了网线、usb转接线和microUSB数据线。       入门任务:搭建环境,下载调试示例程序,Blink,按键 开发软件,我是使用官方的IDE,内核应该是eclipse。参考着老师的视频安装IDE环境,我这里安装的是“setup_fsp_v5_5_0_e2s_v2024-07.exe”。然后下载例程包“ra-fsp-examples-5.6.0.example.1.zip”,导入例程包中的“_quickstart”例程。         点击图标栏里边的“锤子”图标,或者在项目上右键鼠标选择构建,即可编译项目,有一些警告,不用管它。然后通过microUSB线,插到板子的“usb full”口。官方例程中提供了按键和LED的控制。蓝色LED闪烁。左边的按钮控制蓝色LED灯的亮度:10%、50%、90%;右边的按键控制闪烁频率1Hz、5Hz、10Hz。查看例程的源码,可以找到控制LED灯亮度的方法: void gpt_blue_callback(timer_callback_args_t * p_args) { /* Void the unused params */ FSP_PARAMETER_NOT_USED(p_args); 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]; } } }  两个按键使用了中断的处理方法。 /* SW 1 */ /********************************************************************************************************************** * 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) % 3); 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) % 3); 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); } } }      基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试。这里使用两根microUSB数据线连接到开发板。一根线连接到“USB FULL”口,用来烧写调试程序,一根线连接到板子下方的“DEBUG”口,用来通过串口与板子通讯。      依然是使用例程中的测试代码,具体代码在ospi_test.c中实现。       DAC输出。依然使用“_quickstart”例程。 1、添加DAC功能,这里DAC输出使用P014管脚,直接设置会报错,原因是P014管脚已经被ADC0使用了,找到ADC0的设置,取消P014的使用,就可以了。     参考着老师的视频讲解,初始化DAC的使用。     在gpt_blue_callback方法中,添加DAC的调用,这里创建了一个锯齿波。设置一个变量,变量累加。因为“R_DAC_Write”最大输入值为4095.所以将变量自加,当值大于等于4095时就归零。使用示波器观察波形输出。     进阶任务:示例程序中新增命令打印信息。在“menu_main.c ”文件中找到例程的菜单,添加一行自定义菜单。  编写自定义菜单对应方法。 test_fn follow_me(void) { int8_t c = -1; sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home); print_to_console((void*)s_print_buffer); //清屏 sprintf (s_print_buffer, "%s", "Follow me Season 2 Issue 3"); print_to_console((void*)s_print_buffer); while (CONNECTION_ABORT_CRTL != c) { c = input_from_console (); if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c)) { break; } } xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS); return (0); } 然后调试运行,就可以看见自己增加的菜单了。     扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。 这里简单地设计了两个波形:锯齿波、方波。通过DAC输出。使用外接示波器来做观察。模仿着例程设计一个菜单,显示用户可以选择的选项。选择1,显示锯齿波;选择2,显示方波。还有“w”、“r”两个选项,用户选择“w”则将当前显示的波形类型写入flash中。选择“r”则从flash中读取已经保存了的波形类型,并且通过DAC输出。   首先,在例程的基础上添加一个DAC输出波形的方法。通过一个全局变量来判断,输出的波形是锯齿波还是方波。 void DAC_Wave(char wavetype) { static int value=0; if(wavetype==1) R_DAC_Write(&g_dac0_ctrl, value);//锯齿波 if(wavetype==2) R_DAC_Write(&g_dac0_ctrl, value > 2050 ? 4095 : 0);//方波 value=value+20; if(value>=4095) value=0; } 然后启动一个新菜单,通过键盘与用户交互,可以选择熟人波形类型,或者读写flash。这里使用了汉字输出,但在串口终端上实际输出的效果不太好,汉字的最后部分总是显示不全。 test_fn follow_me(void) { int8_t c = -1; uint16_t buffer[1]; sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home); print_to_console ((void*) s_print_buffer); //清屏 sprintf (s_print_buffer, "%s", "波形控制:\r\n1:三角波 \r\n2:方波 \r\nr: 从flash存储读取\r\nw: 写入到flash存储\r\n"); print_to_console ((void*) s_print_buffer); while (CONNECTION_ABORT_CRTL != c) { c = input_from_console (); if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c)) { break; } if (0 != c) { /* Cast, as compiler will assume calc is int */ sprintf (s_print_buffer, "select %c \r\n", c); print_to_console ((void*) s_print_buffer); if ('1' == c) wavetype = 1; //输入1 选择三角波 if ('2' == c) wavetype = 2; //输入2 选择方波 if ('r' == c) //输入r 读取保存的参数 { readFromFlash (buffer); sprintf (s_print_buffer, "read from buf %d \r\n", buffer[0]); print_to_console ((void*) s_print_buffer); // if (buffer[0] == '1' || buffer[0] == '2') wavetype = buffer[0]; } if ('w' == c) //输入w 保存方波类型参数 { buffer[0] = wavetype; saveToFlash (buffer); } } } xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS); return (0); } 最后添加两个函数,用来读写flash。因为需要写入和读取的数据只有一个波形类型的数据,只需要一个整形数据即可。 void saveToFlash(uint16_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; /* Cast to req type */ p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS; // err = R_QSPI_Open(&g_qspi_ctrl, &g_qspi_cfg); // if (FSP_SUCCESS != err) // { // sprintf(s_print_buffer, "Failed to open QSPI module\r\n"); // return; // } /* 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"); } } // err = R_QSPI_Close(&g_qspi_ctrl); // if (FSP_SUCCESS != err) // { // sprintf(s_print_buffer, "Failed to close QSPI module\r\n"); // } /* close QSPI module */ deinit_qspi (current_spi_mode); } void readFromFlash(uint16_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); }         心得体会:非常开心参加Follow me活动,这次活动推出的瑞萨的EK-RA6M5开发板功能超级强悍。但与此同时,掌握开发板的开发方法也相当的困难。好在有老师在视频课中事无巨细地耐心讲解,通过反复观看老师的视频,总算是入门了这块开发板,但是远远没有能发挥出这块开发板的能力,期待着后续看到各位老师优秀的作品。

  • 2024-11-17
  • 加入了学习《FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解》,观看 Adafruit Circuit Playground Express 及任务讲解

  • 2024-11-15
  • 回复了主题帖: 小米的四电机系统的圆规掉头、原地掉头,算法实现上难吗?

    有现成的运动模型。能够单独控制4个轮子旋转方向和转速就可以原地旋转。但是针对非理想环境要如何处理,4个轮子所处的地面摩擦力相差较大时,需要额外增加角速度传感器来进行闭环处理。

  • 加入了学习《鸿蒙 HarmonyOS NEXT星河版零基础入门到实战》,观看 ArkTS-认识和存储数据

  • 2024-11-06
  • 回复了主题帖: 想搞自动驾驶小车,在B站看到一个成本300的,在犹豫中

    nmg 发表于 2024-11-6 15:52 扫地机器人的地图建模应该用的不是激光雷达吧,这个激光雷达是不是挺贵的 海鲜市场整个二手的,很便宜的。小50拿下!

  • 2024-11-05
  • 回复了主题帖: 想搞自动驾驶小车,在B站看到一个成本300的,在犹豫中

    不推荐这个,建议买个大点的车体。扩展性强点。

  • 2024-10-31
  • 回复了主题帖: 【Follow me第二季第3期】 EK-RA6M5 开发前准备工作

    感谢!

  • 2024-10-27
  • 回复了主题帖: 【Follow me第二季第3期】 EK-RA6M5 开发前准备工作

    感谢!感谢!

  • 2024-10-25
  • 回复了主题帖: 【2024 DigiKey创意大赛】赛博竖笛完成

    赞!

  • 2024-10-19
  • 加入了学习《得捷电子专区》,观看 【2024 DigiKey 创意大赛】红外温度检测及火灾报警器

  • 2024-10-18
  • 回复了主题帖: 【2024 DigiKey 创意大赛】用esp32-s3-lcd-ev-board制作华容道拼图游戏

    wangerxian 发表于 2024-10-17 16:29 这游戏有点意思,从零开发的呀? 不是,移植开源的项目!

统计信息

已有73人来访过

  • 芯积分:230
  • 好友:--
  • 主题:33
  • 回复:46

留言

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


现在还没有留言