打印
[技术问答]

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

[复制链接]
10208|91
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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 load  1ms中断
       
    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 load  1ms中断
       
    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的说明。
如果谁有麻烦上传一份。
好了,今天就到这。


使用特权

评论回复
评论
mdc9 2022-5-18 16:14 回复TA
感谢分享!!确实本人也没找到 嘀嗒的完整驱动,只有ms级别延时,没有us的。现在测试温湿度传感器DHT11就遇到问题了。而且华大 配置时钟和不配置时钟,官方自带的延时也相差很大,测试 /* Initialize Clock */ BSP_CLK_Init(); 不配置,使用默认时钟(8M),100ms延时 实际70ms,但初始化时钟后(200M)100ms实际170ms 
chnchmhgw 2021-7-21 16:17 回复TA
参考大牛分享代码,已在hc32f460上面验证实测,延时函数很精准;多谢! 
buzhang1915 2021-1-5 17:11 回复TA
请问Sysytick的时钟源怎么设置的呢?我也没找到 
沙发
zeshoufx| | 2020-9-30 08:37 | 只看该作者
谢谢分享【华大HC32F460开发板之systick延时函数】

使用特权

评论回复
板凳
gwsan| | 2020-10-11 16:37 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
地板
kxsi| | 2020-10-11 16:37 | 只看该作者
宝贵的经验啊

使用特权

评论回复
5
nawu| | 2020-10-11 16:38 | 只看该作者
帖子内容真的很好

使用特权

评论回复
6
qcliu| | 2020-10-11 16:38 | 只看该作者
正式我需要的 谢谢

使用特权

评论回复
7
tfqi| | 2020-10-11 16:38 | 只看该作者
很好 避免走弯路了

使用特权

评论回复
8
嵌入小菜菜| | 2020-10-13 08:50 | 只看该作者
最近经过各种国产MCU的摧残,一开始我还觉得代码风格不是很好的华大460开发板代码,在我眼里又好了起来。之前时间在调试HC32L130,用了之后我对华大的MCU开始有了好的印象。最近又有点空了,决定再全面整下F460。
老规矩,先看第一个DEMO,gpio输出控制LED的例程。在看

使用特权

评论回复
9
嵌入小菜菜| | 2020-10-13 08:51 | 只看该作者
最近经过各种国产MCU的摧残,一开始我还觉得代码风格不是很好的华大460开发板代码,在我眼里又好了起来。之前时间在调试HC32L130,用了之后我对华大的MCU开始有了好的印象。最近又有点空了,决定再全面整下F460。
老规矩,先看第一个DEMO,gpio输出控制LED的例程。

使用特权

评论回复
10
binoo7| | 2021-1-16 14:50 | 只看该作者
给楼主点赞,我也没有找到关于滴答定时器的相关介绍,感觉是不重视,而且官方给的资料里也没有加入操作系统的介绍,都是一些常规的操作,感觉和STM32还是有一定的差距的

使用特权

评论回复
11
jimton| | 2021-1-19 12:43 | 只看该作者
高手在民间。
国产MCU凑合着用,能实现功能就好,要达到ST的程度还需要几年,同时还得漂亮国配合

使用特权

评论回复
12
小小电子爱好者| | 2021-1-20 12:45 | 只看该作者
还在不停完善中    国产加油

使用特权

评论回复
13
bcrachel| | 2021-1-20 16:38 | 只看该作者
F460库函数里有SysTick_Delay 延时函数,和软件延时在同一个C文件里。

使用特权

评论回复
14
liangzhou1988| | 2021-7-23 16:43 | 只看该作者
很好!

使用特权

评论回复
15
前功尽弃| | 2022-1-20 13:25 | 只看该作者
华大M4的460系列的用户手册我看了,真的还有更新余地,直接把systick的相关说明抛弃了,我找了半天硬是没找到,最后在demo中找相关代码,看得真的是费劲,本来demo配合用户手册搞起来一清二楚。

使用特权

评论回复
16
mdc9| | 2022-5-18 17:55 | 只看该作者
感谢楼主!!  结果很准! 附上测试结果





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

使用特权

评论回复
17
carpsnow| | 2022-5-25 21:35 | 只看该作者
波形整挺好啊

使用特权

评论回复
18
touser| | 2022-5-28 16:50 | 只看该作者
这个精准性怎么样

使用特权

评论回复
19
deliahouse887| | 2022-5-28 17:39 | 只看该作者
这个定时延时吗  

使用特权

评论回复
20
minzisc| | 2022-5-28 18:05 | 只看该作者
比for和while强多了。  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝