找回密码
 注册
关于网站域名变更的通知
查看: 394|回复: 3
打印 上一主题 下一主题

单片机通过定时器来实现多任务,充分利用定时器资源来实现异步处理

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-10-26 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int()
  l9 Q0 c+ I) Q3 {$ ^" d{+ O( g7 k- H1 l  t: f% F: g
// t0_int(&data) ;8 q% d+ H0 ?; C- t
uchar tl ,th ;
- m% `0 [. I, @) @uint temp ;8 C" m& ~7 y+ A9 @
if(T0IF)
- e+ P& V( v. t; M( k{) g  o7 X$ Y" |( c/ o& N6 @5 e1 J
  T0IF=0 ;: y0 `6 o% _' [
  (ds.count)++ ;9 H/ |$ r. b+ E3 S0 c
  if(ds.count==80)
/ N; ]2 X1 |6 X: u+ l8 ~  {1 q( M# v6 n+ j$ y1 s- C- W
   ds.count=0 ;% D: W7 ~6 }9 r. _+ b# F6 y7 G* D
   switch(ds.state)
' V' d- r' [2 ]3 W0 q5 H   {1 H( P1 n$ _' f5 w  Z. p
    case 0 :7 g5 L. z( ^1 ~3 G
     ds.state=1 ;
+ j* Q6 k: ]0 Z! X. P1 y     init_ds18b20() ;+ g+ e6 X7 z8 F1 Q8 K4 F2 u( }$ d  ]
     write_ds18b20(ROM_SKIP) ;
0 r# x+ W' \8 ?) h: B9 `' S2 J     write_ds18b20(MEM_CONVERT) ;
6 P! y  l% \" E' `" D     break ;8 T3 B8 s. `- P1 \
    case 1 :- a- e# X% m4 u; |2 n
     init_ds18b20() ;
1 X3 z6 A: U+ v* M" a4 p     write_ds18b20(ROM_SKIP) ;
( U9 O3 `, h$ i$ J# |& E     write_ds18b20(MEM_READ) ;  m! }- u0 K3 g! A9 l* I
     tl=read_ds18b20() ;2 w$ b( F! G: h2 G- {
     th=read_ds18b20() ;  ~6 D5 V. O- J' ^  |$ }
     if(!(th&0xf0))8 X  I- K$ b5 _' z4 y
     {
) A7 w4 g6 |' Y; h6 _7 x* Y: u6 q/ L8 P3 \      th=th&0x07 ;: n0 s) |4 k' ~0 `: [7 r
      temp=th*256+tl ;. W7 _9 A% Y$ d: Z% X6 K
      ds.data=temp/16 ;
3 ^. {7 _- n& r6 ]     }
* l4 [6 g  t  q2 ?+ P; o3 g     else
! j+ a# Q: Y  ~; |1 W. u# V     { th=th&0x07 ;+ s8 i' q; f7 Q9 \% {6 p
      temp=th*256 +tl ;
- m: y4 b5 W& P  s, [! q  i      ds.data=temp/16 ;7 L" F; N+ u. J* D
     }3 E8 ~; o: z* F2 E
     ds.state=0 ;5 _$ W) z! V" Z; R# J/ B* v$ ^+ z3 |
     break ;# K* ~( p/ Y- G# F
    default :
6 p+ y( y, l. E. O; s     ds.state=0 ;
* @  I" }) W  ^2 ?9 f     break ;
! U  x0 Z* `- ^9 @; e! m; |   }
8 ?, A5 N( A3 T5 B* @& _/ [, U  }
' n. I& f) ~, s* c  int_display1(ds.data) ;
/ R8 R: ?* b( H4 s8 \  TMR0=210 ;
1 d- k9 _! H. u3 ~}! m/ p1 {. O6 i& [4 D
}
: Y: c- Q* b) V' L9 u2 A: G$ P

该用户从未签到

2#
发表于 2021-10-26 16:00 | 只看该作者
如果有等待一定要进行超时检测,来避免死机

该用户从未签到

3#
发表于 2021-10-26 17:42 | 只看该作者
必须使用定时器来控制延时实现动态扫描

该用户从未签到

4#
发表于 2021-10-26 17:43 | 只看该作者
中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-9-11 07:57 , Processed in 0.125000 second(s), 24 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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