[DemoCode下载] DSP计算卷积

[复制链接]
1501|19
 楼主| jiekou001 发表于 2022-12-22 16:14 | 显示全部楼层 |阅读模式
新唐很多系列MCU具备DSP内核,可以很方便的进行高级计算。
简介
展示使用 CMSIS DSP 函式库进行卷积运算(Convolution),用户可以直接使用这些函式,来实现自己的数学方程式运算。程序内比较了有无使用 DSP 计算时间的差异,并计算效率提升比率。
原理
9387963a411c450235.png
6509563a411d6445fc.png
2121063a411ea7d7dd.png
 楼主| jiekou001 发表于 2022-12-22 16:15 | 显示全部楼层
  1. /*************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=247401]@brief[/url]    Display how to use DSP Convolution function
  4. *           and compare with calcultion without DSP
  5. *
  6. * @note
  7. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2019 Nuvoton Technology Corp. All rights reserved.
  8. *****************************************************************************/
  9. #include <stdio.h>
  10. #include "NuMicro.h"
  11. #include "arm_math.h"
  12. /*---------------------------------------------------------------------------*/
  13. /* Define                                                                    */
  14. /*---------------------------------------------------------------------------*/
  15. #define PLL_CLOCK    192000000
  16. #define TEST_LENGTH_SAMPLES 320
  17. #define BLOCK_SIZE          32
  18. #define NUM_TAPS            29

  19. extern float32_t testInput_f32_1kHz_15kHz[TEST_LENGTH_SAMPLES];
  20. /*---------------------------------------------------------------------------*/
  21. /* Global variables                                                          */
  22. /*---------------------------------------------------------------------------*/
  23. float32_t firCoeffs32[NUM_TAPS] = {
  24.     -0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f, +0.0085302217f, -0.0000000000f, -0.0173976984f,
  25.         -0.0341458607f, -0.0333591565f, +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f, +0.2229246956f,
  26.         +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f, -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f,
  27.         +0.0080754303f, +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f
  28.     };
  29. float32_t conoutput[400], CONoutput[320], CONLOutput, DSPCalTime, CalTime;
  30. uint32_t numBlocks = TEST_LENGTH_SAMPLES / BLOCK_SIZE, i = 0, j = 0, k = 0;

  31. /*---------------------------------------------------------------------------*/
  32. /* Functions                                                                 */
  33. /*---------------------------------------------------------------------------*/
  34. /* Convolution (length of the first input vector, length of the second input vector) */
  35. void Convolution(int n, int m)
  36. {
  37.     CONLOutput = TEST_LENGTH_SAMPLES + NUM_TAPS - 1;

  38.     for (i = 0; i < CONLOutput; ++i) {
  39.         CONoutput[i] = 0;
  40.     }

  41.     for (i = 0; i < n; ++i) {
  42.         for (j = 0; j < m; ++j) {
  43.             CONoutput[i + j] += testInput_f32_1kHz_15kHz[i] * firCoeffs32[j];
  44.         }
  45.     }
  46. }

  47. void SYS_Init(void)
  48. {
  49.     /*---------------------------------------------------------------------------------------------------------*/
  50.     /* Init System Clock                                                                                       */
  51.     /*---------------------------------------------------------------------------------------------------------*/
  52.     /* Unlock protected registers */
  53.     SYS_UnlockReg();

  54.     /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
  55.     PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

  56.     /* Enable External XTAL (4~24 MHz) */
  57.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  58.     /* Waiting for 12MHz clock ready */
  59.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  60.     /* Set core clock as PLL_CLOCK from PLL */
  61.     CLK_SetCoreClock(PLL_CLOCK);
  62.     /* Set PCLK0/PCLK1 to HCLK/2 */
  63.     CLK->PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2);

  64.     /* Enable UART clock */
  65.     CLK_EnableModuleClock(UART0_MODULE);
  66.     CLK_EnableModuleClock(TMR0_MODULE);

  67.     /* Select UART clock source from HXT */
  68.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
  69.     CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);

  70.     /* Update System Core Clock */
  71.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
  72.     SystemCoreClockUpdate();

  73.     /* Lock protected registers */
  74.     SYS_LockReg();
  75. }
  76. void UART_Init(void)
  77. {
  78.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  79.     SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
  80.     SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  81.     /* Reset UART module */
  82.     SYS_ResetModule(UART0_RST);

  83.     /* Configure UART0 and set UART0 Baudrate */
  84.     UART_Open(UART0, 115200);
  85. }
  86. /*---------------------------------------------------------------------------------------------------------*/
  87. /*  Main Function                                                                                          */
  88. /*---------------------------------------------------------------------------------------------------------*/
  89. int main()
  90. {
  91.     /* Init System, peripheral clock and multi-function I/O */
  92.     SYS_Init();
  93.     /* Init UART for printf */
  94.     UART_Init();

  95.     printf("+-----------------------------------------+\n");
  96.     printf("|       DSP Convolution Sample Code       |\n");
  97.     printf("+-----------------------------------------+\n\n");

  98.     /* Init Timer */
  99.     TIMER_Open(TIMER0, TIMER_CONTINUOUS_MODE, 1);
  100.     /* Let TIMER0 start to count */
  101.     TIMER_Start(TIMER0);

  102.     /* Calculate convoltion with M4 DSP instruction */
  103.     arm_conv_f32(testInput_f32_1kHz_15kHz, TEST_LENGTH_SAMPLES, firCoeffs32, NUM_TAPS, conoutput);

  104.     /* Read Timer counter */
  105.     DSPCalTime = TIMER_GetCounter(TIMER0);
  106.     /* Reset Timer counter */
  107.     TIMER_ResetCounter(TIMER0);

  108.     /* Calculate convoltion */
  109.     Convolution(TEST_LENGTH_SAMPLES, NUM_TAPS);

  110.     TIMER_Close(TIMER0);
  111.     /* Read Timer counter */
  112.     CalTime = TIMER_GetCounter(TIMER0);

  113.     /* Calculate the time, timer clock source is 12M, unit is ms */
  114.     DSPCalTime = (DSPCalTime / 12000000) * 1000;
  115.     CalTime = (CalTime / 12000000) * 1000;

  116.     printf("Calculating time with DSP instruction is %f ms\n\n", DSPCalTime);
  117.     printf("Calculating time without DSP instruction is %f ms\n\n", CalTime);
  118.     printf("Efficiency increase rate is %.2f \n", CalTime / DSPCalTime);

  119.     while (1);

  120. }

wahahaheihei 发表于 2022-12-29 11:04 | 显示全部楼层
卷积通常用于什么?
twjiang 发表于 2022-12-29 11:21 | 显示全部楼层
本帖最后由 twjiang 于 2023-1-5 20:27 编辑

控制论 (the theorem of control),
insignal: t -> x(t)

outsignal: t -> y(t)


星辰大海不退缩 发表于 2022-12-29 12:54 | 显示全部楼层
信号的处理上用过卷积
tpgf 发表于 2023-1-5 15:02 | 显示全部楼层
卷积、旋积或摺积(英语:Convolution)是通过两个函数f 和g 生成第三个函数的一种数学算子,表征函数f 与g经过翻转和平移的重叠部分的面积
xiaoqizi 发表于 2023-1-5 15:18 | 显示全部楼层
如果将参加卷积的一个函数看作区间的指示函数,卷积还可以被看作是"滑动平均"的推广。
木木guainv 发表于 2023-1-5 15:28 | 显示全部楼层
卷积是两个变量在某范围内相乘后求和的结果。
renzheshengui 发表于 2023-1-5 15:38 | 显示全部楼层
卷积定理指出,函数卷积的傅里叶变换是函数傅里叶变换的乘积。即,一个域中的卷积相当于另一个域中的乘积,例如时域中的卷积就对应于频域中的乘积。
zljiu 发表于 2023-1-5 15:48 | 显示全部楼层
利用卷积定理可以简化卷积的运算量。对于长度为n的序列,按照卷积的定义进行计算,需要做2n- 1组对位乘法,其计算复杂度为;而利用傅里叶变换将序列变换到频域上后,只需要一组对位乘法,利用傅里叶变换的快速算法之后,总的计算复杂度为。这一结果可以在快速乘法计算中得到应用。
nawu 发表于 2023-1-5 15:58 | 显示全部楼层
统计学中,加权的滑动平均是一种卷积。概率论中,两个统计独立变量X与Y的和的概率密度函数是X与Y的概率密度函数的卷积。声学中,回声可以用源声与一个反映各种反射效应的函数的卷积表示。电子工程与信号处理中,任一个线性系统的输出都可以通过将输入信号与系统函数(系统的冲激响应)做卷积获得。物理学中,任何一个线性系统(符合叠加原理)都存在卷积。
chenjun89 发表于 2023-1-6 08:25 来自手机 | 显示全部楼层
在数字信号处理中应用较广
twjiang 发表于 2023-1-11 15:45 | 显示全部楼层
本帖最后由 twjiang 于 2023-1-11 16:12 编辑

对 两个函数 f * g 的 卷积 进行 傅里叶变换,就变成了 F(g) x F(g) 两个傅里叶变换的积,道理大家都懂。

卷积的定义长成这样子,其中的由来有谁能讲清楚吗?
就像 勾股定理 a^2 + b^2 = c^2

一个学到长方形的人说:长方形的长的平方 + 长方形的宽的平方 = 长方形的斜边的平方
一个学到正方形的人说:正方形的.....
一个学到三角函数的人说:sin(a)^2 + cos(a)^2 = 1

但是没有一个人站出来解释 a^2 + b^2 = 1 是怎么来的?
OKAKAKO 发表于 2023-1-11 16:56 来自手机 | 显示全部楼层
线性卷积和圆卷积
中国龙芯CDX 发表于 2023-1-12 12:29 | 显示全部楼层
卷积看来要学习的东西还很多,尤其是在数学方面的基础还是很重要的
小夏天的大西瓜 发表于 2023-1-12 13:34 | 显示全部楼层
卷积学习一下,新手没有应用这个卷积定理
 楼主| jiekou001 发表于 2023-1-12 14:34 | 显示全部楼层
小夏天的大西瓜 发表于 2023-1-12 13:34
卷积学习一下,新手没有应用这个卷积定理

高等数学上的概念。
小夏天的大西瓜 发表于 2023-1-12 15:24 | 显示全部楼层
jiekou001 发表于 2023-1-12 14:34
高等数学上的概念。

嗯嗯,概念我知道,但是在实际中没有用到过这个定理,高数都还的老师了
szt1993 发表于 2023-1-12 20:30 | 显示全部楼层
小夏天的大西瓜 发表于 2023-1-12 15:24
嗯嗯,概念我知道,但是在实际中没有用到过这个定理,高数都还的老师了 ...

其实如果做相关领域算法的话可能还能用到高数等,如果不从事相关的开发确实,时间长了就生疏了
AdaMaYun 发表于 2023-1-13 13:00 | 显示全部楼层
楼主,卷积通常用于什么行业领域,进行那些领域的开发,方便给举个例子嘛
您需要登录后才可以回帖 登录 | 注册

本版积分规则

147

主题

1539

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部