标题: 关于STM32单片机自己写delay函数的问题 [打印本页]

作者: 菜菜的周某人    时间: 2022-5-12 17:00
标题: 关于STM32单片机自己写delay函数的问题
大佬们,虽然说STM32单片机自带一个嘀嗒定时器可以实现延迟,但是我现在想在KEIL里写了一个1s的delay延迟函数,然后我想通过debug界面测试这个函数的执行时间,调整delay函数里的循环变量次数使其接近1s,延迟函数代码(如图1),但是现在问题是当我用Debug-Use Simulator调试时(如图2),程序便进入到systemInit()系统初始化函数里(如图3),这里是等待时钟源稳定,后面我将其屏蔽掉(我不知道这么做对不对),程序是可以执行,但是软件测出来是1s,而烧录到板子上观看LED闪烁,时间根本不是1s,闪烁频率极快,这是为什么呢?
第二个问题是,后面我放弃了使用Debug-Use Simulator调试,而是使用(如图4)DAP仿真器进行调试,在trace界面设置72Mhz(如图5),因为F103系列主频是72Mhz,但是出现一个奇怪的现象,delay函数debug后我测出1次循环是1ms,所以我将循环变量i分别设置为1次、10次、100次、1000次、10000次,理论上应该是1ms、10ms、100ms、1s、10s延时,但是在100次以下时结果正确,当1000次及以上时实际结果只能达到0.7s和7s多(如图6-15),这个又是什么原因导致的?是我软件哪里设置错误了吗?希望各位大佬批评指正!

图片14.png (352.57 KB, 下载次数: 37)

图片14.png

图片12.png (349.18 KB, 下载次数: 38)

图片12.png

图片13.png (353.16 KB, 下载次数: 45)

图片13.png

图1.png (32.72 KB, 下载次数: 41)

图1.png

图2.png (104.67 KB, 下载次数: 45)

图2.png

图3.png (214.25 KB, 下载次数: 43)

图3.png

图4.png (106.6 KB, 下载次数: 51)

图4.png

图5.png (92.95 KB, 下载次数: 36)

图5.png

图片6.png (338.84 KB, 下载次数: 43)

图片6.png

图片7.png (353.11 KB, 下载次数: 44)

图片7.png

图片8.png (344.74 KB, 下载次数: 49)

图片8.png

图片9.png (346.49 KB, 下载次数: 36)

图片9.png

图片10.png (339.89 KB, 下载次数: 51)

图片10.png

图片11.png (350.1 KB, 下载次数: 47)

图片11.png

图片15.png (352.9 KB, 下载次数: 38)

图片15.png

作者: xuyaqi    时间: 2022-5-12 18:27
仿真会影响延时,调试可以用让输出脚翻转,逻辑分析仪测试。
作者: zxbzsm    时间: 2022-5-12 18:30
还是用滴答定时器靠谱
作者: 菜菜的周某人    时间: 2022-5-12 19:33
xuyaqi 发表于 2022-5-12 18:27
仿真会影响延时,调试可以用让输出脚翻转,逻辑分析仪测试。

感谢您的回复,我还想问下,如果仿真会影响延时,那是KEIL软件的问题还是DAP仿真器通信的问题?以及如果这样说,那岂不是说用Keil软件debug查看执行时间这一方法根本行不通?或者说我想要得到粗略1s的延迟,除了用定时器外,就没有其他方法吗?因为我无法知道我的dealy函数执行时间是多少!
作者: Y_G_G    时间: 2022-5-12 19:53
明明有稳定精确的延时,为什么要自己写呢?
哪怕是8051,1秒钟延时也是不会用软件延时的
有时间折腾这个,还不如玩几个DIY小东西

作者: Hephaestus    时间: 2022-5-12 20:16
stm32的ms级延迟用systick。
作者: 菜菜的周某人    时间: 2022-5-12 21:28
Y_G_G 发表于 2022-5-12 19:53
明明有稳定精确的延时,为什么要自己写呢?
哪怕是8051,1秒钟延时也是不会用软件延时的
有时间折腾这个,还 ...

感谢您的回复,我不是执着于1s的软件延时,我只是在想如果软件debug查看执行时间这一方法不准确,那么写IC的开发时序图(比如DS18B20的单总线时序、TFLCD等)的需要延时时,如何确定我的时序正确呢?当然在32内部有嘀嗒定时器可准确延迟,那么其他MCU呢,其他MCU可没有嘀嗒定时器。
作者: Y_G_G    时间: 2022-5-12 22:00
菜菜的周某人 发表于 2022-5-12 21:28
感谢您的回复,我不是执着于1s的软件延时,我只是在想如果软件debug查看执行时间这一方法不准确,那么写I ...

目前为止,我还没有用过没有定时器的单片机
对于一个单片机程序,延时时间达1秒的,肯定是不能用软件延时的,难道你要让程序什么都不做,就在那干等1秒吗?
像18b20p 这种需要那么长时间的时序,肯定是要通标志位或者全局变量来处理时序的嘛
如果非得执着于软件延时1秒,那仿真肯定不行,就像说的一样,STM32有仿真,那别的单片机不一定能仿真
那肯定是示波器了
先随便写一个延时函数,大概是1mS左右,然后用示波器看一下这1mS的真正延时,不断的调整,直到最接近1mS然后把这个延时循环放到另一个循环中,参数调用就行了

假设,我已经调节好了一个1mS延时,它是这样的
i = 32;
j = 40;
do
{
        while (--j);
}         while (--i);

那就把这循环放到另一个循环中,做成一个函数就可以了,
这样的函数调用参数会用到一定的时间,整个延时的时间可能会有误差,再通过微调就差不多了

void Delay_ms(unsigned int a)               
{
        unsigned char i, j;
        for(a;a>0;a--)
            {
                i = 32;
                j = 40;
                do
                {
                        while (--j);
                }         while (--i);
          }
}


作者: 菜菜的周某人    时间: 2022-5-12 22:03
Y_G_G 发表于 2022-5-12 22:00
目前为止,我还没有用过没有定时器的单片机
对于一个单片机程序,延时时间达1秒的,肯定是不能用软件延时的 ...

感谢您的回复!
作者: Hephaestus    时间: 2022-5-12 22:46
delay_1ms()里面
u16 j,k要加volatile属性。
作者: munuc_w    时间: 2022-5-13 16:08
软件延时受程序执行情况及中断的影响,是不准的。
作者: yzwzfyz    时间: 2022-5-14 16:59
1、程序最终会被编译成运行代码,也是汇编程序。
2、在非流水取指的系统中(如51系统),每条指令运行的时间是固定的,是可以事先计算出运行的总时间的。所以仿真器算出来比较准。
3、32系统是指令流水结构,当你执行当前指令时,下条指令就已被取出了,这样速度快。但前提是必须知道下条指令放在哪里。所以遇到跳转指令就不好流水了。也就是说,同样的批令,如果流水执行就快,不流水就慢,如果仿真器无法识别下条指令是不是流水执行,自然就算不准了。
4、1ms的子程序,调用1000次,不会是1S。因为每次调用要判断是否结束了,会多运行:调用指令1000次、判断指令1000次。而这些指令也是要占用时间的。

作者: 菜菜的周某人    时间: 2022-5-16 17:12
yzwzfyz 发表于 2022-5-14 16:59
1、程序最终会被编译成运行代码,也是汇编程序。
2、在非流水取指的系统中(如51系统),每条指令运行的时 ...

感谢您的回复!
作者: 菜菜的周某人    时间: 2022-5-16 17:12
munuc_w 发表于 2022-5-13 16:08
软件延时受程序执行情况及中断的影响,是不准的。

感谢您的回复!




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1