找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2295|回复: 9
打印 上一主题 下一主题
收起左侧

32单片机C语言延时函数误差问题

[复制链接]
跳转到指定楼层
楼主
ID:978416 发表于 2023-9-12 11:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
测试这个延时函数1us示波器看实际是3.多us,时钟频率填的72,请教一下这样的误差正常吗,,超过10us以上误差基本还算正常
单片机源程序如下:
#include "delay.h"


/*
适用于STM32F407系列
*/
static uint8_t  fac_us=0;                                                        //us延时倍乘数                          
static uint16_t fac_ms=0;                                                        //ms延时倍乘数,在os下,代表每个节拍的ms数

//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟的1/8
//SYSCLK:系统时钟频率

void delay_init(uint8_t SYSCLK)
{
        HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);                        //SYSTICK_CLKSOURCE_HCLK_DIV8////SYSTICK_CLKSOURCE_HCLK
        fac_us=SYSCLK/8;                                                //不论是否使用OS,fac_us都需要使用
        fac_ms=(uint16_t)fac_us*1000;                                //非OS下,代表每个ms需要的systick时钟数   
}                                       

      

/****************************
** 定时us
** nus: 需要定时的微秒数
**延时nus
**nus为要延时的us数.      
**注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
*****************************/
void delay_us(int32_t nus)
{
        uint32_t temp;                     
        SysTick->LOAD=nus*fac_us;                                 //时间加载                           
        SysTick->VAL=0x00;                                        //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数         
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
        SysTick->VAL =0X00;                                       //清空计数器
}

//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对168M条件下,nms<=798ms
void delay_xms(uint16_t nms)
{
        uint32_t temp;
        SysTick->LOAD=(uint32_t)nms*fac_ms;                        //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                                   //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
        SysTick->VAL =0X00;                                       //清空计数器                     
}

/****************************
** 定时ms
** nms: 需要定时的毫秒数
*****************************/
void delay_ms(int32_t nms)
{
        uint8_t repeat=nms/540;                                                //这里用540,是考虑到某些客户可能超频使用,
                                                                                        //比如超频到248M的时候,delay_xms最大只能延时541ms左右了
        uint16_t remain=nms%540;
        while(repeat)
        {
                delay_xms(540);
                repeat--;
        }
        if(remain)delay_xms(remain);
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2023-9-13 14:38 | 只看该作者
太正常了,1us对于72MHz带流水线的单片机来说太短了,反应慢呗。
回复

使用道具 举报

板凳
ID:123289 发表于 2023-9-13 16:12 | 只看该作者
此类硬延时的时间,取决于CPU的运行时间,它与:
主频、执行指令的条数有关,很不靠谱。原因:
1、延时不线性。例如参数10延时10ms,而参数20未必延时20ms。所以要试参数,象楼主一样用示波器试。
2、程序执行时,遇到中断,被强行多运行了一个中断服务程序。这就随机了,碰运气了。
如果懂汇编、机器码,就能明白延时过程,并能准确计算出延时时间。
回复

使用道具 举报

地板
ID:382454 发表于 2023-9-13 17:31 | 只看该作者
如果想要精准,帮官方的STC生成的时间延时代码。
回复

使用道具 举报

5#
ID:584814 发表于 2023-9-14 09:37 | 只看该作者
单片机要想得到精准延时,需用示波器等进行精确调校,通常都是大致时间可兼容。
回复

使用道具 举报

6#
ID:206581 发表于 2023-9-14 11:38 | 只看该作者
理论计算是没有问题的,但单片机在实际工作是会受环境影响,如果需要精准时间,需要根据实际环境调参数。
回复

使用道具 举报

7#
ID:883242 发表于 2023-9-14 14:01 | 只看该作者
yzwzfyz 发表于 2023-9-13 16:12
此类硬延时的时间,取决于CPU的运行时间,它与:
主频、执行指令的条数有关,很不靠谱。原因:
1、延时不 ...

这说明你根本就不懂什么汇编。

ARM这样带流水线的体系,懂了汇编也算不出准确的延迟时间。
回复

使用道具 举报

8#
ID:1088185 发表于 2023-9-14 15:49 | 只看该作者
这类延时方法,只适合上电后初始化阶段,之后中断一开就不可能做到精准的延时, 用定时器吧
回复

使用道具 举报

9#
ID:1034262 发表于 2023-9-14 15:58 | 只看该作者
精确延时还用软件延时?那么多定时器养着不用干嘛?
回复

使用道具 举报

10#
ID:401564 发表于 2023-9-15 00:02 | 只看该作者
SysTick是可以做到uS级别的
问题出现在你延时函数中的循环上
C语言的循环只是C语言字面上的循环次数,并不是单片机指令的实际执行次数
C语言和机器语言之间的不是直接对等的,并不是说C语言循环几次,汇编指令就执行几次的
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表