155|0

172

帖子

3

TA的资源

一粒金砂(高级)

楼主
 

【Follow me第二季第三期】进阶任务:通过USB发送指令修改QSPI中的数据 [复制链接]

 

本帖最后由 EPTmachine 于 2024-12-15 12:07 编辑

查看开发资料中演示例程的流程图了解控制台指令是如何实现的。开发板通过USB接口连接到电脑后,通过对电脑端发送的字符串进行解析,从而执行不同的功能函数。

USB传输字符串并解析

USB通讯中,客户端(这里为开发板)可以设定端点(endpoint)的类型,实现不同的功能,本任务中使用的CDC类型的端点,通过usb连接至电脑后,可以实现串口通讯功能,传输数据,实现人机交互。

实现上述功能需要用的到外设有qspi、usb。在FSP的配置界面中添加需要用到的组件、定义的RTOS线程以及信号量等。

USB模块使用USB_PCDC,FSP工具可以生成USB CDC类型端点的代码,简化开发流程。

属性界面中设置CallBack的函数名。

QSPI的配置参考基础任务中的qspi配置。

添加新指令

任务目标是添加一条新指令,指令的功能设定为查看和修改存储在QSPI Flash上的DDS数据。存储在QSPI Flash上的数据结构为dds_record,dds_record的定义如下。

  1. typedef struct dds_param{
  2. uint8_t waveType;
  3. uint8_t amp;
  4. int8_t offset;
  5. uint32_t freq;
  6. }dds_param_t;
  7. enum dds_wavetype{
  8. SIN_WAVE=0,
  9. SQU_WAVE=1,
  10. TRI_WAVE=2
  11. };
  12. #define DDS_RECORD_TYPE 0xF5
  13. typedef struct dds_record{
  14. uint8_t type;
  15. dds_param_t dds_items[10];
  16. }dds_record_t;

程序设计

程序设计参考示例程序的框架,包含的文件中新的文件如图所示。dds_record.c、dds_record.h和dds_record_ctrl_entry.c实现在QSPI Flash中管理数据的功能。menu_dds_record.c、menu_dds_record.h实现指令解析部分。

新文件中的代码为实现新指令的代码。

Flash存储相关的代码会初始化qspi flash,并对需要存储的数据进行管理。

  1. #include "common_init.h"
  2. #include "common_utils.h"
  3. #include "qspi_drv.h"
  4. #define DDS_RECORD_SIZE 1024
  5. static char_t s_print_buffer[BUFFER_LINE_LENGTH] = {};
  6. extern dds_record_t dds_record_ins;
  7. /* DDS_record entry function */
  8. /* pvParameters contains TaskHandle_t */
  9. void dds_record_ctrl_entry(void *pvParameters)
  10. {
  11. FSP_PARAMETER_NOT_USED (pvParameters);
  12. fsp_err_t err;
  13. uint8_t* p_src=(uint8_t *)QSPI_DEVICE_START_ADDRESS;;
  14. uint8_t* p_dest=(uint8_t*)&dds_record_ins;
  15. qpi_init();
  16. memcpy (p_dest, p_src, sizeof(dds_record_t));
  17. if(dds_record_ins.type!=DDS_RECORD_TYPE)
  18. {
  19. /* Erase Flash for one sector */
  20. err = R_QSPI_Erase(&g_qspi_ctrl, p_src, SECTOR_SIZE);
  21. if (FSP_SUCCESS != err)
  22. {
  23. sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
  24. print_to_console((void*)s_print_buffer);
  25. }
  26. }
  27. /* TODO: add your own code here */
  28. while (1)
  29. {
  30. while (pdPASS != xSemaphoreTake(g_store_dds_semaphore, pdMS_TO_TICKS(500u)))
  31. {
  32. vTaskDelay(10);
  33. }
  34. dds_record_ins.type=DDS_RECORD_TYPE;
  35. /* Erase Flash for one sector */
  36. err = R_QSPI_Erase(&g_qspi_ctrl, p_src, SECTOR_SIZE);
  37. if (FSP_SUCCESS != err)
  38. {
  39. sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
  40. print_to_console((void*)s_print_buffer);
  41. }
  42. err = get_flash_status();
  43. err = R_QSPI_Write(&g_qspi_ctrl, (uint8_t*)&dds_record_ins, p_src, sizeof(dds_record_t));
  44. if (FSP_SUCCESS != err)
  45. {
  46. sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
  47. print_to_console((void*)s_print_buffer);
  48. }
  49. err = get_flash_status();
  50. sprintf (s_print_buffer, "g_store_dds_semaphore recevied" );
  51. print_to_console((void*)s_print_buffer);
  52. memcpy (p_dest, p_src, sizeof(dds_record_t));
  53. vTaskDelay (10);
  54. }
  55. }

上述代码在初始化QSPI Flash后,读取其中的数据,并等待g_store_dds_semaphore信号量,用于更新Flash中存储的内容。

USB CDC模块中,用户需要自定义相关的端点描述符用于设备的枚举。相关的代码参考示例程序在r_usb_pcdc_descriptor.c中。

usb的Callback中转发接受到的事件,用于后续的字符解析。

  1. void usb_console_callback(usb_event_info_t* p_event_info, usb_hdl_t hdl, usb_onoff_t state)
  2. {
  3. /* Void unused args */
  4. FSP_PARAMETER_NOT_USED(hdl);
  5. FSP_PARAMETER_NOT_USED(state);
  6. BaseType_t xHigherPriorityTaskWoken;
  7. memcpy(&s_usb_event_list[s_usb_event_pindex], p_event_info, sizeof(usb_event_info_t));
  8. if (xQueueIsQueueFullFromISR(g_usb_transaction_queue) == pdFALSE)
  9. {
  10. xQueueSendToBackFromISR(g_usb_transaction_queue, &s_usb_event_pindex, &xHigherPriorityTaskWoken);
  11. /* set next available index, cast to maintain sign integrity */
  12. s_usb_event_pindex = (uint8_t)((s_usb_event_pindex + 1) % USB_QUEUE_SIZE);
  13. }
  14. else
  15. {
  16. /* Fatal error - usb message queue is full, this should not occur unless there has been a fatal USB error */
  17. //SYSTEM_ERROR
  18. }
  19. /* Switch context if necessary. */
  20. if (xHigherPriorityTaskWoken)
  21. {
  22. taskYIELD ();
  23. }
  24. }

后续对字符串的处理参考示例代码中usb_console_main.c的实现。

USB交互相关的部分则对用户的输入进行解析,修改DDS_record中数据,数据修改完成后,向Flash存储任务发出信号量g_store_dds_semaphore,进行存储数据的更新。主要的代码menu_dds_record.c的dds_record_menu函数中。相关的代码在工程的dds_record_menu函数中。

实际测试

工程编译并下载后,效果运行的效果如下所示。能够对Flash中存储的数据进行读写管理。

相关工程代码

task03_usb_cmd.7z

(1.34 MB, 下载次数: 0)

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
Microchip 直播|利用motorBench开发套件高效开发电机磁场定向控制方案 报名中!
直播主题:利用motorBench开发套件高效开发电机磁场定向控制方案
直播时间:2025年3月25日(星期二)上午10:30-11:30
快来报名!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表