OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9090|回复: 12

非阻塞的方法实现delay函数

[复制链接]

2

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-11-8
在线时间
9 小时
发表于 2022-11-22 15:20:16 | 显示全部楼层 |阅读模式
1金钱
众所周知,delay函数是通过while循环计数以达到设定的时间,这种方法会造成STM32的阻塞,影响性能。请教一下各位带佬,如何通过非阻塞的方法实现delay函数。

最佳答案

查看完整内容[请看2#楼]

http://t.zoukankan.com/LittleTiger-p-4685581.html https://blog.csdn.net/weixin_33048721/article/details/117211787?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-117211787-blog-123053454.pc_relevant_multi_platform_whitelistv4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-117211787-blog-123053454 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8206
金钱
8206
注册时间
2020-5-11
在线时间
3700 小时
发表于 2022-11-22 15:20:17 | 显示全部楼层
专治疑难杂症
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8206
金钱
8206
注册时间
2020-5-11
在线时间
3700 小时
发表于 2022-11-22 15:35:26 | 显示全部楼层
状态机了解一下。
另外还可参考一下: 时间触发嵌入式系统设计模式、Protothread 机制、小小调度器.
专治疑难杂症
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-11-8
在线时间
9 小时
 楼主| 发表于 2022-11-22 16:05:59 | 显示全部楼层
LcwSwust 发表于 2022-11-22 15:35
状态机了解一下。
另外还可参考一下: 时间触发嵌入式系统设计模式、Protothread 机制、小小调度器.

谢谢指导,有没有状态机实现非阻塞的文章或者学习资料呀,网上相关的资料好像很少。
回复

使用道具 举报

9

主题

218

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1364
金钱
1364
注册时间
2020-5-12
在线时间
381 小时
发表于 2022-11-22 17:29:00 | 显示全部楼层
有个函数放在1毫秒里循环执行,如果这个函数执行了20次,那就是延时了20毫秒
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-11-8
在线时间
9 小时
 楼主| 发表于 2022-11-22 19:27:17 | 显示全部楼层
LcwSwust 发表于 2022-11-22 16:22
http://t.zoukankan.com/LittleTiger-p-4685581.html
https://blog.csdn.net/weixin_33048721/article/ ...

谢谢!
回复

使用道具 举报

2

主题

446

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4133
金钱
4133
注册时间
2018-5-14
在线时间
902 小时
发表于 2022-11-23 08:49:02 | 显示全部楼层
使用调度器太复杂了,最简单的办法用状态机实现。列如
switch(系统状态){
case 初始化:

if(初始化成功)
{
系统状态=执行逻辑1;
开启定时器;
}  
else
  系统状态=系统故障;
break;
case 执行逻辑1:

  if(定时器结束)
     系统状态=执行逻辑2:
break;
case 执行逻辑2:

break;
case 系统故障:

break;
defaut:


}
回复

使用道具 举报

3

主题

117

帖子

0

精华

高级会员

Rank: 4

积分
559
金钱
559
注册时间
2018-10-3
在线时间
107 小时
发表于 2022-11-23 09:03:19 | 显示全部楼层
最简单的延时
count++;  这个放定时器中断里,比如1ms中断

int main(){
u32 taskTimerCount = 100+count;
while(1)
{
      if(taskTimerCount < count)
      {
            taskTimerCount  = 100+count; //这里就实现了延时  100ms调用一次任务。
            task();
      }
}
}
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-11-8
在线时间
9 小时
 楼主| 发表于 2022-11-23 14:38:41 | 显示全部楼层
姚先起 发表于 2022-11-23 08:49
使用调度器太复杂了,最简单的办法用状态机实现。列如
switch(系统状态){
case 初始化:

大概明白了,想问一下,swith函数外面要嵌套一个while循环吗,如果我要用DHT11检测室内温湿度,使用DHT11_Read_Bit读取每一位的数据(通过从低电平跳变成高电平的时间长度判断数据位是0还是1,使用到了Delay函数),同时将数据显示在LCD屏幕上,这个系统状态是不是既包括DHT11,也包括LCD的呀,如何做到非阻塞呀。
回复

使用道具 举报

2

主题

446

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4133
金钱
4133
注册时间
2018-5-14
在线时间
902 小时
发表于 2022-11-24 09:04:09 | 显示全部楼层
utopia53 发表于 2022-11-23 14:38
大概明白了,想问一下,swith函数外面要嵌套一个while循环吗,如果我要用DHT11检测室内温湿度,使用DHT11 ...

最外层大循环要有的,然后给你的流程图改成状态转移图,根据不同的状态完成不同状态下的处理和转移条件判断。比如你串口发送了命令,等从机返回,也可以分为主机发送状态,主机发送完成状态,等待串口接收状态,串口接收完成状态和协议处理状态。项目中不要出现阻塞的delay,delay出现了以后,很多任务的运行周期都会相互干扰,比如通信时不触发按键等,按键检测时通信不响应等。
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-11-8
在线时间
9 小时
 楼主| 发表于 2022-11-24 20:44:58 | 显示全部楼层
姚先起 发表于 2022-11-24 09:04
最外层大循环要有的,然后给你的流程图改成状态转移图,根据不同的状态完成不同状态下的处理和转移条件判 ...

谢谢,我好好参悟参悟。
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2022-11-24 21:25:09 | 显示全部楼层
utopia53 发表于 2022-11-23 14:38
大概明白了,想问一下,swith函数外面要嵌套一个while循环吗,如果我要用DHT11检测室内温湿度,使用DHT11 ...

Dh11 只有等待应答需要延时1ms  其他延时更短  直接延时就好了   屏幕显示10HZ就够了 弄个优先级低的循环慢慢显示就好了
回复

使用道具 举报

2

主题

74

帖子

0

精华

高级会员

Rank: 4

积分
835
金钱
835
注册时间
2019-12-14
在线时间
53 小时
发表于 2022-11-26 07:44:17 | 显示全部楼层
学习了,延时方法还挺多的。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 21:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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