stm32h7第3章threadxusbx协议栈移植到stm32h7(代码片段)

Simon223 Simon223     2023-01-15     555

关键词:

教程更新中:ThreadX USBX协议栈教程更新记录贴,前5章发布(2021-10-11) - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz!http://www.armbbs.cn/forum.php?mod=viewthread&tid=108546

第3章   ThreadX USBX协议栈移植到STM32H7

本章节为大家讲解USBX协议栈移植到STM32H7。

目录

3.1   初学者重要提示

3.2   USBX移植步骤

3.2.1      第1步,了解整体设计框架

3.2.2      第2步,添加USBX和USB驱动到工程

3.2.3      第3步,添加工程路径

3.2.4      第4步,禁止掉添加进来一些文件

3.2.5      第4步,配置GPIO和时钟

3.2.6      第5步,MPU配置

3.2.7      第7步,添加应用代码(USB中断,打开U盘和关闭U盘)

3.3   USBX的模拟U盘移植接口文件ux_device_msc.c说明

3.3.1  状态函数app_usb_device_thread_media_status

3.3.2  读取函数app_usb_device_thread_media_read

3.3.3  写入函数app_usb_device_thread_media_write

3.3.4  接口函数注册

3.4   使用的MicroUSB接口并注意跳线帽设置

3.5   实验例程

3.6   总结


3.1   初学者重要提示

1、  本章使用的ST专门为STM32H7提供的软件包:http://www.armbbs.cn/forum.php?mod=viewthread&tid=108816

2、  本章配套例子使用SD卡模拟一个U盘,使用的MicroUSB接口。

3.2   USBX移植步骤

ThreadX USBX的移植步骤如下:

3.2.1      第1步,了解整体设计框架

为了方便大家移植,需要大家先对移植好的工程有个整体认识:

 

3.2.2      第2步,添加USBX和USB驱动到工程

这里我们在FileX教程做的模板例子基础上添加USBX文件和USB驱动文件,大家可以直接从本章教程提供的例子里面复制。

  •   模拟U盘驱动文件ux_device_msc.c/.h和ux_device_descriptors.c/.h添加到自己的工程里面,路径不限。

配套例子是放在\\User\\usb文件。

  •   USB驱动文件stm32h7xx_hal_hcd.c,stm32h7xx_hal_pcd.c,stm32h7xx_hal_pcd_ex.c和stm32h7xx_ll_usb.c。

这个是STM32H7的HAL库自带的。

  •   USBX相关源文件。

大家可以将所有相关文件都复制到自己的工程里面,配套例子是放在\\USBX。

3.2.3      第3步,添加工程路径

大家根据自己添加的源文件位置,添加相关路径即可:

 

3.2.4      第4步,禁止掉添加进来一些文件

之所以要禁止掉是因为这些文件要用到NetXDUO网络协议栈,或者大家不添加进来都是可以的。添加进来后再禁止的优势是添加时候可以全选添加。

 

禁止的方法是右击此文件去掉如下对钩即可:

 

3.2.5      第4步,配置GPIO和时钟

USB时钟配置在bsp.c文件的函数SystemClock_Config里面:


		/*
		USB工作需要48MHz的时钟,可以由PLL1Q,PLL3Q和HSI48提供
			PLL1Q用于给SDMMC提供时钟
		    PLL3Q给LTDC提供时钟,也可以跟USB共用,不过得更USB设置相同的频率才可一起用。
		    HSI48可以供USB独享,就是精度不是很高。
		*/
		RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = 0;
#if 0
		/* PLL3-Q for USB Clock = 48M */
		PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
		PeriphClkInitStruct.PLL3.PLL3M = 5;
		PeriphClkInitStruct.PLL3.PLL3N = 48;
		PeriphClkInitStruct.PLL3.PLL3P = 2;
		PeriphClkInitStruct.PLL3.PLL3Q = 5;
		PeriphClkInitStruct.PLL3.PLL3R = 2;
		PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2;
		PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
		PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
		PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3;
		if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct)!= HAL_OK)
		
			Error_Handler(__FILE__, __LINE__);
			
#else
		PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
		PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
		if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
		
			Error_Handler(__FILE__, __LINE__);
		
              HAL_PWREx_EnableUSBVoltageDetector();
#endif
		

USB的GPIO,NVIC初始化在demo_sd_usbx.c:

/* 配置USB GPIO, NVIC */
    
        GPIO_InitTypeDef  GPIO_InitStruct = 0;

        __HAL_RCC_GPIOA_CLK_ENABLE();

        GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_FS;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* 使能USB FS时钟 */
        __HAL_RCC_USB2_OTG_FS_CLK_ENABLE();

        /* 在睡眠模式下禁用USB时钟 */
        __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE();
        
        /* 配置USB FS中断 */
        HAL_NVIC_SetPriority(OTG_FS_IRQn, 0x2, 0); 
        HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
    

    /* 初始化USB */
    
        HAL_PWREx_EnableUSBVoltageDetector();

        memset(&hpcd_USB_OTG_FS, 0x0, sizeof(PCD_HandleTypeDef));
        hpcd_USB_OTG_FS.Instance = USB2_OTG_FS;
        hpcd_USB_OTG_FS.Init.dev_endpoints = 8;
        hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = 0;
        hpcd_USB_OTG_FS.Init.ep0_mps = 0x40;
        hpcd_USB_OTG_FS.Init.low_power_enable = 0;
        hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
        hpcd_USB_OTG_FS.Init.Sof_enable = 0;
        hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
        hpcd_USB_OTG_FS.Init.vbus_sensing_enable = 0;
        hpcd_USB_OTG_FS.Init.lpm_enable = 0;

        /* 初始化USB  */
        HAL_PCD_Init(&hpcd_USB_OTG_FS);

        /* 设置TX FIFO和RX FIFO */
        HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 1024);
        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 64);
        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 1024);

        /* 注册STM32到USBX协议栈并初始化 */
        status =  ux_dcd_stm32_initialize((ULONG)USB2_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);

        if (status != FX_SUCCESS)
        
            return;
        
        
    

3.2.6      第5步,MPU配置

为了方便大家移植测试,我们这里直接关闭AXI SRAM的读Cache和写Cache(这样就跟使用STM32F1或者STM32F4系列里面的SRAM一样)。此配置是在bsp.c文件的MPU_Config函数里面实现:

/*
*********************************************************************************************************
*	函 数 名: MPU_Config
*	功能说明: 配置MPU
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )

	MPU_Region_InitTypeDef MPU_InitStruct;

	/* 禁止 MPU */
	HAL_MPU_Disable();

#if 0
   	/* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0x24000000;
	MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

	HAL_MPU_ConfigRegion(&MPU_InitStruct);

 #else
     /* 当前是采用下面的配置 */
	/* 配置AXI SRAM的MPU属性为NORMAL, NO Read allocate,NO Write allocate */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0x24000000;
	MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

	HAL_MPU_ConfigRegion(&MPU_InitStruct);
#endif
	/* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0x60000000;
	MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;	
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
	
	HAL_MPU_ConfigRegion(&MPU_InitStruct);

	/*使能 MPU */
	HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

3.2.7      第7步,添加应用代码(USB中断,打开U盘和关闭U盘)

USB操作专门整理到了文件demo_sd_usbx.c。主要三部分,打开U盘,关闭U盘和USB中断服务程序。这三个函数基本是通用的,大家直接复制粘贴使用即可

特别注意USB中断服务程序别忘了添加。

3.3   USBX的模拟U盘移植接口文件ux_device_msc.c说明

这里将USBX的底层接口文件ux_device_msc.c的实现为大家简单做个说明。

3.3.1  状态函数app_usb_device_thread_media_status

代码如下:

UINT  app_usb_device_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)


  /* The ATA drive never fails. This is just for app_usb_device only !!!! */
  return (UX_SUCCESS);

此函数主要用于获取SD卡模拟U盘的状态。

3.3.2  读取函数app_usb_device_thread_media_read

代码如下:

/**
  * @brief  Function implementing app_usb_device_thread_media_read.
  * @param  storage : Not used
  * @param  lun: Logical unit number
  * @param  lba: Logical block address
  * @param  number_blocks: Blocks number
  * @param  data_pointer: Data
  * @param  media_status: Not used
  * @retval Status (0 : OK / -1 : Error)
  */
UINT  app_usb_device_thread_media_read(VOID *storage, ULONG lun,
                                       UCHAR *data_pointer,
                                       ULONG number_blocks,
                                       ULONG lba, ULONG *media_status)

    UINT status = 0U;

    BSP_SD_ReadBlocks((uint32_t *) data_pointer, lba, number_blocks, 500);									
    //while(BSP_SD_GetCardState() != SD_TRANSFER_OK);
    status = check_sd_status(0);    
    return (status);

用于实现SD模拟U盘的读取功能。

3.3.3  写入函数app_usb_device_thread_media_write

代码如下:

/**
  * @brief  Function implementing app_usb_device_thread_media_write.
  * @param  storage : Not used
  * @param  lun: Logical unit number
  * @param  lba: Logical block address
  * @param  number_blocks: Blocks number
  * @param  data_pointer: Data
  * @param  media_status: Not used
  * @retval Status (0 : OK / -1 : Error)
  */
UINT  app_usb_device_thread_media_write(VOID *storage, ULONG lun,
                                        UCHAR *data_pointer,
                                        ULONG number_blocks,
                                        ULONG lba, ULONG *media_status)

    UINT status = 0U;

    BSP_SD_WriteBlocks((uint32_t *) data_pointer, lba, number_blocks, 500);
    //while(BSP_SD_GetCardState() != SD_TRANSFER_OK);
    status = check_sd_status(0);
    
    return (status);

用于实现SD模拟U盘的写入功能。

3.3.4  接口函数注册

接口函数的注册是在文件demo_sd_usbx.c里面:

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read  =  app_usb_device_thread_media_read;

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write  =  app_usb_device_thread_media_write; 

storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status =  app_usb_device_thread_media_status;

3.4   使用的MicroUSB接口并注意跳线帽设置

本周教程移植的例子使用内部RAM模拟了一个U盘,效果如下:

 

注意使用的是MicroUSB接口:

 

注意板子左下角跳线帽的设置:

 

这里是用于选择CAN1 TX使用PB9或者PA12引脚,CAN1 RX使用PB8或者PA11引脚。大家这里可以什么都不接,或者CAN1 TX通过跳线帽短接PA12,CAN1 RX通过跳线帽短接PA11。切记不可以短接到PA12和PA11引脚上,USB要使用这两个引脚。

3.5   实验例程

配套例子:

V7-2401_ThreadX USBX Template

实验目的:

  1. 学习USBX模板,通过SD来模拟U盘。

实验内容:

1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况                                 

  ========================================================

         CPU利用率 =  0.89%

         任务执行时间 = 0.586484645s

         空闲执行时间 = 85.504470575s

         中断执行时间 = 0.173225395s

         系统总执行时间 = 86.264180615s              

=======================================================

        任务优先级 任务栈大小 当前使用栈  最大栈使用   任务名

          Prio     StackSize   CurStack    MaxStack   Taskname

          2         4092        303         459      App Task Start

          5         4092        167         167      App Msp Pro

          4         4092        167         167      App Task UserIF

           5         4092        167         167      App Task COM

           0         1020        191         191      System Timer Thread           

串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。

App Task Start任务  :启动任务,这里用作BSP驱动包处理。

App Task MspPro任务 :消息处理。

App Task UserIF任务 :按键消息处理。

App Task COM任务   :这里用作LED闪烁。

System Timer Thread任务:系统定时器任务

2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

      (2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串口打印信息,如果使用RTT打印信息

(1)   MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

#define Enable_RTTViewer  1

(2)   Embedded Studio继续使用此宏定义为0, 因为Embedded Studio仅制作了调试状态RTT方式查看。

实验操作:

  1. 测试前务必将SD卡插入到开发板左上角的卡座中。
  2. 支持以下6个功能,用户通过电脑端串口软件发送数字1-6给开发板即可
  3. printf("1 - 显示根目录下的文件列表\\r\\n");
  4. printf("2 - 创建一个新文件armfly.txt\\r\\n");
  5. printf("3 - 读armfly.txt文件的内容\\r\\n");
  6. printf("4 - 创建目录\\r\\n");
  7. printf("5 - 删除文件和目录\\r\\n");
  8. printf("6 - 读写文件速度测试\\r\\n");
  9. printf("a - 打开SD卡模拟U盘\\r\\n");
  10. printf("b - 关闭SD卡模拟U盘\\r\\n");

串口打印的信息:

波特率 115200,数据位 8,奇偶校验位无,停止位 1

 

RTT打印:

 

3.6   总结

本章节就为大家讲解这么多,后面章节再为大家详细讲解USBX的玩法。

stm32h7第4章threadxusbx协议栈基础知识

...://www.armbbs.cn/forum.php?mod=viewthread&tid=108546第4章  ThreadXUSBX协议栈基础知识本章节为大家讲解USB基础知识点,学习USB前,非常有必要有个系统的认识。目录4.1  初学者重要提示4.2  USB历史4.3  USB架构4.4  USB硬件4 查看详情

stm32h7第1章threadxusbx初学准备工作

教程更新中:ThreadXUSBX协议栈教程更新记录贴,前5章发布(2021-10-11)-uCOS&uCGUI&emWin&embOS&TouchGFX&ThreadX-硬汉嵌入式论坛-PoweredbyDiscuz!http://www.armbbs.cn/forum.php?mod=viewthread&ti 查看详情

stm32h7第5章threadxusbx各种usb描述符简介

...://www.armbbs.cn/forum.php?mod=viewthread&tid=108546第5章  ThreadXUSBX各种USB描述符简介本章节为大家讲解USB的各种描述符。目录5.1  初学者重要提示5.2  USB描述符概述(USBDescriptors)5.3  USB设备描述符ÿ 查看详情

threadxnetxduo网络协议栈移植到stm32h7

​​​​第6章  ThreadXNetXDUO网络协议栈移植到STM32H7本章教程为大家讲解NetXDUO的移植。6.1初学者重要提示6.2第1步,准备一个工程模板6.3第2步,添加NetXDUO和ETH驱动到工程6.4第3步,初始化文件nx_stm32_eth_driver.c6.5第4步,MPU配... 查看详情

stm32h7教程第90章stm32h7的canfd总线之关键知识点整理

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980第90章      STM32H7的CANFD总线之关键知识点整理CANFD(CANwithflexibledata-rate)是CAN2.0协议的扩展,CAN-FD由博世开发, 查看详情

stm32h7教程第14章stm32h7的电源,复位和时钟系统(代码片段)

...hp?mod=viewthread&tid=86980第14章      STM32H7的电源,复位和时钟系统本章教程继续为大家讲解学习STM32H7的必备知识点电源,复位和时钟系统。掌握这三方面的知识点对后面的学习大有裨益。14.1初学者重要提示... 查看详情

stm32h7教程第89章stm32h7的canfd总线基础之前世今生

...rmbbs.cn/forum.php?mod=viewthread&tid=86980第89章      STM32H7的CANFD总线基础之前世今生本文整理翻译自CANinAutomation(CiA),通过这个帖子大家会对当前市场上各种CAN名词有个全面系统的认识。目录89 查看详情

stm32h7的dsp教程第50章stm32h7的样条插补实现,波形拟合丝滑顺畅(代码片段)

...rmbbs.cn/forum.php?mod=viewthread&tid=94547第50章      STM32H7的样条插补实现,波形拟合丝滑顺畅本章节讲解样条插补,主要用于波形拟合,平滑过渡。目录50.1初学者重要提示50.2样条插补介绍50.3样条插补实现50.3. 查看详情

stm32h7的dsp教程第33章stm32h7不限制点数fft实现(代码片段)

...hp?mod=viewthread&tid=94547第33章      STM32H7不限制点数FFT实现本章主要讲解不限制点数FFT的实现。33.1初学者重要提示33.2不限制点数FFT移植33.3不限制点数FFT应用说明33.4实验例程说明(MDK) 查看详情

stm32h7教程第92章stm32h7的fdcan总线应用之双fdcan实现(支持经典can)(代码片段)

...rmbbs.cn/forum.php?mod=viewthread&tid=86980第92章      STM32H7的FDCAN总线应用之双FDCAN实现(支持经典CAN)本章节为大家讲解STM32H7的带两个FDCAN控制器使用方法。CANFD中的FD含义就是flexibledata& 查看详情

第3版emwin教程第4章emwin上手之stm32h7ltdc基础知识(代码片段)

....cn/forum.php?mod=viewthread&tid=98429第4章  emWin上手之STM32H7LTDC基础知识本章教程为大家讲解LTDC应用中最基本的汉字显示和2D图形显示功能实现。4.1初学者重要提示4.2LCD相关的基础支持4.3LCD硬件设计4.4LCD驱动设计4.5LCD板级支持... 查看详情

stm32h7教程第46章stm32h7的adc应用之dma方式多通道采样(代码片段)

...hp?mod=viewthread&tid=86980第46章      STM32H7的ADC应用之DMA方式多通道采样本章教程为大家讲解ADC+DMA方式的多通道数据采集,实际项目中有一定的使用价值,使用一路ADC就可以采集多个通道的数据。46.1初学者 查看详情

stm32h7教程第91章stm32h7的fdcan总线基础知识和hal库api(代码片段)

...rmbbs.cn/forum.php?mod=viewthread&tid=86980第91章      STM32H7的FDCAN总线基础知识和HAL库API本章节为大家讲解FDCAN的基础知识和对应的HAL库API。CANFD中的FD含义就是flexibledata,灵活数据通信,且波特 查看详情

stm32h7教程第10章stm32h7的flash,ram和栈使用情况(map和htm文件)

...hp?mod=viewthread&tid=86980第10章      STM32H7的FLASH,RAM和栈使用情况(map和htm文件)本章为大家介绍编译器生成的map和htm文件进行解析,通过这两个文件可以让大家对工程代码的认识程度提升一个档次 查看详情

stm32h7教程第93章stm32h7的spi总线应用之驱动ads1256(8通道24bitadc,增益可编程)(代码片段)

完整教程下载地址:【安富莱】STM32H7用户手册发布,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔,更新至94章(2021-11-29)-STM32H7-硬汉嵌入式论坛-PoweredbyDiscuz!第93章      STM32H7的SPI总线应用之驱... 查看详情

stm32h7的dsp教程第31章stm32h7实数浮点fft(支持单精度和双精度)(代码片段)

...hp?mod=viewthread&tid=94547第31章      STM32H7实数浮点FFT(支持单精度和双精度)本章主要讲解实数浮点FTT,支持单精度和双精度。31.1初学者重要提示31.2实数浮点FFT说明31.3单精度函数arm_rfft_ 查看详情

stm32h7教程第60章stm32h7的dac应用之定时器触发实现dma方式双通道波形(代码片段)

...hp?mod=viewthread&tid=86980第60章      STM32H7的DAC应用之定时器触发实现DMA方式双通道波形本章节为大家讲解DAC采用定时器触发方式实现DMA双通道波形输出,实际输出效果也比较好,项目使用价值也比较大。60.1... 查看详情

stm32h7的dsp教程第38章stm32h7的fir高通滤波器实现(支持逐个数据的实时滤波)(代码片段)

...rmbbs.cn/forum.php?mod=viewthread&tid=94547第38章      STM32H7的FIR高通滤波器实现(支持逐个数据的实时滤波)本章节讲解FIR高通滤波器实现。目录38.1初学者重要提示38.2高通滤波器介绍38.3FIR滤波器介绍38.4Matla 查看详情