OpenEdv-开源电子网

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

Freertos 在通过ds18b20采集温度时,自带的延时函数出现问题导致程序卡死的问题

[复制链接]

3

主题

9

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-1-1
在线时间
5 小时
发表于 2024-2-23 00:55:34 | 显示全部楼层 |阅读模式
1金钱
问题描述:在用freertos创建任务通过DS18B20采集温度时,正点原子自带的delay_us函数会失效、导致ds18b20初始化失败,从而无法跳转出DS18B20初始化的情况,求助大神们是怎么在freertos下进行us级别的延时的

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8184
金钱
8184
注册时间
2020-5-11
在线时间
3697 小时
发表于 2024-2-24 10:35:13 | 显示全部楼层
似乎有两个delay_us函数,你用的哪个?
傲游截图20240224103327.jpg 傲游截图20240224103342.jpg

专治疑难杂症
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-1-1
在线时间
5 小时
 楼主| 发表于 2024-2-24 23:05:41 | 显示全部楼层
大佬你好,我用的是第二个,第一个由于例程给的是uscos,我不知道怎么改成freertos,麻烦大佬指点一下
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8184
金钱
8184
注册时间
2020-5-11
在线时间
3697 小时
发表于 2024-2-26 13:15:40 | 显示全部楼层
本帖最后由 LcwSwust 于 2024-2-26 13:17 编辑
1240134740 发表于 2024-2-24 23:05
大佬你好,我用的是第二个,第一个由于例程给的是uscos,我不知道怎么改成freertos,麻烦大佬指点一下

两个原理不一样,建议用第一个,去掉OS相关代码或自己查一下如何替换,或在延时期间关闭全局中断。

第一个例子就像机械表,比如让你等10秒钟,你就盯着秒针看,它转过10个小格子就完成了。
第二个例子就像运动员用的秒表,先清零,然后启动,计时10秒,时间到,就给它停止并清零。

第一个例子可供多人同时用,因为大家都只是读取秒针,并未影响到钟表。
第二个例子在多人同时用时就有问题了,比如路人甲等10秒,路人乙需要等20秒,甲的时间先到,甲就把计时器停了,乙就一直等了。

专治疑难杂症
回复

使用道具 举报

5

主题

66

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2023-6-26
在线时间
53 小时
发表于 2024-2-26 14:41:13 | 显示全部楼层
看下原子的demo,freertos也是有列程的,原因上面的大哥已经说得很明白了
回复

使用道具 举报

8

主题

168

帖子

0

精华

高级会员

Rank: 4

积分
557
金钱
557
注册时间
2015-7-4
在线时间
104 小时
发表于 2024-3-15 09:03:11 | 显示全部楼层
LcwSwust 发表于 2024-2-26 13:15
两个原理不一样,建议用第一个,去掉OS相关代码或自己查一下如何替换,或在延时期间关闭全局中断。

第 ...

通俗易懂,到位,瞬间明白了
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2021-4-7
在线时间
15 小时
发表于 2024-3-15 15:10:36 | 显示全部楼层
C:\Users\夜暗心明\Desktop\android
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2021-4-7
在线时间
15 小时
发表于 2024-3-15 15:12:40 | 显示全部楼层
void delay_us_freertos(u32 nus)
{
       u32 ticks;
       u32 told,tnow,reload,tcnt=0;
       if((0x0001&(SysTick->CTRL)) ==0)    //定时器未工作
              vPortSetupTimerInterrupt();  //初始化定时器

       reload = SysTick->LOAD;                     //获取重装载寄存器值
       ticks = nus * (SystemCoreClock / 1000000);  //计数时间值
       told=SysTick->VAL;                          //获取当前数值寄存器值(开始时数值)

       while(1)
       {
              tnow=SysTick->VAL;          //获取当前数值寄存器值
              if(tnow!=told)              //当前值不等于开始值说明已在计数
              {         

                     if(tnow<told)             //当前值小于开始数值,说明未计到0
                          tcnt+=told-tnow;     //计数值=开始值-当前值

                     else                  //当前值大于开始数值,说明已计到0并重新计数
                            tcnt+=reload-tnow+told;   //计数值=重装载值-当前值+开始值  (已
                                                      //从开始值计到0)

                     told=tnow;                //更新开始值
                     if(tcnt>=ticks)break;     //时间超过/等于要延迟的时间,则退出.
              }
       }     
}

可以试试这个
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 11:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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