CW32L012实现CORDIC模块微秒级快速运算SIN、COS等三角函数

第一财经记者 2026-01-02 27人围观 ,发现0个评论

CW32L012具有CORDIC 协处理器,能够实现微秒级快速计算三角函数功能。

一、CW32L012的CORDIC运算原理

CORDIC是一种坐标旋转数字计算机算法。CW32L012的CORDIC提供某些数学函数的硬件加速,特别是三角函数,通常用于电机控制、计量、信号处理和许多其他应用。与软件实现相比,它加快了这些功能的计算速度,允许较低的工作频率,或释放处理器周期以执行其他任务。

CW32L012的CORDIC支持余弦 cos、正弦 sin、相位角 atan2、模 hypot、反正切 atan、双曲余弦 cosh、双曲正弦 sinh、双曲反正切 atanh 函数运算。迭代次数可进行配置(范围 6~66)。

具体运算定义如下:

wKgZO2lSNx6AEkEeAAFv2ZiMPDk750.png

关于 q1.15 和 q1.31:

• 用 sint16/sint32 代表 [-1,1)之间的实数

• sint16 对应的 q1.15 = sint16 / pow(2,15)

• sint32 对应的 q1.31 = sint32 / pow(2,31)

关于迭代次数:

• q1.15 建议迭代 16-20 次,q1.31 建议迭代 24-32 次。

关于启动:

• 只有一个数据输入(x 或 y 或 z)时,写入该数据即启动运算。

• 需要两个数据输入(x 和 y)时,写入 y 启动运算。

CORDIC 存在 2 个状态标志,用来指示 CORDIC 的当前工作状态,包括工作状态标志 BUSY、运算完成标志忙标志(CORDIC_CSR.BUSY)

CORDIC_CSR.BUSY 标志位指示当前 CORDIC 是否处于运算结束或空闲状态。

当CORDIC CSR.BUSY 为 0 时,表示 CORDIC 处于运算结束或空闲状态,可以读取结果或开始新的运算;当CSR.BUSY 为 1 时,表示 CORDIC 处于忙碌状态,当前数据运算正在进行中,无法提供运算结果或开始新的运算。

运算完成标志位CORDIC_CSR.EOC 指示 CORDIC 运算完成。EOC 标志位被置位并不影响继续进行新一轮运算,无论新一轮运算是什么类型。当新一轮运算被启动时,标志位自动清零并根据新一轮运算的情况重新进行指示。

二、编程实现

初始化定义:


cordic_init_t init = {
        .func = CORDIC_FUNC_COS,  // 选择余弦函数
        .scale = 0,              // 不使用扩展范围
        .format = CORDIC_FORMAT_Q1_31, // 使用q1.31格式
        .iter = CORDIC_ITER_20,  // 迭代次数
        .comp = 1,               // 硬件补偿伸缩因子
        .ie = 0,                 // 禁用中断
        .dmaeoc = 0,             // 禁用DMA
        .dmaidle = 0             // 禁用DMA空闲
    };  
  CORDIC_Init(&init);  //sin cos运算初始化

角度定义


int32_t angle; 
angle = float_to_q1_31(0.167);

若计算45度的正余弦,则令angle=0.25(即1/4)。这样运算的参数为 PI/4(45度),写入角度参数前需要将数据转化为Q1.31格式或Q1.15格式。

若计算30度的正余弦, 则令angle=0.167(即1/6)。这样运算的参数为PI/6 (30度),写入角度参数前需要将数据转化为Q1.31格式或Q1.15格式。

将浮点数转换为Q1.31格式,函数定义如下:


int32_t float_to_q1_31(float value) {
    return (int32_t)round(value * 2147483648.0); // 2^31
}

运算


while (CORDIC_GetStatus().busy);//运算前判断BUSY状态 
CW_CORDIC->Z =angle;   // 写入Z寄存器启动运算
while (!CORDIC_GetStatus().eoc);  // 等待运算完成,完成时标志硬件置1,读取运算结果时硬件清0

读取结果

int32_t y1,y2;
float  y11,y22; 
y1=CW_CORDIC->Y;// 正弦结果在Y寄存器 ,Q1.31格式 
y2=CW_CORDIC->X;// 余弦结果在X寄存器 Q1.31格式 
y11=q1_31_to_float(y1);   //正弦结果转浮点数,可根据需要使用
y22=q1_31_to_float(y2);   //余弦结果转浮点数,可根据需要使用 

其中Q1.31格式的定点数转为浮点数函数定义如下:


float q1_31_to_float(int32_t value) {
    return (float)value / 2147483648.0; // 2^31
}

Q1.15格式的定点数转换为浮点数函数定义如下:


float q1_15_to_float(int32_t value)
{
    return (float)value / 32768.0f;
}

参考例程

CW32L012的标准库文件夹下有参考例程,可以直接运行。标准库文件可在武汉芯源半导体有限公司的官方网址上直接下载(资料下载固件库)。

例程路径如下:

CW32L012_StandardPeripheralLib_V1.0.3ExamplesCORDICcordic_cosMDK

MDK工程打开示意图如下:

wKgZPGlSOeqAOGNxAAFYdbU5mfI214.png

该例程可以在CW32L012的最小系统架构中运算。

审核编辑 黄宇

  • 随机文章
  • 热门文章
  • 热评文章
不容错过
Powered By Z-BlogPHP