本帖最后由 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
工程介绍如下:
|