- 2024-12-18
-
回复了主题帖:
2025年测评中心,DigiKey得捷赞助继续,欢迎跟帖推你期待的上线的测品啦~
okhxyyo 发表于 2024-12-18 09:55
好~~那等咱N6上线吧
可以搞一些ADI的传感器来做一些活动,单片机玩来玩去就那些。
-
发表了主题帖:
《深度学习的数学——使用Python语言》7、连续型概率分布
前面学习了离散型概率分布,今天开始学习连续型概率分布。
连续型概率变量分布相比离散型,会更加难离解,作者阐述了他为什么先讲离散型概率分布再讲连续型的概率分布的概念。
连续型概率,因为有无穷多个点,这意味着每个点被选中的概率趋于0,因此,只能讨论在给定区间上取值的概率。
最常见的连续型概率分布是区【0,1】上的均匀分布,我们可以讨论在给定区间如[0,0.25]上取值的概率。
书中给出了几种常见的继续型概率分布的曲线:伽马分布,正态分布,贝塔分布,以及均匀分布。
要得到基一区间的概率,就需要在该区间上对分布曲线下方的区域进行累加,这本质上就是求积分,而积分,其实就是求和。
书得讲述了几种分布的形状以及概率密度函数。
【读后感】
感觉读这本书还是需要有很深地数据基础的,要不然看得云里雾里。
-
回复了主题帖:
Raspberry Pi 500 已经发布了
莫得散热器,要是我目前拿到Pi 5的话,散热还是必不可少的。
-
回复了主题帖:
2025年测评中心,DigiKey得捷赞助继续,欢迎跟帖推你期待的上线的测品啦~
okhxyyo 发表于 2024-12-17 12:03
列出来了呀,作为在看的厂商。可以说说你对哪些板子感兴趣,推荐哪些板子上线,给列列具体型号啊
就是现在新出的STM32N6没有接触了,其他的好象都是用过了,没得什么新意。
- 2024-12-17
-
回复了主题帖:
最能打国产芯榜:沁恒冒泡,推荐他家的带高速USB收发器、NFC的蓝牙soc CH585
我看了,开发板也不贵,可以试一试,有空买个回来出些作品。
-
回复了主题帖:
最能打国产芯榜:沁恒冒泡,推荐他家的带高速USB收发器、NFC的蓝牙soc CH585
沁恒的确在国产芯片里是做得非常好的,他家的产品在常见的电器上用得非常多。希望能做出比NXP等还优秀的产品。
- 2024-12-16
-
回复了主题帖:
2025年测评中心,DigiKey得捷赞助继续,欢迎跟帖推你期待的上线的测品啦~
ST他的产品线丰富,教程也丰富,价格还可以,可以做为首选。
NXP近年来也在国内有大动作,今年也出了好几款MCU,可以做为备选。
-
发表了主题帖:
《深度学习的数学——使用Python语言》7、FLDR 算法
Saad等人最提出了速摇铅骰子(Fast Loaded Dice Roller FLDR),它可以用权重生成整数。
FLDR长法允许指定任意离散分布并对礤进行采样。FLDR算法是用Python实现的,可从GitHub网站上免费获取。需要下载fldr.py和fldrf.py
文章出给出用不同算法的采样曲线:
- 2024-12-15
-
加入了学习《Follow me第二季第3期 视频介绍》,观看 Follow me第二季第3期 任务提交
-
回复了主题帖:
【Follow me第二季第3期】作品提交
Jacktang 发表于 2024-12-15 09:54
视频录制讲解的很详细,路过的朋友可以收藏视频
感谢大佬的关注呀,从头理清了一遍,不过感觉还有很多需要修改的地方。
- 2024-12-14
-
回复了主题帖:
【沁恒RISC-V内核 CH582】SPI 驱动ST7735
popzone 发表于 2024-12-14 14:48
厉害了,顶一个
多谢大佬的关注,这个板子挺好的,性价比高,有空可以关注一下。
-
发表了主题帖:
【Follow me第二季第3期】作品提交
本帖最后由 lugl4313820 于 2024-12-14 17:53 编辑
【前言】
感谢EEWORLD以及得捷电子组织这么好的活动,我也能荣幸的成为活动的一员。通过老师的细心教学,以及各位小伙伴位的无私分享了自己的代码,我经过两个月的学习,终于完成了所有的任务。下面我将逐一介绍我所完成的各项任务。
【经验分享】
1、【Follow me第二季第3期】基础任务 - DigiKey得捷技术专区 - 电子工程世界-论坛
2、【Follow me第二季第3期】基础任务quad-spi 和octo-spi flash对比速度测试 - DigiKey得捷技术专区 - 电子工程世界-论坛
3、【Follow me第二季第3期】DAC波形生成 - DigiKey得捷技术专区 - 电子工程世界-论坛
4、【Follow me第二季第3期】 [扩展任务] DAC输出不同波形,FLASH保存和读取历史数据 - DigiKey得捷技术专区 - 电子工程世界-论坛
【作品介绍】
1、环境创建
我使用的瑞萨的e2studio工具来创建,直接导入他的示你工程就行了。
编译:点击工程中的编译工具就行:
2、下载调试:
在下载调试之前要先按如下进行配置,需要选指定的工程,然后点调试就可以下载工程与调试:
【注】下载调式需要使用usb线插到调试接口:
3、blink与按键
首先我们要知道板载的LED与按键的对应的IO,在原理图上有介绍:
并且在工程的bsp_pin.h中也有标明:
然后在blink任务中使用非阻塞式来写入按键实现REDLED翻转的代码:
/* TODO: add your own code here */
while (1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &p_port_value_port_004);
if(!p_port_value_port_004)
{
sw_flage ++;
if(sw_flage > 10) //如果计数达到10次,测表明已经按下,此处为消抖算法
{
//先读取LED灯的值,然后取反,实现翻转效果
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, &p_port_value_red_led);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, !p_port_value_red_led);
}
}
else
{
sw_flage = 0;
}
vTaskDelay (1);
}
4、添加命令打印
首先在menu_man.c的菜单数组中添加一行,一个为菜单,一个为回调函数
/* Table of menu functions */
static st_menu_fn_tbl_t s_menu_items[] =
{
{"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},
{"DAC TEST" ,dac_display_menu}, //添加ADC选项
{"Next Steps", ns_display_menu },
{"", NULL }
};
然后创建DAC实现函数
菜单标题以及菜单命令列表:
#define MODULE_NAME "\r\n DAC TEST\r\n"
#define SUB_OPTIONS "\r\nMenu Options:" \
"\r\n'a' - Increase waveform parameters" \
"\r\n's' - Decrease waveform parameters" \
"\r\n'r' - Read the waveform data from Quad-SPI flash into memory buffer" \
"\r\n'w' - Write the current waveform data to Quad-SPI flash storage" \
"\r\n'g' - Start generator" \
"\r\n> Enter your choice and press tab to continue\r\n"
读取终端输入的命令并实现功能:
* Function Name: ext_display_menu
test_fn dac_display_menu(void)
{
DAC_Init(); // DAC 初始化
static int _maxvalue = 4095;
int32_t c = -1;
uint32_t block_size_actual = 0;
int32_t block_sz_ndx = 0;
int32_t block_sz_limit = (INPUT_BUFFER - 2);
bool_t response_flag = false;
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, g_selected_menu);
/* 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);
/* Keep trying to read a valid text block size
* complete the loop in one of two ways:
* [1] Valid block size is entered (2K boundary range 2-64K) followed by TAB
* [2] Space Bar is pressed at any stage
*/
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
while (false == response_flag)
{
print_to_console("input: ");
vTaskDelay(1);
while ((CONNECTION_ABORT_CRTL != c))
{
c = input_from_console();
if (c == 'a')
{
sprintf(s_print_buffer, "\r\nIncrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
_maxvalue += 500;
if(_maxvalue >= 4095) _maxvalue = 4095;
generateSineWaveIntegers(_maxvalue);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 's')
{
sprintf(s_print_buffer, "\r\nDecrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
_maxvalue -= 500;
if(_maxvalue < 0) _maxvalue = 1;
generateSineWaveIntegers(_maxvalue);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 'r') // 读取波形数据
{
sprintf(s_print_buffer, "\r\nRead the waveform data from Quad-SPI flash into memory buffer\r\n");
print_to_console((void*)s_print_buffer);
Read_Waveform_From_Flash(custom_var);
is_custom_wave = true;
sprintf(s_print_buffer, "After Reading, custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
else if (c == 'w') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nWrite the current waveform data to Quad-SPI flash storage\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "Before Writing, var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
Write_Waveform_To_Flash(custom_var);
}
else if (c == 'g') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nStart Generator...\r\n");
print_to_console((void *)s_print_buffer);
dac_start_flag = !dac_start_flag;
}
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
// break;
if (MENU_EXIT_CRTL == c)
{
response_flag = true;
block_size_actual = 0;
break;
}
if (CARRAGE_RETURN != c)
{
sprintf(s_print_buffer, "%c", (char_t)c);
print_to_console((void*)s_print_buffer);
}
// 输出波形
}
if ((MENU_EXIT_CRTL == c) || (0x00 == c))
{
break;
}
}
return (0);
}
End of function ext_display_menu
这样就可以实现菜单实现了:
7、扩展任务,实现命令来输出波形,并可以进行调节,支持存储与读取:
输出波形为,在blink_enty里面实现,实现无阻塞式的连续波形输入,同时用一个状态标志来实现开关:
void blinky_thread_entry(void *pvParameters)
{
static int count;
static uint8_t sw_flage;
FSP_PARAMETER_NOT_USED (pvParameters);
bsp_io_level_t p_port_value_port_004;
bsp_io_level_t p_port_value_red_led;
/* TODO: add your own code here */
while (1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &p_port_value_port_004);
if(!p_port_value_port_004)
{
sw_flage ++;
if(sw_flage > 10)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, &p_port_value_red_led);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, !p_port_value_red_led);
}
}
else
{
sw_flage = 0;
}
if(dac_start_flag) //如果打开了输出标志,测进行波形输出
{
count ++;
count = count%32;
R_DAC_Write(&g_dac0_ctrl, custom_var[count]); //向DAC写入指buff中的数值产生波形
}
vTaskDelay (1);
}
}
在对波形进行调制中,我使用了sin函数对波形数据进行重新计算,并放入缓冲中:
// 函数用于生成正弦波整数数组,参数max_value用于指定最大值
void generateSineWaveIntegers(int max_value) {
for (int i = 0; i < ARRAY_SIZE; i++) {
double x = (2 * PI * i) / (ARRAY_SIZE - 1); // 使用M_PI表示更精确的圆周率,每次循环重新计算x
double sin_value = sin(x);
// 将[-1, 1]范围的正弦值映射到[0, max_value]
double mapped_value = (sin_value + 1) / 2 * max_value;
custom_var[i] = (uint16_t)round(mapped_value);
}
}
写入缓冲到spi flash中,其代码如下:
**
* @brief 将波形数据存储到 Quad Flash
* @param buffer 需要存储的波形
* @retval 无
*/
void Write_Waveform_To_Flash(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;
/* 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;
}
/* 逐页写入波形数据 */
while (((page_write_count * PAGE_WRITE_SIZE) < sizeof(custom_var)) && (FSP_SUCCESS == err))
{
err = R_QSPI_Write(&g_qspi_ctrl, &buffer[page_write_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
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");
}
}
p_mem_addr += PAGE_WRITE_SIZE;
page_write_count++;
}
/* 关闭 QSPI 模块 */
/* close QSPI module */
deinit_qspi(current_spi_mode);
}
读取存储数据到缓冲区中:
/**
* @brief 从 Quad Flash 读取波形数据
* @param buffer 存储波形的缓冲区
* @retval 无
*/
void Read_Waveform_From_Flash(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;
/* 打开 QSPI 模块 */
/* 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;
}
/* 逐页读取波形数据 */
while ((page_read_count * PAGE_WRITE_SIZE) < sizeof(custom_var))
{
memcpy(&buffer[page_read_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
p_mem_addr += PAGE_WRITE_SIZE;
page_read_count++;
}
/* close QSPI module */
deinit_qspi(current_spi_mode);
}
然后组装从串口终端中的命令进行相应的事件处理:
* Function Name: ext_display_menu
test_fn dac_display_menu(void)
{
DAC_Init(); // DAC 初始化
static int _maxvalue = 4095;
int32_t c = -1;
uint32_t block_size_actual = 0;
int32_t block_sz_ndx = 0;
int32_t block_sz_limit = (INPUT_BUFFER - 2);
bool_t response_flag = false;
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, g_selected_menu);
/* 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);
/* Keep trying to read a valid text block size
* complete the loop in one of two ways:
* [1] Valid block size is entered (2K boundary range 2-64K) followed by TAB
* [2] Space Bar is pressed at any stage
*/
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
while (false == response_flag)
{
print_to_console("input: ");
vTaskDelay(1);
while ((CONNECTION_ABORT_CRTL != c))
{
c = input_from_console();
if (c == 'a')
{
sprintf(s_print_buffer, "\r\nIncrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
_maxvalue += 500;
if(_maxvalue >= 4095) _maxvalue = 4095;
generateSineWaveIntegers(_maxvalue);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 's')
{
sprintf(s_print_buffer, "\r\nDecrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
_maxvalue -= 500;
if(_maxvalue < 0) _maxvalue = 1;
generateSineWaveIntegers(_maxvalue);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 'r') // 读取波形数据
{
sprintf(s_print_buffer, "\r\nRead the waveform data from Quad-SPI flash into memory buffer\r\n");
print_to_console((void*)s_print_buffer);
Read_Waveform_From_Flash(custom_var);
is_custom_wave = true;
sprintf(s_print_buffer, "After Reading, custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
else if (c == 'w') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nWrite the current waveform data to Quad-SPI flash storage\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "Before Writing, var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
Write_Waveform_To_Flash(custom_var);
}
else if (c == 'g') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nStart Generator...\r\n");
print_to_console((void *)s_print_buffer);
dac_start_flag = !dac_start_flag;
}
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
// break;
if (MENU_EXIT_CRTL == c)
{
response_flag = true;
block_size_actual = 0;
break;
}
if (CARRAGE_RETURN != c)
{
sprintf(s_print_buffer, "%c", (char_t)c);
print_to_console((void*)s_print_buffer);
}
// 输出波形
}
if ((MENU_EXIT_CRTL == c) || (0x00 == c))
{
break;
}
}
return (0);
}
End of function ext_display_menu
代码如下:
工程介绍如下:
-
加入了学习《Follow me 第二季第3期成果视频》,观看 成果展示
-
发表了主题帖:
【Follow me第二季第3期】 [扩展任务] DAC输出不同波形,FLASH保存和读取历史数据
本帖最后由 lugl4313820 于 2024-12-14 14:09 编辑
在前面几期的前提下,我增加了DAC的配置,以及flash写入与读取的代码。
1、dac的配置:如前面分享的【Follow me第二季第3期】DAC波形生成 - DigiKey得捷技术专区 - 电子工程世界-论坛
2、在menu_adc.c中增加一组生成正弦波的数组:
//正弦波数据数组变量
uint16_t custom_var[32] = {
2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668,
3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127,
310, 564, 878, 1240, 1636, 2048
};
3、增加初始化ADC:
void DAC_Init()
{
R_DAC_Open(&g_dac0_ctrl, &g_dac0_cfg);
R_DAC_Start(&g_dac0_ctrl);
}
4、增加写入与读取的函数:
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] 调整波形数据
* @param new_value 按键输入的值
* @retval 无
*/
void Adjust_Waveform(int32_t step)
{
for (uint32_t i = 0; i < sizeof(custom_var) / sizeof(custom_var[0]); i++)
{
// 调整值,限制范围在 MIN_VALUE 和 MAX_VALUE 之间
if (custom_var[i] + step > MAX_VALUE)
{
custom_var[i] = MAX_VALUE;
}
else if (custom_var[i] + step < MIN_VALUE)
{
custom_var[i] = MIN_VALUE;
}
else
{
custom_var[i] += step;
}
}
}
/**
* @brief 从 Quad Flash 读取波形数据
* @param buffer 存储波形的缓冲区
* @retval 无
*/
void Read_Waveform_From_Flash(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;
/* 打开 QSPI 模块 */
// 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;
}
/* 逐页读取波形数据 */
while ((page_read_count * PAGE_WRITE_SIZE) < sizeof(custom_var))
{
memcpy(&buffer[page_read_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
p_mem_addr += PAGE_WRITE_SIZE;
page_read_count++;
}
// /* 关闭 QSPI 模块 */
// 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);
}
/**
* @brief 将波形数据存储到 Quad Flash
* @param buffer 需要存储的波形
* @retval 无
*/
void Write_Waveform_To_Flash(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;
/* 打开 QSPI 模块 */
// 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;
}
/* 逐页写入波形数据 */
while (((page_write_count * PAGE_WRITE_SIZE) < sizeof(custom_var)) && (FSP_SUCCESS == err))
{
err = R_QSPI_Write(&g_qspi_ctrl, &buffer[page_write_count * PAGE_WRITE_SIZE / sizeof(uint16_t)], p_mem_addr, PAGE_WRITE_SIZE);
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");
}
}
p_mem_addr += PAGE_WRITE_SIZE;
page_write_count++;
}
/* 关闭 QSPI 模块 */
// 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);
}
这里有些函数是引用menu_ext.c中的函数,有些是私有的,需要修改为全局的,并添加到muenu_ext.h中:
#ifndef MENU_EXT_H_
#define MENU_EXT_H_
extern test_fn ext_display_menu (void);
fsp_err_t qpi_init (void);
void deinit_qspi (const spi_flash_protocol_t spi_protocol_mode);
fsp_err_t get_flash_status(void);
#endif /* MENU_KIS_H_ */
5、添加对数组的波形的设置:
/**
* @brief 调整波形数据
* @param new_value 按键输入的值
* @retval 无
*/
void Adjust_Waveform(int32_t step)
{
for (uint32_t i = 0; i < sizeof(custom_var) / sizeof(custom_var[0]); i++)
{
// 调整值,限制范围在 MIN_VALUE 和 MAX_VALUE 之间
if (custom_var[i] + step > MAX_VALUE)
{
custom_var[i] = MAX_VALUE;
}
else if (custom_var[i] + step < MIN_VALUE)
{
custom_var[i] = MIN_VALUE;
}
else
{
custom_var[i] += step;
}
}
}
6、在接收函数中添加各个功能模块的功能:
* Function Name: ext_display_menu
test_fn dac_display_menu(void)
{
DAC_Init(); // DAC 初始化
int32_t c = -1;
uint32_t block_size_actual = 0;
int32_t block_sz_ndx = 0;
int32_t block_sz_limit = (INPUT_BUFFER - 2);
bool_t response_flag = false;
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, g_selected_menu);
/* 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);
/* Keep trying to read a valid text block size
* complete the loop in one of two ways:
* [1] Valid block size is entered (2K boundary range 2-64K) followed by TAB
* [2] Space Bar is pressed at any stage
*/
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
while (false == response_flag)
{
print_to_console("input: ");
vTaskDelay(1);
while ((CONNECTION_ABORT_CRTL != c))
{
c = input_from_console();
if (c == 'a')
{
sprintf(s_print_buffer, "\r\nIncrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
Adjust_Waveform(STEP_SIZE); // 增加波形值
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 's')
{
sprintf(s_print_buffer, "\r\nDecrease waveform parameters\r\n");
print_to_console((void*)s_print_buffer);
Adjust_Waveform(-STEP_SIZE); // 减少波形值
sprintf(s_print_buffer, "custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
if (c == 'r') // 读取波形数据
{
sprintf(s_print_buffer, "\r\nRead the waveform data from Quad-SPI flash into memory buffer\r\n");
print_to_console((void*)s_print_buffer);
Read_Waveform_From_Flash(custom_var);
is_custom_wave = true;
sprintf(s_print_buffer, "After Reading, custom_var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "custom_var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
}
else if (c == 'w') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nWrite the current waveform data to Quad-SPI flash storage\r\n");
print_to_console((void*)s_print_buffer);
sprintf(s_print_buffer, "Before Writing, var contains:\r\n");
print_to_console((void *)s_print_buffer);
for (uint32_t i = 0; i < 32; i++)
{
sprintf(s_print_buffer, "var[%u] = %u\r\n", i, custom_var[i]);
print_to_console((void *)s_print_buffer);
}
Write_Waveform_To_Flash(custom_var);
}
else if (c == 'g') // 写入波形数据
{
sprintf(s_print_buffer, "\r\nStart Generator...\r\n");
print_to_console((void *)s_print_buffer);
dac_start_flag = !dac_start_flag;
}
block_sz_ndx = 0;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
// break;
if (MENU_EXIT_CRTL == c)
{
response_flag = true;
block_size_actual = 0;
break;
}
if (CARRAGE_RETURN != c)
{
sprintf(s_print_buffer, "%c", (char_t)c);
print_to_console((void*)s_print_buffer);
}
// 输出波形
}
if ((MENU_EXIT_CRTL == c) || (0x00 == c))
{
break;
}
}
return (0);
}
函数中,按键按下'g'开始输出波形,再按一次停止波形。使用了一个全局的标志dac_start_flag,来做为输出的开关。
7、在blinky_thread_entry任务中,来对DAC进行波形的输出。
/***********************************************************************************************************************
* Copyright (c) 2021 - 2024 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
***********************************************************************************************************************/
#include <blinky_thread.h>
extern uint16_t custom_var[32];
extern uint8_t dac_start_flag;
/**********************************************************************************************************************
* Function Name: blinky_thread_entry
* Description : .
* Argument : pvParameters (contains TaskHandle_t)
* Return Value : .
*********************************************************************************************************************/
void blinky_thread_entry(void *pvParameters)
{
static int count;
FSP_PARAMETER_NOT_USED (pvParameters);
/* TODO: add your own code here */
while (1)
{
if(dac_start_flag)
{
count ++;
count = count%32;
R_DAC_Write(&g_dac0_ctrl, custom_var[count]);
}
vTaskDelay (1);
}
}
/**********************************************************************************************************************
End of function blinky_thread_entry
【效果】
当我们进入菜单,按下g时,就开始输出波形,按下a,波形的电压值升高,按下s键波形缩小,按下w键,向flash写入当前波形数据,按下r,读取存取的数据。
【总结】
本次学习了DAC与按键输入,flash的读取。做了一个综合的例程。
-
回复了主题帖:
泰坦触觉 TITAN Core快速设置教程来啦~【你不来申请一块吗?】
okhxyyo 发表于 2024-12-14 11:47
我问问泰坦哦。活动页面里有那个卡皮巴拉和心动的diy资料,可以看看。
我翻了一下,好象没有看到有示例工程,不能打无准备之战呀,我想做个智能提示的东东。
-
发表了主题帖:
【Follow me第二季第3期】进阶任务——示例程序中新增命令打印信息:
1、quickstart_ek工程中新建两个文件,分别为menu_dac.h/c:
2、menu_adc.c内容如下,主要是进入时,打印提示菜单,然后周期读取数据,如果是1-5打印出相应的字符,如果是0则退出此个菜单:
/*
* menu_dac.c
*
* Created on: 2024年12月14日
* Author: liujianhua
*/
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "semphr.h"
#include "queue.h"
#include "task.h"
#include "bsp_api.h"
#include "common_init.h"
#include "common_data.h"
#include "common_utils.h"
#include "menu_ext.h"
#define CONNECTION_ABORT_CRTL (0x00)
#define MENU_EXIT_CRTL (0x20)
#define MENU_ENTER_RESPONSE_CRTL (0x09)
#define INPUT_BUFFER (0x05)
#define CARRAGE_RETURN (0x0D)
#define BLOCK_LIMIT (0x40)
#define MODULE_NAME "\r\n DAC TEST\r\n"
#define SUB_OPTIONS ("Wave control:\r\n" \
"1: Triangle Wave\r\n" \
"2: Square Wave\r\n" \
"3: Sine Wave\r\n" \
"4: Read from flash \r\n" \
"5: Write to flash \r\n" \
"0: Exit\r\n")
/* Each thread must have a separate print buffer, to avoid clashes on task switching */
static char_t s_print_buffer[BUFFER_LINE_LENGTH] = {};
static char_t s_block_sz_str[INPUT_BUFFER] = {};
/**********************************************************************************************************************
* Function Name: ext_display_menu
* Description : .
* Return Value : .
*********************************************************************************************************************/
test_fn dac_display_menu(void)
{
int32_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);
sprintf(s_print_buffer, MODULE_NAME, g_selected_menu);
/* 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*)SUB_OPTIONS);
/* Reset input state */
c = -1;
memset(&s_block_sz_str, 0, INPUT_BUFFER);
while ((CONNECTION_ABORT_CRTL != c))
{
c = input_from_console();
value = (uint32_t)(c-'0');
switch (value)
{
case INVALID_CHARACTER:
sprintf(s_print_buffer,"\r\n> Invalid character in entry,please entry'0-5'");
print_to_console((void*)s_print_buffer);
break;
case 1:
sprintf(s_print_buffer,"\r\n> begain Triangle Wave ");
print_to_console((void*)s_print_buffer);
break;
case 2:
sprintf(s_print_buffer,"\r\n> begain Square Wave ");
print_to_console((void*)s_print_buffer);
break;
case 3:
sprintf(s_print_buffer,"\r\n> begain Sine Wave ");
print_to_console((void*)s_print_buffer);
break;
case 4:
sprintf(s_print_buffer,"\r\n> Read from flash ");
print_to_console((void*)s_print_buffer);
break;
case 5:
sprintf(s_print_buffer,"\r\n> Write to flash ");
print_to_console((void*)s_print_buffer);
break;
case 0:
sprintf(s_print_buffer,"\r\n> Exit ");
print_to_console((void*)s_print_buffer);
return 0;
break;
}
}
while ((CONNECTION_ABORT_CRTL != c))
{
if ((MENU_EXIT_CRTL == c) || (0x00 == c))
{
break;
}
c = input_from_console();
}
return (0);
}
/**********************************************************************************************************************
End of function ext_display_menu
*********************************************************************************************************************/
3、头文件则是声明菜单的接口:
#ifndef __MENU_DAC_H__
#define __MENU_DAC_H__
test_fn dac_display_menu(void);
#endif __MENU_DAC_H__
4、将头文件添加到menu_main.h中:
5、在主菜单的列表里添加一条菜单,并把dac_display_menu子菜单函数添加进回调函数:
【实现效果】
按6进入子菜单:
按下0又可以回到主菜单。
-
回复了主题帖:
[Follow me第二季第3期] [扩展任务] DAC输出不同波形,FLASH保存和读取历史数据
御坂10032号 发表于 2024-12-12 23:29
哎,哪里有示波器。 家境贫寒
发几个好帖子,拿了奖去换个虚拟示波器,应该不难!
-
回复了主题帖:
【英飞凌PSOC™ 4100S Max】⑥作品提交:电机触控及屏显系统
看了一下,楼主的工具挺多呀,这转盘也是有个性哦!
-
回复了主题帖:
泰坦触觉 TITAN Core快速设置教程来啦~【你不来申请一块吗?】
申请的机会多不多呀,能不能发一下ESP32教程,要不心理没底呀。
-
回复了主题帖:
2024年12月 TIOBE 编程指数
python还是遥遥领先,C++的上升势 头还可以,C是不是会慢慢下降了。