qjp1988113 发表于 2020-9-29 14:17

【华大测评】+华大HC32F460开发板之systick延时函数

本帖最后由 qjp1988113 于 2020-9-29 14:17 编辑

最近经过各种国产MCU的摧残,一开始我还觉得代码风格不是很好的华大460开发板代码,在我眼里又好了起来。之前时间在调试HC32L130,用了之后我对华大的MCU开始有了好的印象。最近又有点空了,决定再全面整下F460。
老规矩,先看第一个DEMO,gpio输出控制LED的例程。在看到F460给出例程的us级别的延时函数:
void Ddl_Delay1us(uint32_t u32Cnt)
{
    uint32_t u32Cyc = 1ul;
    volatile uint32_t i = 0ul;

    if(SystemCoreClock > 10000000ul)
    {
      u32Cyc = SystemCoreClock / 10000000ul;
      while(u32Cnt-- > 0ul)
      {
            i = u32Cyc;
            while (i-- > 0ul)
            {
                ;
            }
      }
    }
    else
    {
         while(u32Cnt-- > 0ul)
         {
            ;
         }
    }
}

这样只是大概的软件延时。如果仅仅做个大概调试,那没问题,但我觉得官方还是应该给出精确
时间的延时。毕竟是官方么,应该要更权威要更谨慎些。
为啥不直接读systick的值来做延时呢?查了下华大HC460的数据手册和参考手册,对systick都无详细的讲解,真是奇怪,难道这个定时器
不入华大的眼,直接几乎给忽略了,给的例程里面也没有。
systick定时器还是挺重要的,可以做OS系统的心跳节拍,也可以作为延时的定时器。下面用systick
做延时:
为了不和模拟的延时冲突,新建delay.h和delay.c。
具体函数如下:
我查了下,虽然华大的HC460相关DEMO没提到systick,但是它也是基于CM4内核的,在core_cm4.h的
面有该寄存器的定义和应该配置应用函数。
寄存器定义:

相关配置函数:


下面我们参照修改下:
初始化函数,配置1ms中断一次,留在这功能将来移植OS可能要用到:
目前中断函数里面不写。
void delay_init(void)
{       
    SysTick->LOAD= (uint32_t)(SystemCoreClock/1000);                /* set reload register 1KHz */
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
    SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */

        SysTick->CTRL= SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_TICKINT_Msk   |
                     SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
}
//us延时
void delay_us(uint32_t u32Cnt)
{
        uint32_t ticks;
    uint32_t told,tnow,tcnt=0;
    uint32_t reload=SysTick->LOAD;//sysTick load1ms中断
       
    ticks=u32Cnt*(SystemCoreClock/1000000);//转换成1us基本单位的节拍
    told=SysTick->VAL;
    while(1)
    {
      tnow=SysTick->VAL;
      if(tnow!=told)
      {

            if(tnow<told)tcnt+=told-tnow;
            else tcnt+=reload-tnow+told;
            told=tnow;
            if(tcnt>=ticks)break;
      }
    }
}
//ms延时
void delay_ms(uint32_t u32Cnt)
{
        uint32_t ticks;
    uint32_t told,tnow,tcnt=0;
    uint32_t reload=SysTick->LOAD;//sysTick load1ms中断
       
    ticks=u32Cnt*(SystemCoreClock/1000);//转换成1ms基本单位的节拍
    told=SysTick->VAL;
    while(1)
    {
      tnow=SysTick->VAL;
      if(tnow!=told)
      {

            if(tnow<told)tcnt+=told-tnow;
            else tcnt+=reload-tnow+told;
            told=tnow;
            if(tcnt>=ticks)break;
      }
    }
}

在main函数的while循环里面检测10us,LED0引脚反转一次,截取示波器波形:
systick延时的抓起图片:



软件延时抓取的延时:


显然systick定时器更胜一筹。
再用串口助手简易测试下时间间隔:
测试程序:
      printf("Begin。。。\r\n");
      LED0_TOGGLE();
      Ddl_Delay1ms(300);
                //delay_ms(300);
      LED1_TOGGLE();
      Ddl_Delay1ms(300);
                //delay_ms(300);
      LED2_TOGGLE();
      Ddl_Delay1ms(300);
                //delay_ms(300);
      LED3_TOGGLE();
      Ddl_Delay1ms(300);
                //delay_ms(300);
      /* de-init if necessary */
      //PORT_DeInit();
                printf("End。。。\r\n");

用systick的延时函数delay_ms做延时:

能看出2次之间间隔几乎就是1.2ms
用软件延时Ddl_Delay1ms做延时:

能看出2次之间间隔几乎就是1.8ms

当然也可能是我自己把频率调到168M的缘故,导致SystemCoreClock / 10000000ul的商
为16.8,结果可能进位还是啥的。这里列出仅仅是参考对应,要求不严格,2种都可用。
PS:
可能是我自己没找到HC32F460关于systick的说明。
如果谁有麻烦上传一份。
好了,今天就到这。


zeshoufx 发表于 2020-9-30 08:37

谢谢分享【华大HC32F460开发板之systick延时函数】

gwsan 发表于 2020-10-11 16:37

非常感谢楼主分享

kxsi 发表于 2020-10-11 16:37

宝贵的经验啊

nawu 发表于 2020-10-11 16:38

帖子内容真的很好

qcliu 发表于 2020-10-11 16:38

正式我需要的 谢谢

tfqi 发表于 2020-10-11 16:38

很好 避免走弯路了

嵌入小菜菜 发表于 2020-10-13 08:50

最近经过各种国产MCU的摧残,一开始我还觉得代码风格不是很好的华大460开发板代码,在我眼里又好了起来。之前时间在调试HC32L130,用了之后我对华大的MCU开始有了好的印象。最近又有点空了,决定再全面整下F460。
老规矩,先看第一个DEMO,gpio输出控制LED的例程。在看

嵌入小菜菜 发表于 2020-10-13 08:51

最近经过各种国产MCU的摧残,一开始我还觉得代码风格不是很好的华大460开发板代码,在我眼里又好了起来。之前时间在调试HC32L130,用了之后我对华大的MCU开始有了好的印象。最近又有点空了,决定再全面整下F460。
老规矩,先看第一个DEMO,gpio输出控制LED的例程。

binoo7 发表于 2021-1-16 14:50

给楼主点赞,我也没有找到关于滴答定时器的相关介绍,感觉是不重视,而且官方给的资料里也没有加入操作系统的介绍,都是一些常规的操作,感觉和STM32还是有一定的差距的

jimton 发表于 2021-1-19 12:43

高手在民间。
国产MCU凑合着用,能实现功能就好,要达到ST的程度还需要几年,同时还得漂亮国配合

小小电子爱好者 发表于 2021-1-20 12:45

还在不停完善中    国产加油

bcrachel 发表于 2021-1-20 16:38

F460库函数里有SysTick_Delay 延时函数,和软件延时在同一个C文件里。

liangzhou1988 发表于 2021-7-23 16:43

很好!

前功尽弃 发表于 2022-1-20 13:25

华大M4的460系列的用户手册我看了,真的还有更新余地,直接把systick的相关说明抛弃了,我找了半天硬是没找到,最后在demo中找相关代码,看得真的是费劲,本来demo配合用户手册搞起来一清二楚。

mdc9 发表于 2022-5-18 17:55

感谢楼主!!结果很准! 附上测试结果





对比华大官方库的延时函数完胜!!没想到官方的误差居然这么大

carpsnow 发表于 2022-5-25 21:35

波形整挺好啊

touser 发表于 2022-5-28 16:50

这个精准性怎么样

deliahouse887 发表于 2022-5-28 17:39

这个定时延时吗

minzisc 发表于 2022-5-28 18:05

比for和while强多了。
页: [1] 2 3 4 5
查看完整版本: 【华大测评】+华大HC32F460开发板之systick延时函数