?
CW32L012和STM32F103在定位和性能上差異顯著,在三角函數的運算性能上的對比亦非常直觀。
一、 硬件架構對比(性能基礎)
| 芯片型號 | CW32L012C8 | STM32F103C8 |
|---|---|---|
| 內核 | ARM Cortex-M0+ | ARM Cortex-M3 |
| 主頻 | 最高 96 MHz | 最高 72 MHz |
| 硬件CORDIC | 支持 | 無 |
| DSP | 無 | 無 |
| 立創樣片價格 | 3.69元 | 7.55元 |
兩者都沒有硬件浮點運算單元。 但在運算三角函數時,CW32L012支持CORDIC算法。
二、 三角運算性能具體分析
1:標準庫浮點運算(如 math.h 的 sinf, cosf)
這是最常用但也是最慢的方式。
STM32F103C8:Cortex-M3內核的整體性能,使其在運行相同的軟件浮點庫時,性能優于CW32L012的Cortex-M0+。
CW32L012C8:Cortex-M0+內核設計更簡單,但用軟件浮點運算效率較低,耗時會更長。
以下是使用STM32F103C8T6和CW32L012C8T6兩種芯片。使用math.h運算SIN和COS的代碼實現。
STM32F103使用math.h運算SIN30度與COS30度 :
float angle; void performance_test(unsigned long iterations) { unsigned long i=0; float y1,y2; for(i=1;i<=iterations;i++) { y1=sin(angle); y2=cos(angle); } } void LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } void TIM1_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); TIM_InternalClockConfig(TIM1); TIM_TimeBaseInitTypeDef TIM1_Initstructure; TIM1_Initstructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM1_Initstructure.TIM_CounterMode=TIM_CounterMode_Up; TIM1_Initstructure.TIM_Period=1000-1; //定時時長=72000000/(Prescaler-1)/(Period-1) TIM1_Initstructure.TIM_Prescaler=72-1; TIM1_Initstructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM1,&TIM1_Initstructure); TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE); TIM_ClearFlag(TIM1,TIM_IT_Update); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_Initstructure; NVIC_Initstructure.NVIC_IRQChannel=TIM1_UP_IRQn; NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_Initstructure.NVIC_IRQChannelSubPriority=1; NVIC_Init(&NVIC_Initstructure); TIM_Cmd(TIM1,ENABLE); } unsigned int timecount=0; unsigned int lastcmputetime=0; int main(void) { char temp_buff1[40]; LED_Init(); TIM1_Init(); OLED_Init(); //清屏 OLED_Printf(0,0,OLED_6X8," SIN/COS COMPUTE Test "); OLED_Printf(0,16,OLED_6X8," For 1000000 Times "); OLED_Update(); angle=0.523; //0.785(45度弧度制)=45度/180度*3.14 0.523(30度弧度制)=30/180*3.14 while (1) { sprintf(temp_buff1, " STM32F103 start...... "); OLED_Printf(0, 32, OLED_6X8, temp_buff1); OLED_Printf(0, 48, OLED_8X16, " "); OLED_Update(); timecount=0; performance_test(1000000); lastcmputetime=timecount; sprintf(temp_buff1, " STM32F103 used time: "); OLED_Printf(0, 32, OLED_6X8, temp_buff1); sprintf(temp_buff1, " %d mS ", lastcmputetime); OLED_Printf(0, 48, OLED_8X16, temp_buff1);OLED_Update(); while(1); //由于結果太慢,不進行二次運算,停在這里方便查看時間. 如果需要二次運算,則屏蔽該條語句 timecount=0; while(timecount4000); //等待2S } } void TIM1_UP_IRQHandler(void) { static unsigned int flag=0; if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) { TIM_ClearITPendingBit(TIM1,TIM_IT_Update); timecount++; // if(timecount?>=500) //以下用于檢查時間配置是否準確 // {timecount=0; // flag=1-flag; // if(flag==1) // GPIO_SetBits(GPIOC,GPIO_Pin_13); // else // GPIO_ResetBits(GPIOC,GPIO_Pin_13); // } } }

使用MATH.H執行結果:運算100W次SIN30度與COS30度時間顯示內容如下:

CW32L012使用math.h運算SIN30度與COS30度:
核心代碼:
void performance_test(unsigned long iterations)
{
unsigned long i=0;
float y1,y2;
CW_FLASH->CR2 = 0x5a5a001B;
for(i=1;i<=iterations;i++)
{
y1=sin(anglef);
y2=cos(anglef);
}
CW_FLASH-?>CR2 = 0x5a5a0003;
}

使用MATH.H執行結果:運算100W次SIN30度與COS30度時間顯示內容如下:

2:使用硬件CORDIC
CORDIC是一種用移位和加法實現三角、雙曲等函數的算法。CW32L012的CORDIC提供某些數學函數的硬件加速,特別是三角函數,通常用于電機控制、計量、信號處理和許多其他應用。與軟件實現相比,它加快了這些功能的計算速度,允許較低的工作頻率,或釋放處理器周期以執行其他任務。
CW32L012的CORDIC支持余弦 cos、正弦 sin、相位角 atan2、模 hypot、反正切 atan、雙曲余弦 cosh、雙曲正弦 sinh、雙曲反正切 atanh 函數運算。
CW32L012使用CORDIC運算100W次SIN30度與COS30度的代碼實現如下:
int32_t angle;
void RCC_Configuration(void)
{
SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV1);
SYSCTRL_HCLKPRS_Config(SYSCTRL_HCLK_DIV1);
SYSCTRL_PCLKPRS_Config(SYSCTRL_PCLK_DIV1);
SYSCTRL_SystemCoreClockUpdate(96000000);
}
void performance_test1(unsigned long iterations)
{
unsigned long i=0;
int32_t y1,y2;
float y11,y22;
for(i=1;i<=iterations;i++)
{
while (CORDIC_GetStatus().busy);
CW_CORDIC-?>Z =angle; // 寫入Z寄存器啟動運算
// 等待運算完成
while (!CORDIC_GetStatus().eoc); //運算完成標志硬件置1,讀取運算結果硬件清0
// 讀取結果
//y1=CW_CORDIC->Y;//sin(PI/6); // 正弦結果在Y寄存器 Q1.31格式 根據需要使用
//y2=CW_CORDIC->X;//cos(PI/6); // 余弦結果在X寄存器 Q1.31格式 根據需要使用
//y11=q1_31_to_float(y1); //正弦結果轉浮點數 根據需要使用
//y22=q1_31_to_float(y2); //余弦結果轉浮點數 根據需要使用
}
}
void BTIM1_Configuration(void) //1ms進一次中斷
{
BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct = {0};
__SYSCTRL_BTIM123_CLK_ENABLE();
__disable_irq();
NVIC_EnableIRQ(BTIM1_IRQn);
__enable_irq();
BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_MODE_TIMER;
BTIM_TimeBaseInitStruct.BTIM_Period = 1000 - 1;
BTIM_TimeBaseInitStruct.BTIM_Prescaler = 96 - 1; // 8
BTIM_TimeBaseInit(CW_BTIM1, &BTIM_TimeBaseInitStruct);
BTIM_ITConfig(CW_BTIM1, BTIM_IT_UPDATE, ENABLE);
BTIM_Cmd(CW_BTIM1, ENABLE);
}
unsigned int timecount=0;
unsigned int lastcmputetime=0;
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
char temp_buff1[4];
RCC_Configuration();//時鐘配置
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運算初始化
EAU_Init();// 初始化EAU
EAU_SetMode(EAU_MODE_UNSIGNED_DIV);// 設置為無符號除法模式
__SYSCTRL_GPIOC_CLK_ENABLE(); //GPIOC LED
GPIO_InitStruct.Pins = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init( CW_GPIOC, &GPIO_InitStruct);
GPIO_WritePin(CW_GPIOC,GPIO_PIN_13,GPIO_Pin_RESET);
BTIM1_Configuration(); //1MS
OLED_Init(); //清屏
OLED_Printf(0,0,OLED_6X8," SIN/COS COMPUTE Test ");
OLED_Printf(0,16,OLED_6X8," For 1000000 Times ");
OLED_Update();
angle = float_to_q1_31(0.167);//float_to_q1_15 // 0.25=1/4,即:運算45度=PI/4,換算為Q1.31格式, //0.167=1/6 PI/6=30度
while (1)
{
sprintf(temp_buff1, " CW32L012 start...... ");
OLED_Printf(0, 32, OLED_6X8, temp_buff1);
OLED_Printf(0, 48, OLED_8X16, " ");
OLED_Update();
timecount=0;
performance_test1(1000000);
lastcmputetime=timecount;
sprintf(temp_buff1, " CW32L012 used time: ");
OLED_Printf(0, 32, OLED_6X8, temp_buff1);
sprintf(temp_buff1, " %d mS ", lastcmputetime);
OLED_Printf(0, 48, OLED_8X16, temp_buff1);OLED_Update();
timecount=0;
while(timecount4000); //等待2S
}
}
void BTIM1_IRQHandler(void)
{
/* USER CODE BEGIN */
if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_UPDATE))
{
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_UPDATE);
timecount++;
}
/* USER CODE END */
}

運算結果:

計算100W次SIN30度 與COS30度。其中運算結果數據表示為:CORDIC運算結果為Q1.31格式表示;math.h:運算結果為浮點數表示。
時間對比參考如下:

?
審核編輯 黃宇
-
STM32F103
+關注
關注
34文章
495瀏覽量
67693 -
CW32
+關注
關注
1文章
299瀏覽量
1846
發布評論請先 登錄
基于STM32F103驅動DAC1220 20位/16位DAC數模轉換模塊輸出可調±10V基準和三角波信號
基于STM32F103驅動AD9833模塊 DDS信號發生器輸出正弦波/三角波/方波可編程信號
FOC控制中如何利用芯片內部的運放設計電流采樣電路?
CW32L012與STM32G431的CORDIC三角函數運算性能對比
CW32L012小型機器人控制評估板活動 四足機器人+智能小車 開箱評測
**CW32L012****開發評估板的第一個程序**
CW32L012小機器人的電機控制
使用芯源CW32的CW32L012開發評估板做了spi屏幕驅動
MH32F103A系列單片機的功能特性
在STM32F103c8上做DLQR最優控制算法的C編程資料
堅持繼續布局32位MCU,進一步完善產品陣容,96Mhz主頻CW32L012新品發布!
CW32L012與STM32F103的三角運算性能對比
評論