- 2025-01-12
-
发表了主题帖:
【Follow me第二季第3期】任务提交总贴
基础任务:
【Follow me第二季第3期】+入门任务+软件安装、例程下载 - DigiKey得捷技术专区 - 电子工程世界-论坛
【Follow me第二季第3期】基础任务+quad-spi flash和octo-spi flash配置及读写速度 - DigiKey得捷技术专区 - 电子工程世界-论坛
【Follow me第二季第3期】基础任务+DAC配置生成波形及性能测试 - DigiKey得捷技术专区 - 电子工程世界-论坛
拓展任务
【Follow me第二季第3期】基础任务+DAC配置生成波形及性能测试 - DigiKey得捷技术专区 - 电子工程世界-论坛
进阶任务:
【Follow me第二季第3期】拓展任务-手搓一个信号发生器 - DigiKey得捷技术专区 - 电子工程世界-论坛
全部代码如下:
学习感想:
在工作之余,学到了RA6M5的知识,让自己的知识有减少了一部分的空缺。
-
发表了主题帖:
【Follow me第二季第3期】拓展任务-手搓一个信号发生器
前言拓展任务就是制作一个信号发生器,这里我们在DAC的功能上面进行拓展,同时实现使用按键,操作输出的频率;
一:软件代码配置
如上图所示:配置本次项目中,按键检测功能,所使用到的引脚,DAC输出和存储部分的
二:软件编写流程
1:初始化按键、DAC和存储使用的IO 口
2:配置DAC的输出
3:检测是否有按键按下, 当有按键按下时,执行更改DAC输出功能
三:软件代码如下:
/* TODO: add your own code here */
fsp_err_t err = FSP_SUCCESS;
double w = 0,dac_value = 0;
double freq = 10;
uint8_t dac_freq = 10;
/* Open the DAC channel */
err = R_DAC_Open (&g_dac_ctrl, &g_dac_cfg);
if (FSP_SUCCESS != err)
{
/* DAC module open failed */
APP_PRINT("DAC open falied\r\n");
R_DAC_Close(&g_dac_ctrl);
}
getDACsetferq(flash_value);
if (flash_value[0] != 0)
{
freq = flash_value[0];
}
APP_PRINT("read DAC value is:%d\r\n",dac_freq);
/* handle error */
while (1)
{
//qspi_DAC_input_value = process_input_data();
if( Key_Scan(KEY1_SW2_PIN) == KEY_ON )
{
dac_freq += 10;
freq = dac_freq;
flash_value[0] = freq;
saveDACfreq(flash_value);
APP_PRINT("read DAC value is:%d\r\n",dac_freq);
}
if( Key_Scan(KEY2_SW1_PIN) == KEY_ON )
{
dac_freq -= 10;
if (dac_freq <= 0)
{
dac_freq = 10;
}
flash_value[0] = freq;
saveDACfreq(flash_value);
APP_PRINT("read DAC value is:%d\r\n",dac_freq);
}
w += (PI / freq);
if (w >= (2 * PI))
{
w = 0;
}
dac_value = (sin(w) + 1) / 2 * 4095;
R_DAC_Write(&g_dac_ctrl, (uint16_t)dac_value);
R_DAC_Start(&g_dac_ctrl);
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MICROSECONDS);
}
实物测试如下:
测试视频如下:
[localvideo]46f7c0d40b868b87116c43f3965b4149[/localvideo]
-
发表了主题帖:
【Follow me第二季第3期】进阶任务+示例程序中新增命令打印信息
本帖最后由 聪聪哥哥 于 2025-1-12 22:08 编辑
今天和大家分享一下进阶任务的开发流程-在示例程序中新增命令打印信息。
1:主要使用FSP库进行开发软件,然后使用官方的例程里面的代码。这里就是使用串口的打印功能,这里我增加了一个是串口显示功能,直接在串口工具中进行显示。
一、增加Followme_display_menu函数功能
在 menu_text.c的代码中进行数据显示,增加的代码如下:
/* Table of menu functions */
static st_menu_fn_tbl_t s_menu_items[] =
{
{"Follow me work autor by congcong" , Followme_display_menu},
{"Kit Information" , kis_display_menu},
{"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 }
};
二:Followme_display_menu 文件中增加显示函数
test_fn Followme_display_menu(void)
{
int8_t c = -1;
//uint32_t value = 0;
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);
print_to_console((uint8_t *)"autor by congcong Please enter a number(0~9):");
/* provide small delay so board_status should be up to date */
vTaskDelay (s_ticks_to_wait);
//xEventGroupSetBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);
while (CONNECTION_ABORT_CRTL != c)
{
c = input_from_console ();
if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c))
{
break;
}
else
{
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, "You entered is:%d", c - '0');
print_to_console((void*)s_print_buffer);
print_to_console((uint8_t *)"\r\n\r\n> Press space bar to return to MENU Or Continue entering numbers\r\n");
print_to_console((uint8_t *)"\r\n\r\n> thanks you\r\n");
}
}
//xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);
return (0);
}
二:实物测试图片如下所示:
开机复位后,可以显示 “follow me work autor by congcong”,表示程序运行正常;
2.1 使用串口工具,检测一下串口的发出的数据,如下所示:
在输入框内 输入 数字2 ,可以看到 瑞萨的单片机有返回数据,可以显示当前输入的内容,并且程序可以返回,表示交互功能正常。
输入空格,可以返回到 主界面,功能正常。
学习感悟:使用官方例程进行开发很容易,集成度很高,可以应用到工作中很方便, 给自己工作的带来了更多的乐趣。
实物测试视频如下:
[localvideo]8afdb014dcd89834ec4f69bd8b7417bc[/localvideo]
-
发表了主题帖:
【Follow me第二季第3期】基础任务+DAC配置生成波形及性能测试
和大家分享一下,使用RA6M5的DAC的功生成波形
DAC基本配置过程
在DAC模式配置过程中,需要配置DAC的输出引脚、工作模式、分辨率、输出范围等等,
DAC功能的性能指标:
1:分辨率是模拟输出电压可被分离的等级数,n位DA分辨率一般为1/2^n。位数越高,分辨率越高。
2:转换速度用来描述数字量变化引起模拟量变换的转换时间,具有的指标:建立时间和转换速率。
A/D转换一般步骤:
这里配置的时候,需要结合FSP的图形化配置软件,对底层的驱动代码的开发,很方便。
一:FSP库配置如下:
这里配置P014引脚为DAC0的引脚,并且映射过去,
设置new stack 中g-dac 的软件:配置DAC的 引脚 P014的 引脚属性
程序编写流程如下:
1:初始化IO口,P014 为DAC输出引脚
2:进入主程序编写输出不同电压的数据
3:为了方便调试,这里使用的系统延时的方式进行调节。
4:这里为了方便测试,编写正弦波的产生函数程序:
主程序代码如下:
while (1)
{
w += (PI / 30);
if (w >= (2 * PI))
{
w = 0;
}
dac_value = (sin(w) + 1) / 2 * 4095;
R_DAC_Write(&g_dac_ctrl, (uint16_t)dac_value);
R_DAC_Start(&g_dac_ctrl);
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
}
实际效果测试如下:
测试视频如下:
[localvideo]a3f1ffb373f7498e01d461b59b78c77f[/localvideo]
- 2025-01-10
-
发表了主题帖:
【Follow me第二季第3期】基础任务+quad-spi flash和octo-spi flash配置及读写速度
本帖最后由 聪聪哥哥 于 2025-1-11 10:55 编辑
今天和大家分享一下,基本任务:quad-spi flash和octo-spi flash配置及读写速度测试过程;
前言:通过查看本次活动的开发板RA6M5开发板,我们可以看到该款开发板上面提供了多种外设模块,为了测试不同的SPI模块的性能,搭建了Quand-SPI flash-MX25L25645G和Octo-SPI Flash-MX25LM51245GM两种不同的存储芯片。
依靠着瑞萨提供的FSP(Flexiable Software Package)工具,我们不仅仅可以配置本次任务中所使用的SPI接口引脚部分,也可以通过图形化配置工具,对底层的驱动函数进行自动生成,我们可以在生成底层驱动代码下,开发相对应的功能。
本次任务中所使用的模块资料如下:
1:quad spi 芯片flash-MX25L25645G 2:octo spi芯片: Flash-MX25LM51245GM
一:我们先简单了解一下 quad spi
基本的概念:Quad-SPI是一种串行接口,它通过四条数据线(I0、I1、I2、I3)实现数据的读取、写入和擦除操作。
设计的目的:Quad-SPI设计的主要目的是与支持此接口的闪存芯片进行通信,解决一些应用存储空间不足的问题,尤其是当使用大量多媒体数据时。
传输速度:与传统SPI接口相比,Quad-SPI提供了更高的数据传输速率和更大的带宽。传统SPI通常只有两根数据线(MOSI和MISO),而Quad-SPI则有四根数据线,可以同时传输四路数据,从而大大提升传输速率。
二:quad spi的工作原理:
2.1 双向数据线:Quad-SPI接口的数据线是双向的,可以根据需要动态配置为输入或输出。在数据传输过程中,Quad-SPI接口通过时钟信号控制数据的同步传输。
2.2通讯过程:Quad-SPI的通信过程通常包括指令阶段、地址阶段、交替字节阶段、空指令周期阶段和数据阶段。在指令阶段,Quad-SPI接口发送一个8位指令到闪存芯片,指定要执行的操作类型;在地址阶段,发送1~4字节的地址信息,指示操作的目标位置;交替字节阶段用于发送控制操作模式的字节;空指令周期阶段则用于准备数据线的传输方向;最后,在数据阶段,Quad-SPI接口可以从闪存芯片接收或向其发送任意数量的字节。
2.3 通讯数据效率模式:Quad-SPI支持双倍数据速率模式,即在每个时钟周期的上升沿和下降沿都传输数据,从而实现了数据传输速率的加倍。但需要注意的是,这个功能需要微控制器和闪存芯片都支持才能实现。
三:Quad-SPI的优势和未来的存在的发展的可能性
随着技术的不断发展,Quad-SPI接口的性能和功能也将不断提升。例如,一些最新的Quad-SPI接口支持更高的时钟频率和更大的数据传输量,同时还提供了更多的配置选项和更强大的错误检测与纠正功能。这些改进使得Quad-SPI接口在高性能嵌入式系统中的应用更加广泛和深入。此外,Octo-SPI作为Quad-SPI的升级版,通过增加数据线的数量来进一步提高数据传输速率和带宽,为嵌入式系统提供了更多的选择和可能性。
综上所述,Quad-SPI是一种功能强大、灵活高效的串行接口,它通过四条数据线实现了与外部闪存芯片的高速通信。在嵌入式系统中发挥着至关重要的作用,并随着技术的不断进步而持续发展。
原理图如下所示:
在和大家分享一下octo-spi 的相关知识
基本概念:Octo-SPI是一种高速串行接口技术,它通过使用八条数据线(而不是Quad-SPI的四条)来进一步提高数据传输速率和带宽。这种接口技术适用于需要处理大量数据的现代嵌入式系统,如智能手机、平板电脑、数码相机等消费电子产品。
Octo-SPI的主要特点如下:
1:高效的数据传输:Octo-SPI通过增加数据线的数量,实现了更高的数据传输速率。每个时钟周期可以传输多达8个比特的数据,从而大大提高了通信效率。
2:并行通信:与Quad-SPI类似,Octo-SPI也采用并行通信方式。但由于其数据线数量加倍,因此通信效率更高。
3:向下兼容:Octo-SPI接口通常也支持Single-SPI、Dual-SPI和Quad-SPI模式,这意味着它可以与这些较低版本的SPI接口设备兼容。
4:内存映射模式:在Octo-SPI接口中,外部存储器可以像内部内存一样被访问。这提高了系统的总线主控器(如DMA)在CPU停机的低功耗模式下自动访问外部内存的能力。
5:多种操作模式:Octo-SPI支持多种操作模式,包括直接模式、自动状态转移模式和内存映射模式等。这些模式可以根据具体的应用需求进行选择。
基本工作原理:
Octo-SPI的工作原理与Quad-SPI相似,但数据传输能力更强。它通常包括指令阶段、地址阶段、数据阶段等。在指令阶段,Octo-SPI接口发送一个指令到外部存储器,指定要执行的操作类型。在地址阶段,发送地址信息,指示操作的目标位置。最后,在数据阶段,Octo-SPI接口可以从外部存储器接收或向其发送数据。
基本的配置和使用
在配置和使用Octo-SPI接口时,通常需要进行以下步骤:
1:初始化IO口:首先需要将Octo-SPI接口的硬件引脚和时钟初始化到合适的参数。这包括设置数据线的方向、配置时钟频率等。
2:配置工作模式:根据具体的应用需求,选择合适的Octo-SPI工作模式。这包括设置指令阶段、地址阶段和数据阶段的长度和格式等。
3:执行读写操作:在配置完成后,就可以通过Octo-SPI接口执行读写操作了。这通常涉及到发送指令、地址和数据等步骤,并根据返回的数据进行相应的处理。
综上所述,Octo-SPI是一种高速、高效的串行接口技术,它适用于需要处理大量数据的现代嵌入式系统。通过合理配置和使用Octo-SPI接口,可以大大提高系统的数据传输速率和存储性能。
三:软件编译
软件编写流程如下:
3.1 板载IO口初始化
3.2 USB初始化(用来虚拟串口与PC端通讯)
3.3 LED初始化,用来指示程序工作状态
3.4 初始化定时器等状态
3.5开始任务调度
FSP库配置截图如下:
3.1 OSPI代码写测试写入和读写测试代码
void ospi_performance_test(uint32_t data_size,
uint32_t *ospi_performance_write_result,
uint32_t *ospi_performance_read_result)
{
fsp_err_t err;
uint32_t i = 1;
if (R_CGC_Open (g_cgc.p_ctrl, g_cgc.p_cfg) != FSP_SUCCESS)
{
__asm("bkpt");
}
while (i)
{
err = R_OSPI_Open(g_ospi.p_ctrl, g_ospi.p_cfg);
if (FSP_SUCCESS != err)
{
__asm("bkpt");
}
#if HIGH_SPEED_MODE
configure_dopi_ospi();
ospi_test_wait_until_wip();
#endif
*ospi_performance_write_result = write_dopi_ospi(data_size);
ospi_test_wait_until_wip();
*ospi_performance_read_result = read_dopi_ospi(data_size);
ospi_test_wait_until_wip();
erase_dopi_ospi();
ospi_test_wait_until_wip();
#if HIGH_SPEED_MODE
configure_spi_ospi();
ospi_test_wait_until_wip();
#endif
err = R_OSPI_Close(g_ospi.p_ctrl);
if (FSP_SUCCESS != err)
{
__asm("bkpt");
}
i--;
}
}
3.2 写入数据代码如下
static uint32_t write_dopi_ospi(uint32_t data_size)
{
fsp_err_t err;
uint32_t test_var;
/* Cast to req type */
uint8_t * p_dest = (uint8_t *)OSPI_DMA_ADDRESS;
timer_status_t status = {};
uint32_t number_of_pages;
R_GPT_Open(g_memory_performance.p_ctrl, g_memory_performance.p_cfg);
/* Cast, as compiler will assume result of calc to be int */
number_of_pages = (uint32_t)(data_size * (1024 / OSPI_TEST_PAGE_SIZE));
/* Write 32 blocks worth of data starting at Block 0
* Block size = 64K, i.e. 2 blocks = 128K of data
* check this comment....... */
for (test_var = 0; test_var < number_of_pages; test_var++ )
{
/* Performance measured around this loop will be slightly lower due to branches and test write-in-progress
* The actual throughput should be measured with direct debugger downloads (not supported by SEGGER yet)*/
R_GPT_Start(g_memory_performance.p_ctrl);
err = R_OSPI_Write(g_ospi.p_ctrl, s_page, p_dest, OSPI_TEST_PAGE_SIZE);
if (FSP_SUCCESS != err)
{
__asm("bkpt");
}
ospi_test_wait_until_wip();
p_dest += OSPI_TEST_PAGE_SIZE;
R_GPT_Stop(g_memory_performance.p_ctrl);
vTaskDelay(1U);
}
R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
R_GPT_Reset(g_memory_performance.p_ctrl);
R_GPT_Close(g_memory_performance.p_ctrl);
return (status.counter);
}
测试图片如下所示:
代码运行图片如下所示:
使用串口工具对开发板输出信息进行监控,监控界面如下所示:
输入数字:4 对 SPI写入和读写数据的速度进行测试。
按下:64后,可以看到测试结果如下所示:
实物测试图如下所示:
-
加入了学习《【Follow me第二季第3期】》,观看 【Follow me第二季第3期】入门任务
- 2024-12-15
-
发表了主题帖:
【Follow me第二季第3期】+入门任务+软件安装、例程下载
本帖最后由 聪聪哥哥 于 2024-12-15 15:20 编辑
自己非常的荣幸参加电子工程世界联合得捷举办的Follow me活动的,利用自己的工作之余,对瑞萨的开发板有了一定的了解,主要是感谢该平台,让自己的工作之余变得很充实!
购买的实物图片:
入门任务
一:开发环境 E2S的下载
之前对瑞萨的开发板编程的时候基本上是使用keil的编程工具,对软件进行开发,对e2s使用的比较少,所以借助本次的开发机会,对e2s软件进行一次系统的了解和学习。
我这边使用的版本是5.6.0版本,下载网址如下:https://github.com/renesas/fsp/releases
我们在下载的时候,需要注意e2s软件更新的速度有点快,我记得当时下载软件安装包时候,还没有5.7.0版本,当时官方刚刚公布了最新的版本,对于软件更新问题,我们使用最新的芯片时候还是要对软件进行重新安装,要不使用的时候可能会遇到问题。
下载完成后,只需要一步安装即可,安装过程如下:
首先是对e2S软件进行安装,软件解压过程,解压过程有些慢,大家只需要耐心的等待就好了;
根据自己的需要,对软件的安装位置进行设置,如果电脑上面的C盘空间,足够大时候,就可以快速安装,在安装的过程中,需要注意设置 软件的语言版本,软件的工具链(如果没有选择也没有关系,安装完成后,可以在瑞萨的软件中进行再次安装),基本上是属于一键安装的过程,这里就不做过多的介绍了。
二:软件支持包的安装
我们安装在安装好软件的之后,对于官方的提供的例程需要自行安装,安装过程也是一键安装,这里不做过多的介绍了。
如上图所示:为官方的库文件,解压之后,官方的提供的库文件比较大,对于没有用到的芯片的例程包,大家可以自行删除。
三:例程的编译
3.1 e2s软件打开界面如下:
导入方法如下:【文件】-【从文件系统中打开工程】-【目录中选择测试例程】(导入过程图片如下所示)
需要等待编译软件导入完成,才可以对编程软件进行操作:编译成功界面及构建、调试按键如图所示:
配置一下调试方式:
进入调试界面如下所示:
四:按键控制LED的闪烁亮度和闪烁频率
部分代码如下:
static fsp_err_t gpt_initialize(void)
{
fsp_err_t fsp_err = FSP_SUCCESS;
for (uint32_t i = 0; i < 1; i++ )
{
fsp_err = R_GPT_Open (s_pwm_pins[i].p_timer->p_ctrl, s_pwm_pins[i].p_timer->p_cfg);
if (FSP_SUCCESS != fsp_err)
{
return fsp_err;
}
}
fsp_err = R_GPT_Open (g_blinker.p_ctrl, g_blinker.p_cfg);
{
if (FSP_SUCCESS != fsp_err)
{
return fsp_err;
}
}
fsp_err = R_GPT_Open (g_gpt_blue.p_ctrl, g_gpt_blue.p_cfg);
if (fsp_err)
{
SYSTEM_ERROR
return fsp_err;
}
fsp_err = R_GPT_Start (g_blinker.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
/* Close the GPT timer */
R_GPT_Close (g_blinker.p_ctrl);
return fsp_err;
}
return fsp_err;
}
fsp_err_t common_init(void)
{
fsp_err_t fsp_err = FSP_SUCCESS;
fsp_err = adc_initialize ();
if (FSP_SUCCESS != fsp_err)
{
return fsp_err;
}
fsp_err = icu_initialize ();
if (FSP_SUCCESS != fsp_err)
{
return fsp_err;
}
fsp_err = gpt_initialize ();
#if 1
if (FSP_SUCCESS != fsp_err)
{
return fsp_err;
}
led_duty_cycle_update ();
#endif
/* Set baseline LED status */
g_board_status.led_intensity = 0;
g_board_status.led_frequency = 0;
R_GPT_PeriodSet(g_blinker.p_ctrl, g_pwm_rates[g_board_status.led_frequency]);
led_duty_cycle_update ();
s_duty = g_pwm_dcs[g_board_status.led_intensity];
/* Start the timers */
R_GPT_Start(g_blinker.p_ctrl);
R_GPT_Start(g_gpt_blue.p_ctrl);
return fsp_err;
}
/**********************************************************************************************************************
End of function common_init
*********************************************************************************************************************/
/**********************************************************************************************************************
* Function Name: led_duty_cycle_update
* Description : .
* Return Value : .
*********************************************************************************************************************/
void led_duty_cycle_update(void)
{
R_GPT_DutyCycleSet (s_pwm_pins[0].p_timer->p_ctrl, g_pwm_dcs[g_board_status.led_intensity], s_pwm_pins[0].pin);
s_duty = g_pwm_dcs[g_board_status.led_intensity];
}
/**********************************************************************************************************************
End of function led_duty_cycle_update
*********************************************************************************************************************/
/*
* Defined to select whether this project will
* a. PWM the LED by direct connection to a GPT compare output pin,
* where the board is tracked to support this.
* b. The GPT compare to raise an interrupt. Then the LED is toggled in SW within the interrupt handler
* (gpt_blue_callback). For where the LED is not directly tracked to the GPT compare output pin.
*/
#ifdef USE_SW_TIMER
/**********************************************************************************************************************
* Function Name: periodic_timer_callback
* Description : Callback function for driver g_periodic_timer.
* Argument : p_args
* Return Value : .
*********************************************************************************************************************/
void gpt_blinker_callback(timer_callback_args_t *p_args)
{
/* Void the unused params */
FSP_PARAMETER_NOT_USED(p_args);
if (OFF == s_blueled_flashing)
{
s_blueled_flashing = ON;
}
else
{
s_blueled_flashing = OFF;
}
}
/**********************************************************************************************************************
End of function periodic_timer_callback
*********************************************************************************************************************/
/**********************************************************************************************************************
* Function Name: gpt_blue_callback
* Description : Callback function for driver g_gpt_blue.
* Argument : p_args
* Return Value : .
*********************************************************************************************************************/
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];
}
}
}
烧录代码例程,完成搭建环境,下载调试示例程序,Blink,按键的基本任务操作。
视频演示如下:
[localvideo]8c728f6dfaad83500467988d01cdf127[/localvideo]
- 2024-12-13
-
加入了学习《【Follow me第二季第3期】所有任务汇总》,观看 【Follow me第二季第3期】所有任务汇总
- 2024-10-28
-
加入了学习《Follow me第二季第1期》,观看 完整版
-
加入了学习《Follow me第二季第1期》,观看 基础任务三(必做):接近检测
-
加入了学习《Follow me第二季第1期》,观看 基础任务二(必做):监测环境温度和光线
-
加入了学习《Follow me第二季第1期》,观看 入门任务(必做):开发环境搭建,板载LED点亮 基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
-
加入了学习《Follow me第二季第1期》,观看 器材介绍
- 2024-10-20
-
加入了学习《【Follow me第二季第1期】全部任务演示》,观看 全部任务演示2.0
- 2024-09-08
-
发表了主题帖:
【Follow me第二季第1期】汇总提交帖:全部任务视频及其代码下载
首先很荣幸参加follow me 第二季第一期的活动,在学习、工作之余有精力和时间去接触Adafruit Circuit Playground Express 这款开发板,下面我和大家分享一下开发过程。
全部视频演示视频:
完整版
物料展示:
本次活动中,我购买了Circuit Playground Express主板和陀机两种物料
购买实物图片展示:
任务成果展示
入门任务:01 Ardunio ide环境搭建+ 物料展示 +板载LED点亮
相对应的帖子地址:https://bbs.eeworld.com.cn/thread-1293111-1-1.html
软件环境搭建:
这次我所使用的编译软件为arduino 来实现功能。
官方下载网址:https://www.arduino.cc/en/software
软件属于一键安装的过程:
安装完成后,打开IDE,在左侧栏的Boards Manager,安装Arduino SAMD.连接开发板,就能看见上面正确显示了板子的型号
任务:点亮板载的LED灯
简单利用arduino实现闪烁板载的LED灯功能,查看官方的原理图我们可以看到D13连接到引脚是13,
软件流程图:
软件操作代码如下:
void setup() {
// put your setup code here, to run once:
pinMode(13, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(13, 1);
delay(1000);
digitalWrite(13, 0);
delay(1000);
}
编译之后软件效果图:
测试实物图片:
可以通过修改延时函数中的时间,改变LED的闪烁间隔
基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
对应帖子的连接:https://bbs.eeworld.com.cn/thread-1293113-1-1.html
该任务比较简单,使用这个用Adafruit_NeoPixel.h这个库就能实现,设置了七种不同的颜色进行循环切换,
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#define PIN 8
#define NNUMPIN 10
Adafruit_NeoPixel pixels(NNUMPIN, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
pixels.begin();
}
void loop() {
// write your code here
static uint8_t led_num = 0;
//static uint32_t colors[8] = {0x040304, 0x000505, 0x050005, 0x050500, 0x050005, 0x000A00, 0x0A0000,0x0A000A};
static uint32_t colors[7] = {0x0A0000, 0x000A00, 0x00000A, 0x050500, 0x050005, 0x000505, 0x040304};
//static uint32_t colors[8] = {0x011011, 0x22022, 0x033033, 0x44044, 0x055055, 0x66066, 0x77777,0x088088};
static uint8_t color_num = 0;
static Adafruit_NeoPixel pixels(NNUMPIN, PIN, NEO_GRB + NEO_KHZ800);
pixels.clear();
pixels.setPixelColor(led_num, colors[color_num]);
pixels.show();
led_num++;
if (led_num == NNUMPIN) {
led_num = 0;
color_num++;
if (color_num == 8)
color_num = 0;
}
delay(200);
}
基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
对应帖子的连接:https://bbs.eeworld.com.cn/thread-1293113-1-1.html
参考官方发布的原理图和CircuitPython库的代码可以得出引脚电压(A8)与温度、光照(A9)之间的关系。
软件的流程图如下:
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "SensorAB.h"
#define PIN 8
#define NUMPIXELS 10
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
Serial.begin(115200);
pixels.begin();
}
void loop() {
// write your code here
const double temperature = get_temperature(A9);
const double photocell = get_photocell(A8);
pixels.clear();
if (temperature < 14) {
pixels.setPixelColor(5, 0, 0, 10);
} else if (temperature < 18 && temperature >= 14) {
pixels.setPixelColor(6, 0, 5, 5);
} else if (temperature >= 18 && temperature <= 20) {
pixels.setPixelColor(7, 0, 10, 0);
} else if (temperature > 20 && temperature <= 25) {
pixels.setPixelColor(8, 5, 5, 0);
} else if (temperature > 25) {
pixels.setPixelColor(9, 10, 0, 0);
}
if (photocell > 1000) {
pixels.setPixelColor(0, 10, 0, 0);
} else if (photocell > 500 && photocell <= 1000) {
pixels.setPixelColor(1, 5, 5, 0);
} else if (photocell >= 200 && photocell <= 500) {
pixels.setPixelColor(2, 0, 10, 0);
} else if (photocell >= 50 && photocell < 200) {
pixels.setPixelColor(3, 0, 5, 5);
} else if (photocell < 50) {
pixels.setPixelColor(4, 0, 0, 10);
}
pixels.show();
Serial.print("temperature:" + String(temperature) + " sheshidu " + "photocell:" + String(photocell) + " lux\n");
delay(1000);
}
软件仿真之后效果图:
实物图片如下:
基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
对应帖子的连接:https://bbs.eeworld.com.cn/thread-1293113-1-1.html
使用红外传感器,,通过IR LED发射一定频率的脉冲,通过读取接收器测得的模拟值,当模拟值增大即有物体靠近。
试验现象:没有物体接近时灯珠全灭或显示一个,随着物体接近灯珠会亮的越来越多。
软件代码如下:
#include <Adafruit_CircuitPlayground.h>
#define SAFE_DISTANCE 500 // 定义安全距离
const int alertTone = 500; // 警报音调
const int irTransmitterPin = 25; //引脚定义
const int irReceiverPin = A10;
void setup()
{
CircuitPlayground.begin();
Serial.begin(9600); //
pinMode(irReceiverPin, INPUT); // 红外传感器输入
pinMode(irTransmitterPin, OUTPUT);// 红外led输出
delay(100);
}
void loop() {
sendIRPulse();
int distance = analogRead(irReceiverPin); // 读取红外传感器的值
displayDistance(distance);
checkForIntrusion(distance);
delay(300);
}
void displayDistance(int distance) {
int ledCount = map(distance, 290, SAFE_DISTANCE, 1, 10); // 将距离值映射到0-10的LED数量
Serial.print("Distance: ");
Serial.print(distance);
Serial.print(", LED Count: ");
Serial.println(ledCount);
for (int i = 0; i < 10; i++) {
if (i < ledCount) {
CircuitPlayground.setPixelColor(i, 0, 255, 0);
} else {
CircuitPlayground.setPixelColor(i, 0);
}
}
}
void checkForIntrusion(int distance) {
if (distance > SAFE_DISTANCE) {
Serial.println("Intrusion detected!");
playAlertTone();
}
}
void sendIRPulse() {
for (int i = 0; i < 32; i++) {
digitalWrite(irTransmitterPin, HIGH);
delayMicroseconds(13);
digitalWrite(irTransmitterPin, LOW);
delayMicroseconds(13);
}
}
void playAlertTone() {
CircuitPlayground.playTone(alertTone, 500); // 播放警报音500ms
}
进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
对应帖子链接:https://bbs.eeworld.com.cn/thread-1293114-1-1.html
这个任务本质上就是用板载陀螺仪检测板子的姿态,然后给出对应的灯光效果。我实现的是根据板子的倾斜方向亮起对应的灯,
软件流程图:
代码如下:
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "Acc.h"
#define PIN 8
#define NUMPIXELS 10
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
Serial.begin(115200);
pixels.begin();
if (!init_acceleration()) {
Serial.println("ERROR");
}
}
void loop() {
// write your code here
std::array<double, 2> data = get_acceleration();
double length = sqrt(pow(data[0], 2) + pow(data[1], 2));
int degree = atan(-1 * data[0] / data[1]) / M_PI * 180;
degree += data[0] * data[1] >= 0 ? 180 : 0;
pixels.clear();
if (degree >= 15 && degree <= 165) {
pixels.setPixelColor((degree-15)/30+(data[0]<0?5:0), length*10, abs(10-length*10), 0);
}
pixels.show();
Serial.println("X:" + String(data[0]));
Serial.println("Y:" + String(data[1]));
Serial.println("degree" + String(degree));
Serial.println();
delay(100);
}
项目总结:
自己对这次活动做一个简单的总结,在本次活动中,我使用Arduino IDE的编译软件对Adafruit Circuit Playground 板载上面的资源做了简单的了解。经过对活动任务的学习,通过实现不同功能模块的了解,查询资料,深入对该开发板进行多种多种的学习,自己动手写代码,知道开发板的强大,
对于硬件方面来说,自己动手去制作一些DIY产品,依靠现有的资源对电路板进行开发,在工作之余、学习的同时,给自己的生活带来一些乐趣。
最后感谢EEworld与得捷电子举办的活动,希望自己以后有机会参与更多的学习。
代码如下:
-
发表了主题帖:
【Follow me第二季第1期】03 进阶任务制作不倒翁
本帖最后由 聪聪哥哥 于 2024-9-8 23:23 编辑
这个任务本质上就是用板载陀螺仪检测板子的姿态,然后给出对应的灯光效果。我实现的是根据板子的倾斜方向亮起对应的灯,
系统框图:
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "Acc.h"
#define PIN 8
#define NUMPIXELS 10
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
Serial.begin(115200);
pixels.begin();
if (!init_acceleration()) {
Serial.println("ERROR");
}
}
void loop() {
// write your code here
std::array<double, 2> data = get_acceleration();
double length = sqrt(pow(data[0], 2) + pow(data[1], 2));
int degree = atan(-1 * data[0] / data[1]) / M_PI * 180;
degree += data[0] * data[1] >= 0 ? 180 : 0;
pixels.clear();
if (degree >= 15 && degree <= 165) {
pixels.setPixelColor((degree-15)/30+(data[0]<0?5:0), length*10, abs(10-length*10), 0);
}
pixels.show();
Serial.println("X:" + String(data[0]));
Serial.println("Y:" + String(data[1]));
Serial.println("degree" + String(degree));
Serial.println();
delay(100);
}
#include "Acc.h"
#define LISADDR 0x19
bool init_acceleration() {
Wire1.begin();
delay(1000);
Wire1.beginTransmission(LISADDR);
Wire1.write(0x0f);
Wire1.endTransmission();
Wire1.requestFrom(LISADDR, 1);
if (0x33 != Wire1.read()) {
return false;
}
Wire1.beginTransmission(LISADDR);
Wire1.write(0x24);
Wire1.write(0x80);
Wire1.endTransmission();
delay(1000);
Wire1.beginTransmission(LISADDR);
Wire1.write(0x20);
Wire1.write(0x23);
Wire1.endTransmission();
Wire1.beginTransmission(LISADDR);
Wire1.write(0x23);
Wire1.write(0x88);
Wire1.endTransmission();
return true;
}
std::array<double, 2> get_acceleration() {
std::array<double, 2> data;
Wire1.beginTransmission(LISADDR);
Wire1.write(0x28 | 0x80);
Wire1.endTransmission();
Wire1.requestFrom(LISADDR, 4);
for (int tmp = 0; tmp < 3; tmp++) {
data[tmp] = static_cast<int16_t>(Wire1.read() | Wire1.read() << 8) / 16;
data[tmp] /= 1000.0;
}
return data;
}
#ifndef ACCELERATION_H
#define ACCELERATION_H
#include <Arduino.h>
#include <array>
#include <Wire.h>
bool init_acceleration();
std::array<double,2> get_acceleration();
#endif
[localvideo]7eb7ea388d2728ab912bb5b86bd88322[/localvideo]
-
发表了主题帖:
【Follow me第二季第1期】02 控制板载炫彩LED,跑马灯点亮和颜色变换
本帖最后由 聪聪哥哥 于 2024-9-8 23:27 编辑
基础任务1:控制板载炫彩LED,跑马灯点亮和颜色变换
该任务比较简单,使用这个用Adafruit_NeoPixel.h这个库就能实现,设置了七种不同的颜色进行循环切换,
程序流程图
代码如下:
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#define PIN 8
#define NNUMPIN 10
Adafruit_NeoPixel pixels(NNUMPIN, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
pixels.begin();
}
void loop() {
// write your code here
static uint8_t led_num = 0;
//static uint32_t colors[8] = {0x040304, 0x000505, 0x050005, 0x050500, 0x050005, 0x000A00, 0x0A0000,0x0A000A};
static uint32_t colors[7] = {0x0A0000, 0x000A00, 0x00000A, 0x050500, 0x050005, 0x000505, 0x040304};
//static uint32_t colors[8] = {0x011011, 0x22022, 0x033033, 0x44044, 0x055055, 0x66066, 0x77777,0x088088};
static uint8_t color_num = 0;
static Adafruit_NeoPixel pixels(NNUMPIN, PIN, NEO_GRB + NEO_KHZ800);
pixels.clear();
pixels.setPixelColor(led_num, colors[color_num]);
pixels.show();
led_num++;
if (led_num == NNUMPIN) {
led_num = 0;
color_num++;
if (color_num == 8)
color_num = 0;
}
delay(200);
}
[localvideo]65156387bafbd9e6b29cbf6a3e48d07c[/localvideo]
[localvideo]bed5dccd8ad56cc0cc0550c5e002d435[/localvideo]
基础任务2:监测环境温度和光线,通过板载LED展示舒适程度
参考官方发布的原理图和CircuitPython库的代码可以得出引脚电压(A8)与温度、光照(A9)之间的关系。
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "SensorAB.h"
#define PIN 8
#define NUMPIXELS 10
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// write your initialization code here
Serial.begin(115200);
pixels.begin();
}
void loop() {
// write your code here
const double temperature = get_temperature(A9);
const double photocell = get_photocell(A8);
pixels.clear();
if (temperature < 14) {
pixels.setPixelColor(5, 0, 0, 10);
} else if (temperature < 18 && temperature >= 14) {
pixels.setPixelColor(6, 0, 5, 5);
} else if (temperature >= 18 && temperature <= 20) {
pixels.setPixelColor(7, 0, 10, 0);
} else if (temperature > 20 && temperature <= 25) {
pixels.setPixelColor(8, 5, 5, 0);
} else if (temperature > 25) {
pixels.setPixelColor(9, 10, 0, 0);
}
if (photocell > 1000) {
pixels.setPixelColor(0, 10, 0, 0);
} else if (photocell > 500 && photocell <= 1000) {
pixels.setPixelColor(1, 5, 5, 0);
} else if (photocell >= 200 && photocell <= 500) {
pixels.setPixelColor(2, 0, 10, 0);
} else if (photocell >= 50 && photocell < 200) {
pixels.setPixelColor(3, 0, 5, 5);
} else if (photocell < 50) {
pixels.setPixelColor(4, 0, 0, 10);
}
pixels.show();
Serial.print("temperature:" + String(temperature) + " sheshidu " + "photocell:" + String(photocell) + " lux\n");
delay(1000);
}
#include "SensorAB.h"
double get_temperature(const uint32_t pin) {
return 1.0/(log(1023.0/analogRead(pin)-1)/3950.0+1.0/(273.15+25))-273.15;
}
double get_photocell(const uint32_t pin) {
return analogRead(pin)*3.3/1023.0/2.9*3446;
}
#ifndef SENSOR_H
#define SENSOR_H
#include <Arduino.h>
#define R_T2 10000
#define B 3380000
#define T2 25
double get_temperature(uint32_t pin);
double get_photocell(uint32_t pin);
#endif //SENSOR_H
[localvideo]ac764251aabab3423e84d293595ba0a9[/localvideo]
[localvideo]2b8440a76885e8677f64e2fa54efaf63[/localvideo]
基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
使用红外传感器,,通过IR LED发射一定频率的脉冲,通过读取接收器测得的模拟值,当模拟值增大即有物体靠近。
试验现象:没有物体接近时灯珠全灭或显示一个,随着物体接近灯珠会亮的越来越多。
#include <Adafruit_CircuitPlayground.h>
#define SAFE_DISTANCE 500 // 定义安全距离
const int alertTone = 500; // 警报音调
const int irTransmitterPin = 25; //引脚定义
const int irReceiverPin = A10;
void setup()
{
CircuitPlayground.begin();
Serial.begin(9600); //
pinMode(irReceiverPin, INPUT); // 红外传感器输入
pinMode(irTransmitterPin, OUTPUT);// 红外led输出
delay(100);
}
void loop() {
sendIRPulse();
int distance = analogRead(irReceiverPin); // 读取红外传感器的值
displayDistance(distance);
checkForIntrusion(distance);
delay(300);
}
void displayDistance(int distance) {
int ledCount = map(distance, 290, SAFE_DISTANCE, 1, 10); // 将距离值映射到0-10的LED数量
Serial.print("Distance: ");
Serial.print(distance);
Serial.print(", LED Count: ");
Serial.println(ledCount);
for (int i = 0; i < 10; i++) {
if (i < ledCount) {
CircuitPlayground.setPixelColor(i, 0, 255, 0);
} else {
CircuitPlayground.setPixelColor(i, 0);
}
}
}
void checkForIntrusion(int distance) {
if (distance > SAFE_DISTANCE) {
Serial.println("Intrusion detected!");
playAlertTone();
}
}
void sendIRPulse() {
for (int i = 0; i < 32; i++) {
digitalWrite(irTransmitterPin, HIGH);
delayMicroseconds(13);
digitalWrite(irTransmitterPin, LOW);
delayMicroseconds(13);
}
}
void playAlertTone() {
CircuitPlayground.playTone(alertTone, 500); // 播放警报音500ms
}
[localvideo]2accfeb41009f36efd04efb84d2c64b3[/localvideo]
-
发表了主题帖:
【Follow me第二季第1期】01 Ardunio ide环境搭建+ 物料展示 +板载LED点亮
本帖最后由 聪聪哥哥 于 2024-9-8 23:24 编辑
【Follow me第二季第1期】01 Ardunio ide环境搭建+ 物料展示 +板载LED点亮
首先很荣幸参加follow me 第二季第一期的活动,在学习、工作之余有精力和时间去接触Adafruit Circuit Playground Express 这款开发板,下面我和大家分享一下开发过程。
首先看一下官方给出的开发板介绍图:
Circuit Playground Express基于ATSAMD21微控制器,采用32位ARM® Cortex®-M0+内核。ATSAMD21采用先进的电源管理技术,电流消耗极低。它可以由USB、“AAA”电池组或Lipoly电池供电。传感器封装圆形Circuit Playground Express板的边缘具有鳄鱼夹焊盘,便于连接到项目而无需焊接。可通过内置USB快速连接进行编程,无需专用电缆或适配器。
可以看到该款开发板的功能时很强大的,板载了诸多的传感器和外设,圆形的设计也很友好,放在手掌上正好。
本次活动中,我购买了Circuit Playground Express主板和陀机两种物料
实物展示:
软件环境搭建:
我所使用的开发软件时arduino 来实现功能。
官方下载网址:https://www.arduino.cc/en/software
软件属于一键安装的过程,这里就不再过多的介绍
简单利用arduino实现闪烁板载的LED灯功能,查看官方的原理图我们可以看到D13连接到引脚是13,
软件流程图如下:
程序代码如下:
void setup() {
// put your setup code here, to run once:
pinMode(13, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(13, 1);
delay(100);
digitalWrite(13, 0);
delay(100);
}
编译之后:
实物图片如下:
我们可以修改delay函数中的延时时间,来观察闪烁的效果。
[localvideo]c9ceaf4e8855296c1a396fa06a40632c[/localvideo]
-
加入了学习《Follow me第二季第1期》,观看 创意任务二:章鱼哥
- 2024-08-28
-
加入了学习《【Follow me第二季第1期】简单方法实现(任务提交)》,观看 【Follow me第二季第1期】简单方法实现(任务提交)(接近检测视频补充)