目录

06.01_DSP-除法

测试步骤

使用硬件dsp进行除法计算

实测数据

实测数据

abDSP_Div(a, b)DSP_Mod(a, b)div errmod err
-2147483648 (0x80000000)-2147483648 (0x80000000)1000
-2147483648 (0x80000000)-100000000 (0xfa0a1f00)21-4748364800
-2147483648 (0x80000000)-32768 (0xffff8000)65536000
-2147483648 (0x80000000)-10000 (0xffffd8f0)214748-364800
-2147483648 (0x80000000)-1 (0xffffffff)21474836470-10
-2147483648 (0x80000000)0 (0x00000000)0-214748364800
-2147483648 (0x80000000)1 (0x00000001)-2147483648000
-2147483648 (0x80000000)10000 (0x00002710)-214748-364800
-2147483648 (0x80000000)32767 (0x00007fff)-65538-200
-2147483648 (0x80000000)100000000 (0x05f5e100)-21-4748364800
-2147483648 (0x80000000)2147483647 (0x7fffffff)-1-100
-100000000 (0xfa0a1f00)-2147483648 (0x80000000)0-10000000000
-100000000 (0xfa0a1f00)-100000000 (0xfa0a1f00)1000
-100000000 (0xfa0a1f00)-32768 (0xffff8000)3051-2483200
-100000000 (0xfa0a1f00)-10000 (0xffffd8f0)10000000
-100000000 (0xfa0a1f00)-1 (0xffffffff)100000000000
-100000000 (0xfa0a1f00)0 (0x00000000)0-10000000000
-100000000 (0xfa0a1f00)1 (0x00000001)-100000000000
-100000000 (0xfa0a1f00)10000 (0x00002710)-10000000
-100000000 (0xfa0a1f00)32767 (0x00007fff)-3051-2788300
-100000000 (0xfa0a1f00)100000000 (0x05f5e100)-1000
-100000000 (0xfa0a1f00)2147483647 (0x7fffffff)0-10000000000
-32768 (0xffff8000)-2147483648 (0x80000000)0-3276800
-32768 (0xffff8000)-100000000 (0xfa0a1f00)0-3276800
-32768 (0xffff8000)-32768 (0xffff8000)1000
-32768 (0xffff8000)-10000 (0xffffd8f0)3-276800
-32768 (0xffff8000)-1 (0xffffffff)32768000
-32768 (0xffff8000)0 (0x00000000)0-3276800
-32768 (0xffff8000)1 (0x00000001)-32768000
-32768 (0xffff8000)10000 (0x00002710)-3-276800
-32768 (0xffff8000)32767 (0x00007fff)-1-100
-32768 (0xffff8000)100000000 (0x05f5e100)0-3276800
-32768 (0xffff8000)2147483647 (0x7fffffff)0-3276800
-10000 (0xffffd8f0)-2147483648 (0x80000000)0-1000000
-10000 (0xffffd8f0)-100000000 (0xfa0a1f00)0-1000000
-10000 (0xffffd8f0)-32768 (0xffff8000)0-1000000
-10000 (0xffffd8f0)-10000 (0xffffd8f0)1000
-10000 (0xffffd8f0)-1 (0xffffffff)10000000
-10000 (0xffffd8f0)0 (0x00000000)0-1000000
-10000 (0xffffd8f0)1 (0x00000001)-10000000
-10000 (0xffffd8f0)10000 (0x00002710)-1000
-10000 (0xffffd8f0)32767 (0x00007fff)0-1000000
-10000 (0xffffd8f0)100000000 (0x05f5e100)0-1000000
-10000 (0xffffd8f0)2147483647 (0x7fffffff)0-1000000
-1 (0xffffffff)-2147483648 (0x80000000)0-100
-1 (0xffffffff)-100000000 (0xfa0a1f00)0-100
-1 (0xffffffff)-32768 (0xffff8000)0-100
-1 (0xffffffff)-10000 (0xffffd8f0)0-100
-1 (0xffffffff)-1 (0xffffffff)1000
-1 (0xffffffff)0 (0x00000000)0-100
-1 (0xffffffff)1 (0x00000001)-1000
-1 (0xffffffff)10000 (0x00002710)0-100
-1 (0xffffffff)32767 (0x00007fff)0-100
-1 (0xffffffff)100000000 (0x05f5e100)0-100
-1 (0xffffffff)2147483647 (0x7fffffff)0-100
0 (0x00000000)-2147483648 (0x80000000)0000
0 (0x00000000)-100000000 (0xfa0a1f00)0000
0 (0x00000000)-32768 (0xffff8000)0000
0 (0x00000000)-10000 (0xffffd8f0)0000
0 (0x00000000)-1 (0xffffffff)0000
0 (0x00000000)0 (0x00000000)0000
0 (0x00000000)1 (0x00000001)0000
0 (0x00000000)10000 (0x00002710)0000
0 (0x00000000)32767 (0x00007fff)0000
0 (0x00000000)100000000 (0x05f5e100)0000
0 (0x00000000)2147483647 (0x7fffffff)0000
1 (0x00000001)-2147483648 (0x80000000)0100
1 (0x00000001)-100000000 (0xfa0a1f00)0100
1 (0x00000001)-32768 (0xffff8000)0100
1 (0x00000001)-10000 (0xffffd8f0)0100
1 (0x00000001)-1 (0xffffffff)-1000
1 (0x00000001)0 (0x00000000)0100
1 (0x00000001)1 (0x00000001)1000
1 (0x00000001)10000 (0x00002710)0100
1 (0x00000001)32767 (0x00007fff)0100
1 (0x00000001)100000000 (0x05f5e100)0100
1 (0x00000001)2147483647 (0x7fffffff)0100
10000 (0x00002710)-2147483648 (0x80000000)01000000
10000 (0x00002710)-100000000 (0xfa0a1f00)01000000
10000 (0x00002710)-32768 (0xffff8000)01000000
10000 (0x00002710)-10000 (0xffffd8f0)-1000
10000 (0x00002710)-1 (0xffffffff)-10000000
10000 (0x00002710)0 (0x00000000)01000000
10000 (0x00002710)1 (0x00000001)10000000
10000 (0x00002710)10000 (0x00002710)1000
10000 (0x00002710)32767 (0x00007fff)01000000
10000 (0x00002710)100000000 (0x05f5e100)01000000
10000 (0x00002710)2147483647 (0x7fffffff)01000000
32767 (0x00007fff)-2147483648 (0x80000000)03276700
32767 (0x00007fff)-100000000 (0xfa0a1f00)03276700
32767 (0x00007fff)-32768 (0xffff8000)03276700
32767 (0x00007fff)-10000 (0xffffd8f0)-3276700
32767 (0x00007fff)-1 (0xffffffff)-32767000
32767 (0x00007fff)0 (0x00000000)03276700
32767 (0x00007fff)1 (0x00000001)32767000
32767 (0x00007fff)10000 (0x00002710)3276700
32767 (0x00007fff)32767 (0x00007fff)1000
32767 (0x00007fff)100000000 (0x05f5e100)03276700
32767 (0x00007fff)2147483647 (0x7fffffff)03276700
100000000 (0x05f5e100)-2147483648 (0x80000000)010000000000
100000000 (0x05f5e100)-100000000 (0xfa0a1f00)-1000
100000000 (0x05f5e100)-32768 (0xffff8000)-30512483200
100000000 (0x05f5e100)-10000 (0xffffd8f0)-10000000
100000000 (0x05f5e100)-1 (0xffffffff)-100000000000
100000000 (0x05f5e100)0 (0x00000000)010000000000
100000000 (0x05f5e100)1 (0x00000001)100000000000
100000000 (0x05f5e100)10000 (0x00002710)10000000
100000000 (0x05f5e100)32767 (0x00007fff)30512788300
100000000 (0x05f5e100)100000000 (0x05f5e100)1000
100000000 (0x05f5e100)2147483647 (0x7fffffff)010000000000
2147483647 (0x7fffffff)-2147483648 (0x80000000)0214748364700
2147483647 (0x7fffffff)-100000000 (0xfa0a1f00)-214748364700
2147483647 (0x7fffffff)-32768 (0xffff8000)-655353276700
2147483647 (0x7fffffff)-10000 (0xffffd8f0)-214748364700
2147483647 (0x7fffffff)-1 (0xffffffff)-2147483647000
2147483647 (0x7fffffff)0 (0x00000000)0214748364700
2147483647 (0x7fffffff)1 (0x00000001)2147483647000
2147483647 (0x7fffffff)10000 (0x00002710)214748364700
2147483647 (0x7fffffff)32767 (0x00007fff)65538100
2147483647 (0x7fffffff)100000000 (0x05f5e100)214748364700
2147483647 (0x7fffffff)2147483647 (0x7fffffff)1000

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);
}