- /*********************************************************************
- * @fn main
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- SystemCoreClockUpdate();
- Delay_Init();
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n",SystemCoreClock);
- printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
- printf("This is printf example\r\n");
- while(1)
- {
- }
- }
2、初始化测试引脚
- /*********************************************************************
- * @fn GPIO_Toggle_INIT
- *
- * @brief Initializes GPIOD.0
- *
- * @return none
- */
- void GPIO_Toggle_INIT(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- }
3、编写IO翻转代码
- /* Global define */
- #define USE_LIB 0
- #define USE_REG 0
- #define USE_ASM 1
- /*********************************************************************
- * @fn main
- *
- * @brief Main program.
- *
- * @return none
- */
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- SystemCoreClockUpdate();
- Delay_Init();
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n",SystemCoreClock);
- printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
- GPIO_Toggle_INIT();
- while(1)
- {
- #if USE_LIB
- GPIO_SetBits(GPIOD,GPIO_Pin_0);
- GPIO_ResetBits(GPIOD,GPIO_Pin_0);
- #elif USE_REG
- GPIOD->BSHR = GPIO_Pin_0;
- GPIOD->BCR = GPIO_Pin_0;
- #elif USE_ASM
- //GPIO_Toggle_Asm((uint32_t)&GPIOD->OUTDR);
- GPIO_Toggle_Asm();
- #endif
- }
- }
4、新建汇编文件
gpio_toggle.s
- .section .text
- .global GPIO_Toggle_Asm
- GPIO_Toggle_Asm :
- # 高速模式(约48MHz)
- li t1, 0x40011410 # GPIOD_BSHR地址
- li t2, 0x40011414 # GPIOD_BCR地址
- li a5, 0x0001 # PD0置位值
- loop:
- sw a5, 0(t1) # 输出高电平
- sw a5, 0(t2) # 输出低电平
- j loop
四、实测结果
1、使用库函数进行GPIO翻转,将USE_LIB宏定义的值改为1,其他值为0
实测波形如图,翻转速度为9Mhz
2、使用寄存器进行GPIO翻转,将USE_REG宏定义的值改为1,其他值为0
实测波形如图,翻转速度为24Mhz
3、使用汇编语言进行GPIO翻转,将USE_ASM宏定义的值改为1,其他值为0
实测波形与寄存器GPIO翻转一样,都为24Mhz.
从指令周期来分析,寄存器需要两个周期
汇编也只有两个周期
按道理只需要两个周期,频率能达到更高,但
1、SRAM写操作需2~3周期;
2、连续sw指令导致数据依赖,RISC-V单发射流水线无法并行执行。
综上,CH32V307的极限翻转速度只有24Mhz