OpenEdv-开源电子网

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

ucos ii 编程的问题,如何避免关中断呢?

[复制链接]

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
发表于 2014-12-22 11:28:17 | 显示全部楼层 |阅读模式
5金钱
     是这样的,项目使用ucos ii为rtos,其中一个进程使用DHT11测量温度,但是由于DHT11读写时序不应该被打扰,所以我就在读DHT11模块的时候关中断,但是又发现关中断之后DHT11程序中的delay函数(使用TIM3中断延时)不能用了。
   
  我现在用的方法是在操作DHT11的时候失能所有除了TIM3以外其他的中断。

  感觉我用的方法太蠢了,各位大虾有没有什么好一点的方法呢?
  

最佳答案

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

回复【5楼】DChipNau: --------------------------------- 在循环里读定时器TIM3的计数值,通过逻辑判断是否超时。 比如说TIM3的数值是1000,30us后增加为1030,则只需要不断读取判断TIM3是否>1030,如果是的话则定时时间到。 楼主自己做一个延时封装函数,应该不难。 当然如果没有关调度的话,可能会出现延时远远超过30us的情况。就看楼主能不能接受啦。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2014-12-22 11:28:18 | 显示全部楼层
回复【5楼】DChipNau:
---------------------------------
在循环里读定时器TIM3的计数值,通过逻辑判断是否超时。
比如说TIM3的数值是1000,30us后增加为1030,则只需要不断读取判断TIM3是否>1030,如果是的话则定时时间到。
楼主自己做一个延时封装函数,应该不难。

当然如果没有关调度的话,可能会出现延时远远超过30us的情况。就看楼主能不能接受啦。
业余程序玩家。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-12-22 11:28:18 | 显示全部楼层
1,不要用中断方式实现delay
2,重写一个delay(非中断方式)
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1840
金钱
1840
注册时间
2014-6-27
在线时间
982 小时
发表于 2014-12-22 11:54:31 | 显示全部楼层
干嘛要关中断,干嘛要用delay,不是有调度么,调度不是延时吗?程序处理一下不就行了嘛。
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13135
金钱
13135
注册时间
2012-11-26
在线时间
3814 小时
发表于 2014-12-22 12:13:17 | 显示全部楼层
直接进入临界段函数  防止打扰
学无止境
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13135
金钱
13135
注册时间
2012-11-26
在线时间
3814 小时
发表于 2014-12-22 12:13:37 | 显示全部楼层
critical
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-22 12:40:26 | 显示全部楼层
回复【2楼】TinyBoy:
---------------------------------
之所以不用ucos中自带的延时函数的原因:因为DHT11模块对时间要求比较精确,比如读数据的时候可能需要精确地延时30us来判断数据,但是如果用ucos自带的延时函数的话,很容易出现DHT11模块的进程被其他优先级更高的进程占用,导致延时过长,而让读数据失败的情况,所以才想到了关中断。
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-22 12:41:52 | 显示全部楼层
回复【3楼】jermy_z:
---------------------------------
ucos的临界区也是直接屏蔽了除NMI和硬fault之外的中断来实现的,但此时我的程序还是需要TIM3中断。。。。。。
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13135
金钱
13135
注册时间
2012-11-26
在线时间
3814 小时
发表于 2014-12-22 13:04:54 | 显示全部楼层
回复【6楼】DChipNau:
---------------------------------
哦  直接用os的delay做吧
学无止境
回复

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2014-12-22 14:32:15 | 显示全部楼层
关调度就行,楼主想多了。
于20150522停用该账号:http://www.microstar.club
回复

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1840
金钱
1840
注册时间
2014-6-27
在线时间
982 小时
发表于 2014-12-22 15:18:24 | 显示全部楼层
回复【5楼】DChipNau:
---------------------------------
我没说不能延时几十us的,这些细节问题不影响运行,而是在整体上安排合不合理的问题。
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-22 18:39:23 | 显示全部楼层
回复【8楼】styleno1:
---------------------------------
怎么关调度呢?
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-22 18:40:51 | 显示全部楼层
回复【9楼】TinyBoy:
---------------------------------
额,那具体该怎么弄呢?
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-23 14:36:40 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
竟然是站长亲自出现  受教了
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-23 14:36:52 | 显示全部楼层
回复【12楼】ofourme:
---------------------------------
好方法  受教了
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-23 15:35:04 | 显示全部楼层
回复【12楼】ofourme:
---------------------------------
但是这么改会在OSTimeDlyHMSM里抛出硬fault  这是为什么呢?
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2014-12-23 18:00:20 | 显示全部楼层
 回复【16楼】 DChipNau :
---------------------------------
你程序哪里写错了吧?参考原子的代码吧,里面有延时微秒的方法。或者参考我的stm32代码,用systick做定时器:

[mw_shl_code=c,true]#define HW_TICK_PER_SECOND  (100) // 不能高于1000,否则hw_delay_us()要做相应的处理。 #define HW_CLOCK_US() (u32)(SysTick->VAL)/9 #define CPU_HZ  (72000000UL) #define USC_HZ  (CPU_HZ/8) #define USC_RANGE (USC_HZ/HW_TICK_PER_SECOND) #define USC_MAX (USC_RANGE-1) #define USPS    (1000000UL) // 每秒 USPS 微秒 #define USPT    (USPS/HW_TICK_PER_SECOND) // 每tick USPT 微秒 #define USC_CPUS    (USC_HZ/USPS) // cycles/us @ USC [/mw_shl_code] [mw_shl_code=c,true]void hw_usc_init(u8 bReInit) { static u8 bInited = 0; if(bReInit || bInited==0) // 需要强制重新初始化或是没有经过初始化 { bInited = 1; SysTick->CTRL&= 0xfffffffb; //bit2清空,选择外部时钟,也即HCLK/8 SysTick->LOAD = USC_MAX; SysTick->VAL = USC_MAX; // write to clean SysTick->CTRL = 0x01 ; //开始倒数 不产生中断 } } void hw_tick_start(void) { hw_usc_init(0); SysTick->CTRL = 0x03; // 启动systick并产生中断 } void hw_delay_us(u16 us) { u32 start ,target,cur; while(us > 500) // 防止us超过systick周期。(假设systick周期超过500us) { hw_delay_us(500); us -= 500; } start = SysTick->VAL; target = (start-us*USC_CPUS); if(start<target) // 溢出,调整target的值。target不能等于start。 { target += USC_RANGE; do { cur = SysTick->VAL; }while(cur<=start || target<cur); } else // target <= start { do { cur = SysTick->VAL; }while(target<cur&&cur<=start); // 假设target为一个很小的值,则cur有可能在循环周期内溢出而大于target,故须加上cur<=start的条件 } }[/mw_shl_code]




业余程序玩家。
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2014-10-22
在线时间
0 小时
 楼主| 发表于 2014-12-23 22:46:33 | 显示全部楼层
回复【17楼】ofourme:
---------------------------------
谢谢大神
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-27 14:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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