应用上如果只用到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;
}
|