[学习笔记]ARM_DSP库——基础函数(相反数、偏移、移位、减法、比例因子)

本文详细介绍了ARM_DSP库中的基础数学运算函数,包括求相反数、偏移、移位、减法和比例因子计算。针对32位浮点数、32位定点数、16位定点数和8位定点数,提供了对应的函数实现。通过实例展示了每个函数的使用方法,有助于理解和应用这些基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ARM_DSP库——基础函数

相反数、偏移、移位、减法、比例因子

一、相反数(Vector Negate)

这部分函数主要用于求相反数,公式描述如下:

pDst[n] = -pSrc[n],   0 <= n < blockSize;

特别注意,这部分函数支持目标指针和源指针指向相同的缓冲区。

函数arm_negate_f32

用于求32位浮点数的相反数。

函数arm_negate_q31

用于求32位定点数的相反数。

函数arm_negate_q15

用于求16位定点数的相反数。

函数arm_negate_q7

用于求8位定点数的相反数。

  • 函数参数:
    • 第 1 个参数是源数据地址。
    • 第 2 个参数是求相反数后目的数据地址。
    • 第 3 个参数转换的数据个数,这里是指的浮点数或定点数个数。

使用举例

#define log_i printf
void DSP_Negate(void)
{
	float32_t pSrc = 0.0f;
	float32_t pDst;

	q31_t pSrc1 = 0;
	q31_t pDst1;

	q15_t pSrc2 = 0;
	q15_t pDst2;

	q7_t pSrc3 = 0;
	q7_t pDst3;

	/* 求相反数 */
	pSrc -= 1.23f;
	arm_negate_f32(&pSrc, &pDst, 1);
	log_i("arm_negate_f32 = %f\r\n", pDst);

	pSrc1 -= 1;
	arm_negate_q31(&pSrc1, &pDst1, 1);
	log_i("arm_negate_q31 = %d\r\n", pDst1);

	pSrc2 -= 1;
	arm_negate_q15(&pSrc2, &pDst2, 1);
	log_i("arm_negate_q15 = %d\r\n", pDst2);

	pSrc3 += 1;
	arm_negate_q7(&pSrc3, &pDst3, 1);
	log_i("arm_negate_q7 = %d\r\n", pDst3);
	log_i("*****************\r\n");
}

二、偏移(Vector Offset)

这部分函数主要用于求偏移,公式描述如下:

pDst[n] = pSrc[n] + offset,   0 <= n < blockSize;

这部分函数支持目标指针和源指针指向相同的缓冲区。

函数arm_offset_f32

用于求两个 32 位浮点数的偏移。

函数 arm_offset_q31

用于求两个32位定点数的偏移。

函数 arm_offset_q15

用于求两个 16 位定点数的偏移。

函数 arm_offset_q7

用于求两个 8 位定点数的偏移。

  • 函数参数:
    • 第 1 个参数是源数据地址。
    • 第 2 个参数是偏移量。
    • 第 3 个参数是转换后的目的地址。
    • 第 4 个参数是浮点数或定点数个数,其实就是执行偏移的次数。

使用举例

#define log_i printf
void DSP_Offset(void)
{
	float32_t pSrcA = 0.0f;
	float32_t Offset = 0.0f;
	float32_t pDst;

	q31_t pSrcA1 = 0;
	q31_t Offset1 = 0;
	q31_t pDst1;

	q15_t pSrcA2 = 0;
	q15_t Offset2 = 0;
	q15_t pDst2;

	q7_t pSrcA3 = 0;
	q7_t Offset3 = 0;
	q7_t pDst3;

	/* 求偏移 */
	Offset--;
	arm_offset_f32(&pSrcA, Offset, &pDst, 1);
	log_i("arm_offset_f32 = %f\r\n", pDst);

	Offset1--;
	arm_offset_q31(&pSrcA1, Offset1, &pDst1, 1);
	log_i("arm_offset_q31 = %d\r\n", pDst1);

	Offset2--;
	arm_offset_q15(&pSrcA2, Offset2, &pDst2, 1);
	log_i("arm_offset_q15 = %d\r\n", pDst2);

	Offset3--;
	arm_offset_q7(&pSrcA3, Offset3, &pDst3, 1);
	log_i("arm_offset_q7 = %d\r\n", pDst3);
	log_i("*******************\r\n");
}

三、移位(Vector Shift)

这部分函数主要用于实现移位,公式描述如下:

pDst[n] = pSrc[n] << shift,   0 <= n < blockSize;

这部分函数支持目标指针和源指针指向相同的缓冲区。

函数 arm_shift_q31

用于求32位定点数的左移或者右移。

函数 arm_shift_q15

用于求16位定点数的左移或者右移。

函数 arm_shift_q7

用于求8位定点数的左移或者右移。

  • 函数参数:
    • 第 1 个参数是源数据地址。
    • 第 2 个参数是左移或者右移位数,正数是左移,负数是右移。
    • 第 3 个参数是移位后数据地址。
    • 第 4 个参数是定点数个数,其实就是执行左移或者右移的次数。

使用举例

void DSP_Shift(void)
{
	q31_t pSrcA1 = 0x88886666;
	q31_t pDst1;

	q15_t pSrcA2 = 0x8866;
	q15_t pDst2;

	q7_t pSrcA3 = 0x86;
	q7_t pDst3;


	/* 求移位 */
	arm_shift_q31(&pSrcA1, 3, &pDst1, 1);
	log_i("arm_shift_q31 = %8x\r\n", pDst1);

	arm_shift_q15(&pSrcA2, -3, &pDst2, 1);
	log_i("arm_shift_q15 = %4x\r\n", pDst2);

	arm_shift_q7(&pSrcA3, 3, &pDst3, 1);
	log_i("arm_shift_q7 = %2x\r\n", pDst3);
	log_i("******************\r\n");
}

四、减法(Vector Sub)

这部分函数主要用于实现减法,公式描述如下:

pDst[n] = pSrcA[n] - pSrcB[n],   0 <= n < blockSize;

函数 arm_sub_f32

用于求32位浮点数的减法。

函数 arm_sub_q31

用于求32位定点数的减法。

函数 arm_sub_q15

用于求16位定点数的减法。

函数 arm_sub_q7

用于求8位定点数的减法。

  • 函数参数:
    • 第 1 个参数是减数地址。
    • 第 2 个参数是被减数地址。
    • 第 3 个参数是结果地址。
    • 第 4 个参数是数据块大小,其实就是执行减法的次数。

使用举例

void DSP_Sub(void)
{
	float32_t   pSrcA[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
	float32_t   pSrcB[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
	float32_t   pDst[5];

	q31_t  pSrcA1[5] = {1,1,1,1,1};
	q31_t  pSrcB1[5] = {1,1,1,1,1};
	q31_t  pDst1[5];

	q15_t  pSrcA2[5] = {1,1,1,1,1};
	q15_t  pSrcB2[5] = {1,1,1,1,1};
	q15_t  pDst2[5];

	q7_t  pSrcA3[5] = {0x70,1,1,1,1};
	q7_t  pSrcB3[5] = {0x7f,1,1,1,1};
	q7_t  pDst3[5];


	/* 求减法 */
	pSrcA[0] += 1.1f;
	arm_sub_f32(pSrcA, pSrcB, pDst, 5);
	log_i("arm_sub_f32 = %f\r\n", pDst[0]);

	pSrcA1[0] += 1;
	arm_sub_q31(pSrcA1, pSrcB1, pDst1, 5);
	log_i("arm_sub_q31 = %d\r\n", pDst1[0]);

	pSrcA2[0] += 1;
	arm_sub_q15(pSrcA2, pSrcB2, pDst2, 5);
	log_i("arm_sub_q15 = %d\r\n", pDst2[0]);

	pSrcA3[0] += 1;
	arm_sub_q7(pSrcA3, pSrcB3, pDst3, 5);
	log_i("arm_sub_q7 = %d\r\n", pDst3[0]);
	log_i("*******************\r\n");
}

五、比例因子(Vector Scale)

这部分函数主要用于实现数据的比例放大和缩小,浮点数据公式描述如下:

pDst[n] = pSrc[n] * scale,   0 <= n < blockSize

如果是 Q31,Q15,Q7 格式的数据,公式描述如下:

pDst[n] = (pSrc[n] * scaleFract) << shift,   0 <= n < blockSize

这种情况下,比例因子就是:

scale = scaleFract * 2^shift

这部分函数支持目标指针和源指针指向相同的缓冲区

函数 arm_scale_f32

用于求32位浮点数的比例因子计算。

函数 arm_scale_q31

用于求32位定点数的比例因子计算。

函数 arm_scale_q15

用于求16位定点数的比例因子计算。

函数 arm_scale_q7

用于求8位定点数的比例因子计算。

  • 函数参数:
    • 第 1 个参数是数据源地址。
    • 第 2 个参数是比例因子
    • 第 3 个参数是结果地址。
    • 第 4 个参数是数据块大小,其实就是执行比例因子计算的次数。

使用举例

void DSP_Scale(void)
{
	float32_t   pSrcA[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
	float32_t   scale = 0.0f;
	float32_t   pDst[5];

	q31_t  pSrcA1[5] = {0x6fffffff,1,1,1,1};
	q31_t  scale1 = 0x6fffffff;
	q31_t  pDst1[5];

	q15_t  pSrcA2[5] = {0x6fff,1,1,1,1};
	q15_t  scale2 = 0x6fff;
	q15_t  pDst2[5];

	q7_t  pSrcA3[5] = {0x70,1,1,1,1};
	q7_t  scale3 = 0x6f;
	q7_t pDst3[5];

	/* 求比例因子计算 */
	scale += 0.1f;
	arm_scale_f32(pSrcA, scale, pDst, 5);
	printf("arm_scale_f32 = %f\r\n", pDst[0]);

	scale1 += 1;
	arm_scale_q31(pSrcA1, scale1, 0, pDst1, 5);
	printf("arm_scale_q31 = %x\r\n", pDst1[0]);

	scale2 += 1;
	arm_scale_q15(pSrcA2, scale2, 0, pDst2, 5);
	printf("arm_scale_q15 = %x\r\n", pDst2[0]);

	scale3 += 1;
	arm_scale_q7(pSrcA3, scale3, 0, pDst3, 5);
	printf("arm_scale_q7 = %x\r\n", pDst3[0]);
	printf("*******************\r\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值