[单片机芯片] 【沁恒CH32V307 RISC-V开发板测评】05 GPIO极限测试

[复制链接]
 楼主| 怀揣少年梦 发表于 2025-6-22 22:49 | 显示全部楼层 |阅读模式
本次测评主要测试一下CH32V307 GPIO的翻转速度。
一、背景
CH32V307搭载了一颗青稞V4F内核,支持硬件单精度浮点运算,144MHz主频下coremark达380,GPIO作为最基础的外设直接影响实时控制性能,因此对GPIO的翻转速度测试是很有必要的。
另外由于库函数的封装,会影响真实的硬件速度;输出速度50Mhz会误解为信号输出上限。
二、测试环境准备
1、核心板
CH32V307V-R2-1V1,外部晶振为8Mhz,通过PLL倍频到144Mhz
2、使用PD0作为测试引脚
3、测量设备
使用正点原子mini示波器,探头X1衰减模式
三、代码配置
1、基于沁恒官方的MRS开发工具,新建工程,生成的主函数如下
  1. /*********************************************************************
  2. * @fn      main
  3. *
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]   Main program.
  5. *
  6. * [url=home.php?mod=space&uid=266161]@return[/url]  none
  7. */
  8. int main(void)
  9. {
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  11.     SystemCoreClockUpdate();
  12.     Delay_Init();
  13.     USART_Printf_Init(115200);  
  14.     printf("SystemClk:%d\r\n",SystemCoreClock);
  15.     printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
  16.     printf("This is printf example\r\n");

  17.     while(1)
  18.     {

  19.     }
  20. }


2、初始化测试引脚
  1. /*********************************************************************
  2. * @fn      GPIO_Toggle_INIT
  3. *
  4. * @brief   Initializes GPIOD.0
  5. *
  6. * @return  none
  7. */
  8. void GPIO_Toggle_INIT(void)
  9. {
  10.     GPIO_InitTypeDef GPIO_InitStructure = {0};

  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15.     GPIO_Init(GPIOD, &GPIO_InitStructure);
  16. }


3、编写IO翻转代码
  1. /* Global define */
  2. #define USE_LIB 0
  3. #define USE_REG 0
  4. #define USE_ASM 1

  5. /*********************************************************************
  6. * @fn      main
  7. *
  8. * @brief   Main program.
  9. *
  10. * @return  none
  11. */
  12. int main(void)
  13. {
  14.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  15.     SystemCoreClockUpdate();
  16.     Delay_Init();
  17.     USART_Printf_Init(115200);  
  18.     printf("SystemClk:%d\r\n",SystemCoreClock);
  19.     printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
  20.     GPIO_Toggle_INIT();

  21.     while(1)
  22.     {
  23. #if USE_LIB
  24.         GPIO_SetBits(GPIOD,GPIO_Pin_0);
  25.         GPIO_ResetBits(GPIOD,GPIO_Pin_0);
  26. #elif USE_REG
  27.         GPIOD->BSHR = GPIO_Pin_0;
  28.         GPIOD->BCR = GPIO_Pin_0;
  29. #elif USE_ASM
  30.     //GPIO_Toggle_Asm((uint32_t)&GPIOD->OUTDR);
  31.     GPIO_Toggle_Asm();
  32. #endif
  33.     }
  34. }


4、新建汇编文件
gpio_toggle.s
  1. .section .text
  2. .global GPIO_Toggle_Asm

  3. GPIO_Toggle_Asm :
  4.     # 高速模式(约48MHz)
  5.     li t1, 0x40011410   # GPIOD_BSHR地址
  6.     li t2, 0x40011414   # GPIOD_BCR地址
  7.     li a5, 0x0001     # PD0置位值
  8.     loop:

  9.     sw a5, 0(t1)      # 输出高电平
  10.     sw a5, 0(t2)      # 输出低电平
  11.     j loop


四、实测结果
1、使用库函数进行GPIO翻转,将USE_LIB宏定义的值改为1,其他值为0
实测波形如图,翻转速度为9Mhz
017.BMP

2、使用寄存器进行GPIO翻转,将USE_REG宏定义的值改为1,其他值为0
实测波形如图,翻转速度为24Mhz
018.BMP

3、使用汇编语言进行GPIO翻转,将USE_ASM宏定义的值改为1,其他值为0
实测波形与寄存器GPIO翻转一样,都为24Mhz.
从指令周期来分析,寄存器需要两个周期
3376268581744c6b58.png
汇编也只有两个周期
8497968581738579c1.png
按道理只需要两个周期,频率能达到更高,但
1、SRAM写操作需2~3周期;
2、连续sw指令导致数据依赖,RISC-V单发射流水线无法并行执行。
综上,CH32V307的极限翻转速度只有24Mhz







您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一切皆有可能

45

主题

473

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:一切皆有可能

45

主题

473

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部