做网站都需要什么贴吧,七台河新闻联播2021,wordpress安装图片,福田公司简介前言
本系列基于复旦微FM33LC0系列单片机的DataSheet编写#xff0c;旨在提供一些开发指南。 本文章及本系列其他文章将持续更新#xff0c;本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇
本文章最后更新日期#xff1a;2024/10/24 文章目录 前言用途工作流…前言
本系列基于复旦微FM33LC0系列单片机的DataSheet编写旨在提供一些开发指南。 本文章及本系列其他文章将持续更新本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇
本文章最后更新日期2024/10/24 文章目录 前言用途工作流程寄存器耗时对比注意事项原子操作效率数据类型 用途
对于M0内核的MCU而言其内核是没有除法指令的。 当语法中出现除法操作是借助C语言函数库来完成除法操作的。这种操作比较耗时
FM33LC0配备有硬件除法器外设HDIV用于帮助软件加速除法运算。
工作流程 寄存器 HDIV-END 32bit 有符号被除数 HDIV-SOR 16bit 有符号除数 HDIV-QUOT 32bit 有符号商 HDIV-REMD 16bit 有符号余数 HDIV-SR
耗时对比
FM33LC0的DataSheet写明一次除法运算需要8个24MHz周期。
在48MHz的主频编译器优化等级-O0的情况下 C语言使用for循环进行100万次除法操作耗时4728ms用硬件除法器耗时1044ms。 由于使用了1ms的定时器中断计时实际计算时间会比这个更短
硬件除法器测试代码如下
static uint32_t beginTime 0, endTime 0; // 起始时间和结束时间
uint32_t x 214748364; // 被除数必须加volatile否则会被编译器优化
uint16_t y 5635; // 除数必须加volatile否则会被编译器优化
volatile uint32_t z 0; // 商必须加volatile否则会被编译器优化RCC-PCLKCR1 | 0x1u 9; // 使能硬件除法器时钟
beginTime GetTimingCounter(); // 开始计时for(uint32_t i 0; i 1000000; i)
{
#if 1/* 使用硬件除法器 */HDIV-END x; // 被除数HDIV-SOR y; // 除数while( HDIV-SR 0x01 ); // 等待计算完成z HDIV-QUOT; // 商
#else/* 直接做除法运算 */z x / y;
#endif
}endTime GetTimingCounter(); // 结束计时注意事项
原子操作
在使用硬件除法器时务必注意加入原子操作。
在使用HDIV时需要先写入被除数寄存器HDIV-END再写入除数寄存器HDIV-SOR当写入除数寄存器后会自动开始运算。 如果模块A使用硬件除法器做除法在写入被除数寄存器HDIV-END后还没来得及写入除数寄存器HDIV-SOR被一个高优先级的模块B抢占而模块B也使用硬件除法器做除法将导致当程序返回到模块A时HDIV-END寄存器的值其实是模块B的被除数从而得到错误的结果。
效率
虽然操作硬件除法器比直接进行除法更加省时间但平时我们都会将硬件除法器封装为一个单独的函数在这种情况下 1函数中应当使用原子操作并操作硬件除法器以防止运算过程被打断。在这种情况下考虑到函数的调用时间、开关中断的时间硬件除法器节省的时间优势会降低。 2硬件除法器的HDIV-SR寄存器可以指示当前是否在运行过程中但如果在填写HDIV-END和HDIV-SOR寄存器后使用while去一直查询该寄存器来判断是否运算完成是很耗费时间的。所以可以直接加入若干个__nop()。
数据类型
硬件除法器的数据寄存器数据类型都是有符号类型的使用时请注意类型要匹配。