06.01_DSP-除法
测试步骤
使用硬件dsp进行除法计算
实测数据
实测数据
| a | b | DSP_Div(a, b) | DSP_Mod(a, b) | div err | mod err |
|---|---|---|---|---|---|
| -2147483648 (0x80000000) | -2147483648 (0x80000000) | 1 | 0 | 0 | 0 |
| -2147483648 (0x80000000) | -100000000 (0xfa0a1f00) | 21 | -47483648 | 0 | 0 |
| -2147483648 (0x80000000) | -32768 (0xffff8000) | 65536 | 0 | 0 | 0 |
| -2147483648 (0x80000000) | -10000 (0xffffd8f0) | 214748 | -3648 | 0 | 0 |
| -2147483648 (0x80000000) | -1 (0xffffffff) | 2147483647 | 0 | -1 | 0 |
| -2147483648 (0x80000000) | 0 (0x00000000) | 0 | -2147483648 | 0 | 0 |
| -2147483648 (0x80000000) | 1 (0x00000001) | -2147483648 | 0 | 0 | 0 |
| -2147483648 (0x80000000) | 10000 (0x00002710) | -214748 | -3648 | 0 | 0 |
| -2147483648 (0x80000000) | 32767 (0x00007fff) | -65538 | -2 | 0 | 0 |
| -2147483648 (0x80000000) | 100000000 (0x05f5e100) | -21 | -47483648 | 0 | 0 |
| -2147483648 (0x80000000) | 2147483647 (0x7fffffff) | -1 | -1 | 0 | 0 |
| -100000000 (0xfa0a1f00) | -2147483648 (0x80000000) | 0 | -100000000 | 0 | 0 |
| -100000000 (0xfa0a1f00) | -100000000 (0xfa0a1f00) | 1 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | -32768 (0xffff8000) | 3051 | -24832 | 0 | 0 |
| -100000000 (0xfa0a1f00) | -10000 (0xffffd8f0) | 10000 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | -1 (0xffffffff) | 100000000 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 0 (0x00000000) | 0 | -100000000 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 1 (0x00000001) | -100000000 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 10000 (0x00002710) | -10000 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 32767 (0x00007fff) | -3051 | -27883 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 100000000 (0x05f5e100) | -1 | 0 | 0 | 0 |
| -100000000 (0xfa0a1f00) | 2147483647 (0x7fffffff) | 0 | -100000000 | 0 | 0 |
| -32768 (0xffff8000) | -2147483648 (0x80000000) | 0 | -32768 | 0 | 0 |
| -32768 (0xffff8000) | -100000000 (0xfa0a1f00) | 0 | -32768 | 0 | 0 |
| -32768 (0xffff8000) | -32768 (0xffff8000) | 1 | 0 | 0 | 0 |
| -32768 (0xffff8000) | -10000 (0xffffd8f0) | 3 | -2768 | 0 | 0 |
| -32768 (0xffff8000) | -1 (0xffffffff) | 32768 | 0 | 0 | 0 |
| -32768 (0xffff8000) | 0 (0x00000000) | 0 | -32768 | 0 | 0 |
| -32768 (0xffff8000) | 1 (0x00000001) | -32768 | 0 | 0 | 0 |
| -32768 (0xffff8000) | 10000 (0x00002710) | -3 | -2768 | 0 | 0 |
| -32768 (0xffff8000) | 32767 (0x00007fff) | -1 | -1 | 0 | 0 |
| -32768 (0xffff8000) | 100000000 (0x05f5e100) | 0 | -32768 | 0 | 0 |
| -32768 (0xffff8000) | 2147483647 (0x7fffffff) | 0 | -32768 | 0 | 0 |
| -10000 (0xffffd8f0) | -2147483648 (0x80000000) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | -100000000 (0xfa0a1f00) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | -32768 (0xffff8000) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | -10000 (0xffffd8f0) | 1 | 0 | 0 | 0 |
| -10000 (0xffffd8f0) | -1 (0xffffffff) | 10000 | 0 | 0 | 0 |
| -10000 (0xffffd8f0) | 0 (0x00000000) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | 1 (0x00000001) | -10000 | 0 | 0 | 0 |
| -10000 (0xffffd8f0) | 10000 (0x00002710) | -1 | 0 | 0 | 0 |
| -10000 (0xffffd8f0) | 32767 (0x00007fff) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | 100000000 (0x05f5e100) | 0 | -10000 | 0 | 0 |
| -10000 (0xffffd8f0) | 2147483647 (0x7fffffff) | 0 | -10000 | 0 | 0 |
| -1 (0xffffffff) | -2147483648 (0x80000000) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | -100000000 (0xfa0a1f00) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | -32768 (0xffff8000) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | -10000 (0xffffd8f0) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | -1 (0xffffffff) | 1 | 0 | 0 | 0 |
| -1 (0xffffffff) | 0 (0x00000000) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | 1 (0x00000001) | -1 | 0 | 0 | 0 |
| -1 (0xffffffff) | 10000 (0x00002710) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | 32767 (0x00007fff) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | 100000000 (0x05f5e100) | 0 | -1 | 0 | 0 |
| -1 (0xffffffff) | 2147483647 (0x7fffffff) | 0 | -1 | 0 | 0 |
| 0 (0x00000000) | -2147483648 (0x80000000) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | -100000000 (0xfa0a1f00) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | -32768 (0xffff8000) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | -10000 (0xffffd8f0) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | -1 (0xffffffff) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 0 (0x00000000) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 1 (0x00000001) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 10000 (0x00002710) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 32767 (0x00007fff) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 100000000 (0x05f5e100) | 0 | 0 | 0 | 0 |
| 0 (0x00000000) | 2147483647 (0x7fffffff) | 0 | 0 | 0 | 0 |
| 1 (0x00000001) | -2147483648 (0x80000000) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | -100000000 (0xfa0a1f00) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | -32768 (0xffff8000) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | -10000 (0xffffd8f0) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | -1 (0xffffffff) | -1 | 0 | 0 | 0 |
| 1 (0x00000001) | 0 (0x00000000) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | 1 (0x00000001) | 1 | 0 | 0 | 0 |
| 1 (0x00000001) | 10000 (0x00002710) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | 32767 (0x00007fff) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | 100000000 (0x05f5e100) | 0 | 1 | 0 | 0 |
| 1 (0x00000001) | 2147483647 (0x7fffffff) | 0 | 1 | 0 | 0 |
| 10000 (0x00002710) | -2147483648 (0x80000000) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | -100000000 (0xfa0a1f00) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | -32768 (0xffff8000) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | -10000 (0xffffd8f0) | -1 | 0 | 0 | 0 |
| 10000 (0x00002710) | -1 (0xffffffff) | -10000 | 0 | 0 | 0 |
| 10000 (0x00002710) | 0 (0x00000000) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | 1 (0x00000001) | 10000 | 0 | 0 | 0 |
| 10000 (0x00002710) | 10000 (0x00002710) | 1 | 0 | 0 | 0 |
| 10000 (0x00002710) | 32767 (0x00007fff) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | 100000000 (0x05f5e100) | 0 | 10000 | 0 | 0 |
| 10000 (0x00002710) | 2147483647 (0x7fffffff) | 0 | 10000 | 0 | 0 |
| 32767 (0x00007fff) | -2147483648 (0x80000000) | 0 | 32767 | 0 | 0 |
| 32767 (0x00007fff) | -100000000 (0xfa0a1f00) | 0 | 32767 | 0 | 0 |
| 32767 (0x00007fff) | -32768 (0xffff8000) | 0 | 32767 | 0 | 0 |
| 32767 (0x00007fff) | -10000 (0xffffd8f0) | -3 | 2767 | 0 | 0 |
| 32767 (0x00007fff) | -1 (0xffffffff) | -32767 | 0 | 0 | 0 |
| 32767 (0x00007fff) | 0 (0x00000000) | 0 | 32767 | 0 | 0 |
| 32767 (0x00007fff) | 1 (0x00000001) | 32767 | 0 | 0 | 0 |
| 32767 (0x00007fff) | 10000 (0x00002710) | 3 | 2767 | 0 | 0 |
| 32767 (0x00007fff) | 32767 (0x00007fff) | 1 | 0 | 0 | 0 |
| 32767 (0x00007fff) | 100000000 (0x05f5e100) | 0 | 32767 | 0 | 0 |
| 32767 (0x00007fff) | 2147483647 (0x7fffffff) | 0 | 32767 | 0 | 0 |
| 100000000 (0x05f5e100) | -2147483648 (0x80000000) | 0 | 100000000 | 0 | 0 |
| 100000000 (0x05f5e100) | -100000000 (0xfa0a1f00) | -1 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | -32768 (0xffff8000) | -3051 | 24832 | 0 | 0 |
| 100000000 (0x05f5e100) | -10000 (0xffffd8f0) | -10000 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | -1 (0xffffffff) | -100000000 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | 0 (0x00000000) | 0 | 100000000 | 0 | 0 |
| 100000000 (0x05f5e100) | 1 (0x00000001) | 100000000 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | 10000 (0x00002710) | 10000 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | 32767 (0x00007fff) | 3051 | 27883 | 0 | 0 |
| 100000000 (0x05f5e100) | 100000000 (0x05f5e100) | 1 | 0 | 0 | 0 |
| 100000000 (0x05f5e100) | 2147483647 (0x7fffffff) | 0 | 100000000 | 0 | 0 |
| 2147483647 (0x7fffffff) | -2147483648 (0x80000000) | 0 | 2147483647 | 0 | 0 |
| 2147483647 (0x7fffffff) | -100000000 (0xfa0a1f00) | -21 | 47483647 | 0 | 0 |
| 2147483647 (0x7fffffff) | -32768 (0xffff8000) | -65535 | 32767 | 0 | 0 |
| 2147483647 (0x7fffffff) | -10000 (0xffffd8f0) | -214748 | 3647 | 0 | 0 |
| 2147483647 (0x7fffffff) | -1 (0xffffffff) | -2147483647 | 0 | 0 | 0 |
| 2147483647 (0x7fffffff) | 0 (0x00000000) | 0 | 2147483647 | 0 | 0 |
| 2147483647 (0x7fffffff) | 1 (0x00000001) | 2147483647 | 0 | 0 | 0 |
| 2147483647 (0x7fffffff) | 10000 (0x00002710) | 214748 | 3647 | 0 | 0 |
| 2147483647 (0x7fffffff) | 32767 (0x00007fff) | 65538 | 1 | 0 | 0 |
| 2147483647 (0x7fffffff) | 100000000 (0x05f5e100) | 21 | 47483647 | 0 | 0 |
| 2147483647 (0x7fffffff) | 2147483647 (0x7fffffff) | 1 | 0 | 0 | 0 |
DSP_Div用时统计
time = 131
参考代码
06.01_DSP_Div.c
/**
* @brief DSP-除法
* @details 使用硬件dsp进行除法计算
*/
#include "lks32mc09x_dsp.h"
#include "lks32mc09x_timer.h"
volatile int a = 10000;
volatile int b = 100;
volatile int y;
volatile int mod;
volatile int time;
void Timer0_Init(void);
/**
* @brief 主函数,用于测试HSI时钟输出及GPIO翻转
*/
int main(void)
{
DSP_Init();
Timer0_Init();
while (1)
{
TIMER_StatisticsStart(TIMER0);
y = DSP_Div(a, b);
time = TIMER_StatisticsStop(TIMER0);
mod = DSP_Mod(a, b);
}
}
/**
* @brief 配置定时器0,用来统计除法执行时间
*/
void Timer0_Init(void)
{
TIMER_TimerInitTypeDef TIMER_InitStruct;
TIMER_StructInit(&TIMER_InitStruct);
TIMER_InitStruct.EN = 1;
TIMER_InitStruct.TH = 0xffff;
TIMER_Init(TIMER0, &TIMER_InitStruct);
TIMER_Enable(TIMER0);
}
使用到的库函数
库函数部分代码
#define REG_RESET(reg,mask) reg &= ~(mask)
#define REG_SET(reg,mask) reg |= (mask)
#define REG_WRITE(reg,mask) reg = (mask)
#define SYS0 ((SYS_TypeDef *)(SYS_BASE))
#define SYS_MODULE_DSP0 BIT17
#define SYS_MODULE_TIMER0 BIT4
#define SYS_MODULE_TIMER1 BIT5
#define SYS_MODULE_TIMER2 BIT6
#define TIMER0 ((TIMER_TypeDef *)TIMER0_BASE)
#define TIMER1 ((TIMER_TypeDef *)TIMER1_BASE)
#define TIMER2 ((TIMER_TypeDef *)TIMER2_BASE)
/**
* @brief Timer初始化结构体
*/
typedef struct TIMER_TimerInitTypeDef {
uint8_t EN;
uint32_t CAP1_CLR_EN;
uint32_t CAP0_CLR_EN;
uint32_t ONE_TRIG;
uint32_t CENTER;
uint32_t DIR;
uint32_t ClockDiv;
uint32_t ETON;
uint32_t GATE_EN;
uint32_t RL_EN;
uint32_t XCLK_EN;
uint32_t SRC1;
uint32_t CH1Output;
uint32_t CH1_WorkMode;
uint32_t CH1_FE_CAP_EN;
uint32_t CH1_RE_CAP_EN;
uint32_t SRC0;
uint32_t CH0Output;
uint32_t CH0_WorkMode;
uint32_t CH0_FE_CAP_EN;
uint32_t CH0_RE_CAP_EN;
uint32_t TH;
uint32_t CNT;
uint32_t CHN0;
uint32_t CHN1;
uint32_t EVT;
uint32_t FLT;
uint32_t IE;
uint32_t CMP0_TRIGGER_MODE;
uint32_t CMP1_TRIGGER_MODE;
uint32_t SHADOW;
uint32_t CH1_DEFAULT;
uint32_t CH0_DEFAULT;
uint32_t HALT_PRT;
uint32_t FAIL_SEL;
uint32_t FAIL_POL;
uint32_t FAIL_EN;
uint32_t MOE;
};
/**
* @brief Timer初始化
* @param TIMERx Timer实例指针
* @param TIMER_InitStruct Timer初始化结构体指针
*/
void TIMER_Init(TIMER_TypeDef *TIMERx, TIMER_TimerInitTypeDef *TIMER_InitStruct)
{
uint32_t th = TIMER_InitStruct->TH;
TIMER_Enable(TIMERx);
if (TIMERx != TIMER2) // 只有timer2是32位定时器
{
if (th > 0xffff)
{
th = 0xffff;
}
else
{
__NOP();
}
}
else
{
__NOP();
}
// 配置Timer寄存器
TIMERx->CFG2 = (TIMER_InitStruct->EN << 15) |
(TIMER_InitStruct->ONE_TRIG << 9) |
(TIMER_InitStruct->CENTER << 8) |
(TIMER_InitStruct->DIR << 6) |
(TIMER_InitStruct->ClockDiv << 4) |
(TIMER_InitStruct->ETON << 3) |
(TIMER_InitStruct->GATE_EN << 2) |
(TIMER_InitStruct->RL_EN << 1) |
TIMER_InitStruct->XCLK_EN;
TIMERx->CFG0 = (TIMER_InitStruct->CMP0_TRIGGER_MODE << 9) |
(TIMER_InitStruct->CAP0_CLR_EN << 8) |
(TIMER_InitStruct->SRC0 << 4) |
(TIMER_InitStruct->CH0Output << 3) |
(TIMER_InitStruct->CH0_WorkMode << 2) |
(TIMER_InitStruct->CH0_FE_CAP_EN << 1) |
(TIMER_InitStruct->CH0_RE_CAP_EN << 0);
TIMERx->CFG1 = (TIMER_InitStruct->CMP1_TRIGGER_MODE << 9) |
(TIMER_InitStruct->CAP1_CLR_EN << 8) |
(TIMER_InitStruct->SRC1 << 4) |
(TIMER_InitStruct->CH1Output << 3) |
(TIMER_InitStruct->CH1_WorkMode << 2) |
(TIMER_InitStruct->CH1_FE_CAP_EN << 1) |
(TIMER_InitStruct->CH1_RE_CAP_EN << 0);
TIMERx->CHN0 = TIMER_InitStruct->CHN0;
TIMERx->CHN1 = TIMER_InitStruct->CHN1;
TIMERx->TH = th;
TIMERx->CNT = TIMER_InitStruct->CNT;
TIMERx->EVT = TIMER_InitStruct->EVT;
TIMERx->FLT = TIMER_InitStruct->FLT;
TIMERx->IE = TIMER_InitStruct->IE;
TIMERx->IO = (TIMER_InitStruct->HALT_PRT << 7) |
(TIMER_InitStruct->CH0_DEFAULT << 8) |
(TIMER_InitStruct->CH1_DEFAULT << 9) |
(TIMER_InitStruct->MOE << 6) |
(TIMER_InitStruct->FAIL_SEL << 2) |
(TIMER_InitStruct->FAIL_POL << 1) |
(TIMER_InitStruct->FAIL_EN << 0);
// 影子寄存器配置
TIMERx->CFG2 |= (TIMER_InitStruct->SHADOW << 10);
}
/**
* @brief Timer结构体初始化
* @param TIMER_InitStruct Timer初始化结构体指针
*/
void TIMER_StructInit(TIMER_TimerInitTypeDef *TIMER_InitStruct)
{
for (int i = 0; i < sizeof(TIMER_TimerInitTypeDef) / sizeof(uint32_t); i++)
{
((uint32_t *)TIMER_InitStruct)[i] = 0;
}
}
/**
* @brief 使能Timer
* @param TIMERx Timer实例指针
*/
void TIMER_Enable(TIMER_TypeDef *TIMERx)
{
if (TIMERx == TIMER0)
{
SYS_ModuleClockCmd(SYS_MODULE_TIMER0, ENABLE);
}
else if (TIMERx == TIMER1)
{
SYS_ModuleClockCmd(SYS_MODULE_TIMER1, ENABLE);
}
else if (TIMERx == TIMER2)
{
SYS_ModuleClockCmd(SYS_MODULE_TIMER2, ENABLE);
}
else
{
__NOP();
}
}
/**
* @brief 初始化DSP模块
*
* 该函数用于初始化DSP模块,使其处于可用状态。
*/
void DSP_Init(void)
{
SYS_ModuleClockCmd(SYS_MODULE_DSP0, ENABLE);
SYS_SoftResetModule(SYS_MODULE_DSP0);
}
/**
* @brief 执行取模运算
*
* @param a 被除数
* @param b 除数
* @return 余数
*/
s32 DSP_Mod(s32 a, s32 b)
{
DSP0_DID = a;
DSP0_DIS = b;
return DSP0_REM;
}
/**
* @brief 执行整数除法
*
* @param a 被除数
* @param b 除数
* @return 商
*/
s32 DSP_Div(s32 a, s32 b)
{
DSP0_DID = a;
DSP0_DIS = b;
// 执行整数除法,这里直接返回除法结果
return DSP0_QUO;
}
/**
* @brief 数字模块时钟使能
* @param nModule 模块编号
* @param state 使能或禁用状态
*/
void SYS_ModuleClockCmd(uint32_t nModule, uint8_t state)
{
REG_WRITE(SYS0->PROTECT, 0x7a83);
if (state)
{
REG_SET(SYS0->CLK_FEN, nModule);
}
else
{
REG_RESET(SYS0->CLK_FEN, nModule);
}
REG_WRITE(SYS0->PROTECT, 0);
}
/**
* @brief 软复位模块
* @param nModule 模块编号
*/
void SYS_SoftResetModule(uint32_t nModule)
{
REG_WRITE(SYS0->PROTECT, 0x7a83);
REG_SET(SYS0->SFT_RST, nModule);
REG_RESET(SYS0->SFT_RST, nModule); // 触发复位后需清除复位位
REG_WRITE(SYS0->PROTECT, 0);
}