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

电子说

1.4w人已加入

描述

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

一、CW32L012的CORDIC运算原理

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

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

具体运算定义如下:

CORDICCORDIC

关于 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工程打开示意图如下:

CORDIC

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

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • 热点推荐
  • CORDIC

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分