[技术问答] 请问HC32F030 IO翻转最高速率是多少

[复制链接]
 楼主| tottionly 发表于 2020-2-11 16:45 | 显示全部楼层 |阅读模式
IO, HC, pi, gp, GPIO
本帖最后由 tottionly 于 2020-2-11 16:48 编辑
  1. int main(void)
  2. {  

  3.         static uint32_t u32temp1 = 0;
  4.         static uint32_t u32temp2 = 0;

  5.         Sys_Clk_Init();
  6.         u32temp1= Sysctrl_GetHClkFreq();
  7.         u32temp2= Sysctrl_GetPClkFreq();

  8.         Led_PortInit();
  9.         
  10.         while(1)
  11.         {
  12.             setBit(((uint32_t)&M0P_GPIO->PABSET + GpioPortD), GpioPin5, TRUE);
  13.             setBit(((uint32_t)&M0P_GPIO->PABCLR + GpioPortD), GpioPin5, TRUE);
  14.         }
  15.                
  16. }
复制代码

  1. static void Led_PortInit(void)
  2. {
  3.     stc_gpio_config_t pstcGpioCfg;
  4.         
  5.    
  6.     ///< 打开GPIO外设时钟门控
  7.     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
  8.    
  9.     ///< 端口方向配置->输出
  10.     pstcGpioCfg.enDir = GpioDirOut;
  11.     ///< 端口驱动能力配置->高驱动能力
  12.     pstcGpioCfg.enDrv = GpioDrvH;
  13.     ///< 端口上下拉配置->无上下拉
  14.     pstcGpioCfg.enPuPd = GpioNoPuPd;
  15.     ///< 端口开漏输出配置->开漏输出关闭
  16.     pstcGpioCfg.enOD = GpioOdDisable;
  17.     ///< 端口输入/输出值寄存器总线控制模式配置->AHB
  18.     pstcGpioCfg.enCtrlMode = GpioAHB;
  19.    
  20.     ///< GPIO IO PD05初始化(PD05在STK上外接LED)
  21.     Gpio_Init(GpioPortD, GpioPin5, &pstcGpioCfg);
  22.   
  23. }
复制代码


HCLK已经设置为48MHz,通过Sysctrl_GetHClkFreq()函数可读取。
简单测试IO翻转的最高频率,测下来翻转频率是1.5MHz. 理论上不应该这么慢,是哪里设置有问题吗?
感谢解答。
martinhu 发表于 2020-2-11 17:47 | 显示全部楼层
030支持单周期的IO翻转,如果要这么设置,“
  •    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
  •     pstcGpioCfg.enCtrlMode = GpioAHB;”
这里不应该是AHB
865685e426f5721dbe.png
另外要使用寄存器需PxOUT来控制IO的输出,
而且不能使用库函数操作,因为库函数也额外花费代码执行时间,到时翻转频率变慢。

你可以试一下以下这段代码,用KEIL5以后的版本,
PA012是单周期执行的,PB0不是。
256875e42780f1042d.png
int32_t main(void)
{
    uint32_t u32High = 0x00000007;  ///< PA0/1/2
    uint32_t u32Low  = 0x00000000;

    stc_sysctrl_pll_config_t stcPLLCfg;

    DDL_ZERO_STRUCT(stcPLLCfg);

   //Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
       
    //48M时候需要加flash等待
    __set_PRIMASK(1);  //Disable  interrupt
    //Flash_WaitCycle(FlashWaitCycle1);
    __set_PRIMASK(0);  //Enable  interrupt
       

    stcPLLCfg.enInFreq    = SysctrlPllInFreq4_6MHz;     //RCH 4MHz
    stcPLLCfg.enOutFreq   = SysctrlPllOutFreq36_48MHz;  //PLL 输出48MHz
    stcPLLCfg.enPllClkSrc = SysctrlPllRch;              //输入时钟源选择RCH
    stcPLLCfg.enPllMul    = SysctrlPllMul6;//SysctrlPllMul12;            //4MHz x 6 = 24MHz
    Sysctrl_SetPLLFreq(&stcPLLCfg);
    Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
    Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);

    ///< 时钟切换
    Sysctrl_SysClkSwitch(SysctrlClkPLL);



    ///< 打开GPIO外设时钟门控
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
               
    M0P_GPIO->CTRL2_f.AHB_SEL = 0;

    M0P_GPIO->PAOUT = u32High;
    M0P_GPIO->PADIR = u32Low;

    M0P_GPIO->PBDIR_f.PB00 = 0;

    while(1)
    {
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;
        M0P_GPIO->PAOUT = u32High;
        M0P_GPIO->PAOUT = u32Low;

        M0P_GPIO->PBOUT_f.PB00 = 1;
        M0P_GPIO->PBOUT_f.PB00 = 0;
    }
}

 楼主| tottionly 发表于 2020-2-11 18:09 | 显示全部楼层
martinhu 发表于 2020-2-11 17:47
030支持单周期的IO翻转,如果要这么设置,“
  •    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
  •   ...

  • 感谢回复。
    已经测试,按照这个代码,如果HCLK=48MHz,IO翻转频率最高是15MHz左右。

    评论

    48M的时候,因为Flash需要加1个等待周期,所以即使是指令单周期执行,也不是每个时钟周期翻转一次。我测试的时候应该是16MHz。 如果是24M的时钟,IO翻转的频率是12MHz,也就是每个时钟周期IO电平翻转一次。  发表于 2020-2-12 08:30
    gx_huang 发表于 2020-2-11 18:26 | 显示全部楼层
    你用库函数,速度能快才怪呢,光函数调用就很多时间了
    martinhu 发表于 2020-2-12 08:52 | 显示全部楼层
    tottionly 发表于 2020-2-11 18:09
    感谢回复。
    已经测试,按照这个代码,如果HCLK=48MHz,IO翻转频率最高是15MHz左右。 ...

    MCU主频在24MHz时钟以下的时候,使用FAST IO模式可以做到每个HCLK时钟周期IO翻转一次,24M时钟以上,因为需要加Flash等待周期,虽然FAST IO 是单周期的指令,但因为读取Flash指令的时间变多了,所以IO做不到每个HCLK翻转

    314235e434c4ef1d61.png
    菜鸟同学 发表于 2020-2-13 12:16 | 显示全部楼层
    martinhu 发表于 2020-2-12 08:52
    MCU主频在24MHz时钟以下的时候,使用FAST IO模式可以做到每个HCLK时钟周期IO翻转一次,24M时钟以上,因为 ...

    好就你说的读取flash需要延迟,直接跑到RAM 中试试,MCU的IO 翻转速度24M那很吊。我目前用过的还没有发现有这么高的。
    天苍苍野茫茫 发表于 2020-2-18 15:48 | 显示全部楼层
    最起码在8M以上!
    天苍苍野茫茫 发表于 2020-2-18 15:49 | 显示全部楼层
    MCO输出功能可以到主频的4分频
    desertsailor 发表于 2020-11-26 22:02 | 显示全部楼层
    可惜HC32F030读取FLASH没有CACHE,48M主频必须要白等一个周期,STM这方面做得就好些。
    desertsailor 发表于 2020-11-26 22:54 | 显示全部楼层
    本帖最后由 desertsailor 于 2020-11-26 22:57 编辑

    FAST IO只能用于OUT和IN寄存器,改写其中一位的时候其余位也赋了值,这样就要求写之前必须先读,这样一来一回耽误了时间,单周期也就没啥意义了,如果置位和清零寄存器也能适用单周期就完美了。
    martinhu 发表于 2020-11-28 21:40 | 显示全部楼层
    desertsailor 发表于 2020-11-26 22:02
    可惜HC32F030读取FLASH没有CACHE,48M主频必须要白等一个周期,STM这方面做得就好些。 ...

    华大M4的芯片也有cache,200M主频的时候flash也可以做到几乎0等待,
    不过ST的030有cache吗?你确定?
    desertsailor 发表于 2020-11-29 10:29 | 显示全部楼层
    martinhu 发表于 2020-11-28 21:40
    华大M4的芯片也有cache,200M主频的时候flash也可以做到几乎0等待,
    不过ST的030有cache吗?你确定? ...

    STM的F0、F1和F4都有CACHE的,只是大小和性能不同,F0的是3个32位的预取指缓存,F1是2个64的预取指缓存,F4的更大而且还区分I-CODE和D-CODE
    和下土 发表于 2020-11-29 12:06 | 显示全部楼层
    差不多8mdh\
    和下土 发表于 2020-11-29 12:07 | 显示全部楼层
    华大M4的芯片确实有cache
    和下土 发表于 2020-11-29 12:08 | 显示全部楼层
    48M主频必须要白等一个周期吗?
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    9

    主题

    35

    帖子

    1

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