• 正文
  • 相关推荐
申请入驻 产业图谱

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

12/24 11:43
240
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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

一、CW32L012的CORDIC运算原理

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

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

具体运算定义如下:

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

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


扫码加入QQ群 3群| 610403240

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小自还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理都可在CW32生态社区汲取营养、共同成长。