应用上如果只用到DSP做协处理器做数**算时,应避免在多个中断中同时调用DSP进行计算,如果有这方面的需求,可以使用1个全局变量和1个局部变量做状态判断,计算被打断后重新计算即可。
参考配置及头文件见附件
参考配置入下
- /*******************************************************************************
- * 版权所有 (C)2015, LINKO SEMICONDUCTOR Co.ltd
- *
- * 文件名称: lks32mc08x_dsp.c
- * 文件标识:
- * 内容摘要: DSP协处理器模式驱动程序
- * 其它说明: 无
- * 当前版本: V 1.0
- * 作 者: YangZJ
- * 完成日期: 2022年3月10日
- *
- * 修改记录1:
- * 修改日期:2022年3月10日
- * 版 本 号:V 1.0
- * 修 改 人:YangZJ
- * 修改内容:创建
- *
- *******************************************************************************/
- #include "lks32mc08x.h"
- #include "lks32mc08x_sys.h"
- static volatile u8 dsp_**; // 标志位,用于判断程序是否被打断
- /*******************************************************************************
- 函数名称: s16 lks08x_dsp_sin(u16 val)
- 功能描述: 使用08x的DSP计算正弦
- 输入参数: u16 val 角度0-65535对应0-360度
- 返 回 值: s16 result 计算结果Q15格式
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- s16 lks08x_dsp_sin(u16 val)
- {
- s16 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_SC = BIT2 | BIT1;
- DSP_CORDIC_THETA = val;
- result = DSP_CORDIC_SIN;
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: s16 lks08x_dsp_cos(u16 val)
- 功能描述: 使用08x的DSP计算余弦
- 输入参数: u16 val 角度0-65535对应0-360度
- 返 回 值: s16 result 计算结果Q15格式
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- s16 lks08x_dsp_cos(u16 val)
- {
- s16 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_SC = BIT2 | BIT1;
- DSP_CORDIC_THETA = val;
- result = DSP_CORDIC_COS;
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: u16 lks08x_dsp_rms(s16 a,s16 b)
- 功能描述: 使用08x的DSP计算均方根
- 输入参数: s16 a,b
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- u16 lks08x_dsp_rms(s16 a, s16 b)
- {
- u16 c;
- u16 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- //先触发计算
- //在计算的过程中判断数据是否可能溢出
- a = (a > 0) ? a : -a;
- b = (b > 0) ? b : -b;
- c = a + b;
- SYS_SoftResetModule(SYS_Module_DSP);
- if (c > 32767) // 当数据可能溢出的时候降低1位精度并重新开始计算
- {
- DSP_CORDIC_X = a >> 1;
- DSP_CORDIC_Y = b >> 1;
- result = (u16)DSP_CORDIC_MOD;
- result <<= 1;
- }
- else // 正常计算
- {
- DSP_CORDIC_X = a;
- DSP_CORDIC_Y = b;
- result = (u16)DSP_CORDIC_MOD;
- }
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: u16 lks08x_dsp_arctan(s16 x,s16 y)
- 功能描述: 使用08x的DSP计算反正切
- 输入参数: s16 x,y
- 返 回 值: 计算结果 角度0-65535对应0-360度
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- u16 lks08x_dsp_arctan(s16 x, s16 y)
- {
- u16 a;
- u8 i;
- u16 result = 0;
- u8 dsp_**_old;
- a = (x > 0) ? x : -x;
- a = (y > 0) ? a + y : a - y;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- for (i = 0; i < 16; i++)
- {
- if ((a & (0x8000 >> i)) != 0)
- {
- if (i == 0)
- {
- // 08x的DSP在计算角度时必须保证(x*x+y*y)<32767
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_CORDIC_X = x >> 1;
- DSP_CORDIC_Y = y >> 1;
- }
- else
- {
- // 08x的DSP在计算atan时为提高精度,应尽可能的放到X和Y的幅值
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_CORDIC_X = x << (i - 1);
- DSP_CORDIC_Y = y << (i - 1);
- }
- result = DSP_CORDIC_ARCTAN;
- break;
- }
- }
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: s32 lks08x_dsp_div(s32 a,s16 b)
- 功能描述: 使用08x的DSP计算除法
- 输入参数: s32 a 被除数
- s16 b 除数
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- s32 lks08x_dsp_div(s32 a, s16 b)
- {
- s32 c;
- s32 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_DID = a;
- DSP_DIS = b;
- if (b == (s16)0x8000)
- {
- c = -a - 1;
- result = (c >> 15) + 1;
- }
- else if (b == 0)
- {
- result = 0;
- }
- else
- {
- if (a != (s16)0x80000000)
- {
- result = DSP_QUO;
- }
- else
- {
- a >>= 1;
- DSP_DID = a;
- DSP_DIS = b;
- result = DSP_QUO << 1;
- }
- }
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: s32 lks08x_dsp_mod(s32 a,s16 b)
- 功能描述: 使用08x的DSP求模
- 输入参数: s32 a 被除数
- s16 b 除数
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- s32 lks08x_dsp_mod(s32 a, s16 b)
- {
- s32 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_DID = a;
- DSP_DIS = b;
- if (b == 0)
- {
- result = a;
- }
- else
- {
- result = DSP_REM;
- }
- } while (dsp_**_old != dsp_**);
- return result;
- }
- /*******************************************************************************
- 函数名称: u16 lks08x_dsp_sqrt(u32 val)
- 功能描述: 使用08x的DSP开平凡
- 输入参数: u32 val 被开方数
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -----------------------------------------------------------------------------
- 2022.03.10 V1.0 YangZJ 创建
- *******************************************************************************/
- u16 lks08x_dsp_sqrt(u32 val)
- {
- u16 result;
- u8 dsp_**_old;
- do
- {
- dsp_**++;
- dsp_**_old = dsp_**;
- SYS_SoftResetModule(SYS_Module_DSP);
- DSP_RAD = val;
- result = DSP_SQRT;
- } while (dsp_**_old != dsp_**);
- return result;
- }
|