【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的读取。做了一个综合的例程。
|