本帖最后由 beyond_笑谈 于 2024-12-8 22:11 编辑
入门任务:搭建环境,下载调试示例程序,Blink,按键
此任务的目的是搭建开发板的软件编辑环境、初次编译示例程序,以及在例程中增加按键控制LED的程序并且下载测试验证。
由于电脑原因无法通过github下载e2 studio的安装包和例程代码,所以请网友下载后放在了百度网盘提供给需要的网友参考
setup_fsp_v5_6_0_e2s_v2024-10.exe
链接: 提取码: 9p35
ra-fsp-examples-master.zip
链接: 提取码: p45p
下载安装包(如下图)后按照步骤安装软件即可
安装成功并且打开时软件如下图
接着导入参考例程
配置串口调试终端
初次编译开发板提供的quickstart工程文件
编译后进入调试模式,点击下图调试。并且将Micro usb从USB full speed接到DEBUG,如下图
Blink、按键程序测试
在参考例程中增加按键开关控制LED闪烁频率的功能,搜索gpt的中断回调gpt_blinker_callback
找到LED工作状态控制的函数
LED的亮度s_duty取决于变量g_pwm_dcs,通过修改此变量更改LED的亮度并对应的修改数组长度和增加宏定义
修改完成后保存并编译然后下载到开发板中
测试环境和测试视频如下:
1
基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试;
测试quad-spi flash和octo-spi flash读写速度对比,如下图
进入主函数(main.c)找到菜单任务
通过菜单任务逐布找到菜单选项部分程序,也就是串口调试页面的菜单选项,如下
进入spi测试部分程序
编辑程序如下
SPI读写测试程序及转换程序如下
ospi_performance_test (block_size_actual, &ospi_performance_write_result, &ospi_performance_read_result);
ospi_write_result = ((100000000 / timer_frequency) * ospi_performance_write_result) / 100;
qspi_write_result = ((100000000 / timer_frequency) * qspi_write_test(block_size_actual)) / 100;
print_to_console((uint8_t *)"Writing to flash completed\r\n");
print_to_console((uint8_t *)"\r\nReading the text block from external Quad-SPI and Octo-SPI flash memories...\r\n");
ospi_read_result = ((100000000 / timer_frequency) * ospi_performance_read_result) / 100;
qspi_read_result = ((100000000 / timer_frequency) * qspi_read_test(block_size_actual)) / 100;
ospi数据写入测试程序如下:
static uint32_t write_dopi_ospi(uint32_t data_size)
{
fsp_err_t err;
uint32_t test_var;
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);
number_of_pages = (uint32_t)(data_size * (1024 / OSPI_TEST_PAGE_SIZE));
for (test_var = 0; test_var < number_of_pages; test_var++ )
{
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);
}
ospi数据读取测试程序如下:
static uint32_t read_dopi_ospi(uint32_t data_size)
{
uint32_t * p_src = (uint32_t *)OSPI_DMA_ADDRESS;
uint32_t * p_dest = (uint32_t *)s_perf_read;
timer_status_t status = {};
R_GPT_Open(g_memory_performance.p_ctrl, g_memory_performance.p_cfg);
#ifdef READ_PAGE_BY_PAGE
number_of_blocks = data_size * ( 1024 / OSPI_TEST_PAGE_SIZE);
while(number_of_blocks--)
{
data = (OSPI_TEST_PAGE_SIZE) / 4U;
R_GPT_Start(g_memory_performance.p_ctrl);
#ifdef MANUAL_READ
while (data)
{
*p_dest = *p_src;
p_dest++;
p_src++;
data--;
}
#endif
#define READ_MEMCPY
#ifdef READ_MEMCPY
memcpy ( p_dest, p_src, OSPI_TEST_PAGE_SIZE / 4);
p_src += OSPI_TEST_PAGE_SIZE / 4;
p_dest += OSPI_TEST_PAGE_SIZE / 4;
R_GPT_Stop(g_memory_performance.p_ctrl);
vTaskDelay(1U);
#endif
}
#endif
#ifdef READ_AS_SINGLE_BLOCK
R_GPT_Start(g_memory_performance.p_ctrl);
R_OSPI_XipEnter(g_ospi.p_ctrl);
memcpy (p_dest, p_src, (data_size * 1024) / 4);
R_OSPI_XipExit(g_ospi.p_ctrl);
R_GPT_Stop(g_memory_performance.p_ctrl);
#endif
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);
}
qspi数据写入测试程序如下:
static uint32_t qspi_write_test(uint32_t block_size)
{
fsp_err_t fsp_err;
uint32_t qspi_write_result = 0;
timer_status_t status = {};
fsp_err_t err = FSP_SUCCESS;
spi_flash_protocol_t current_spi_mode;
block_size *= 1024;
current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
err = qpi_init();
if (FSP_SUCCESS == err)
{
current_spi_mode = g_qspi_cfg.spi_protocol;
}
uint32_t page_write_count = 0;
uint8_t * p_mem_addr;
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
while (((page_write_count * SECTOR_SIZE) < block_size)
&& ( FSP_SUCCESS == err ) )
{
err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
}
else
{
err = get_flash_status();
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
}
uint32_t count;
for (count = 0; count < SECTOR_SIZE; count++ )
{
if (DEFAULT_MEM_VAL != p_mem_addr[count])
{
err = FSP_ERR_NOT_ERASED;
}
}
}
p_mem_addr += SECTOR_SIZE;
page_write_count++;
}
fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
page_write_count = 0;
while (((page_write_count * PAGE_WRITE_SIZE) < block_size)
&& (FSP_SUCCESS == err))
{
if (FSP_SUCCESS == err)
{
err = R_QSPI_Write(&g_qspi_ctrl, &(sp_source[page_write_count]), p_mem_addr, PAGE_WRITE_SIZE);
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
}
else
{
err = get_flash_status();
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
}
}
}
p_mem_addr += PAGE_WRITE_SIZE;
page_write_count++;
}
deinit_qspi(current_spi_mode);
fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
qspi_write_result = status.counter;
return (qspi_write_result);
}
qspi数据读取测试程序如下:
static uint32_t qspi_read_test(uint32_t block_size)
{
fsp_err_t fsp_err;
fsp_err_t err = FSP_SUCCESS;
uint32_t qspi_read_result = 0;
timer_status_t status = {};
spi_flash_protocol_t current_spi_mode;
uint8_t * p_dma_read_buffer;
uint32_t page_read_count;
uint8_t * p_mem_addr;
block_size *= 1024;
p_dma_read_buffer = pvPortMalloc(block_size);
if (NULL == p_dma_read_buffer)
{
HeapStats_t pxHeapStats;
vPortGetHeapStats(&pxHeapStats);
sprintf(s_print_buffer, "\r\nQSPI malloc operation Failed - Max free mem: %dbytes\r\n",
pxHeapStats.xSizeOfLargestFreeBlockInBytes);
err = FSP_ERR_NOT_ERASED;
}
current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
err = qpi_init();
if (FSP_SUCCESS == err)
{
current_spi_mode = g_qspi_cfg.spi_protocol;
}
fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
page_read_count = 0;
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
while (((page_read_count * PAGE_WRITE_SIZE) < block_size)
&& (FSP_SUCCESS == err))
{
if ((fsp_err_t) (memcmp (p_mem_addr, &(sp_source[page_read_count]), PAGE_WRITE_SIZE)) != FSP_SUCCESS)
{
err = FSP_ERR_NOT_ERASED;
sprintf(s_print_buffer, "\r\nQSPI operation Failed -> Data read does not match with written data\r\n");
}
p_mem_addr += PAGE_WRITE_SIZE;
page_read_count++;
}
fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);
deinit_qspi(current_spi_mode);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);
if (FSP_SUCCESS != fsp_err)
{
SYSTEM_ERROR
}
qspi_read_result = status.counter;
vPortFree(p_dma_read_buffer);
return (qspi_read_result);
}
测试环境和测试视频如下:
2--1
DAC配置生成波形及性能测试
Stack中增加DAC的功能配置
增加DAC0引脚P014并配置为enable,引脚冲突
确认是ADC0的第12通道AN012已经占用P014
ADC0的AN012引脚配置为None,DAC0的引脚配置则不冲突
在common_init中增加DAC函数调用
增加正旋波形产生函数程序
#include "math.h"
#define M_PI 3.14159265358979323846
void gpt_blue_callback(timer_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
uint16_t dacvalue = 0;
static double w = 0.0;
w += M_PI / 30;
if (w >= M_PI * 2)
{
w = 0.0;
}
dacvalue = (sin(w) + 1) / 2 * 4096;
R_DAC_Write(&g_dac0_ctrl, dacvalue);
利用笔式示波器测量P014引脚的输出波形,如下
测试环境和测试视频如下
2-2
进阶任务:示例程序中新增命令打印信息
在串口终端页面显示菜单中增加一项
增加外部函数声明
增加函数内容
编译后下载,然后打开串口终端,已经增加这一项
Kit Information 如下
新增的Demo Information 如下
测试环境和测试视频如下:
3
扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。
导入例程并且增加波形选择部分程序
增加波形生成部分程序
增加波形保存部分程序
采用示波器抓取P014引脚的波形
利用串口终端选择输出波形并且测试
测试照片和视频如下:
4
完整的测试视频由于容量过大,请见:https://training.eeworld.com.cn/course/68824
完整的代码如下:
|