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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int()3 p, f7 z; X  j
{* o  X! }6 B) g  Z' v* }# {
// t0_int(&data) ;$ I+ D( {2 |( A3 n" F) V  Y
uchar tl ,th ;
( J( n) `: f9 I" Z  z2 I2 Euint temp ;( Y1 L* L" {0 T5 t
if(T0IF), N% \6 C( R5 t
{
$ [$ o5 G$ b" G  T0IF=0 ;
+ m+ |1 X0 P  C; V7 |% F  (ds.count)++ ;& i9 K. W0 Z( f. G" Y5 j) P3 H
  if(ds.count==80)0 Z; U- O8 k$ q- v" [3 B
  {
7 T- Z8 f# J9 p. l! s   ds.count=0 ;
0 ], ]7 v3 T. H7 M   switch(ds.state)
, s/ h4 `9 V7 O+ p: C# j3 ~* z! V1 L   {
8 u+ k- K0 B2 f$ l    case 0 :
) f+ z7 o* c7 \+ t! V9 H, d4 @     ds.state=1 ;2 n" h7 e& [8 }0 y3 b2 M1 k( [
     init_ds18b20() ;" K: Q+ V1 N9 l2 g6 y  e6 q
     write_ds18b20(ROM_SKIP) ;
# g: i7 ~& K8 Q1 E     write_ds18b20(MEM_CONVERT) ;
" \% S, q4 U' _! }4 B% P; m9 j) a     break ;
+ g2 @& X' o5 [: l, G0 _* G  L    case 1 :
- x3 |4 ?! d' P' u8 ^     init_ds18b20() ;# ~( t+ ~" |5 x* L2 n; s0 H
     write_ds18b20(ROM_SKIP) ;. v, z$ `: z) C
     write_ds18b20(MEM_READ) ;
3 H/ H! j# S4 o4 R     tl=read_ds18b20() ;
# H3 K) F* _5 d- K' I" c     th=read_ds18b20() ;
! G: ]0 `' o& r" r, ]     if(!(th&0xf0))6 i% w( B( d1 b) s8 X( {- Q) ?
     {) e* L4 }. O1 q; B
      th=th&0x07 ;
( H4 S0 y2 \( a) a, }6 ]" Z/ i      temp=th*256+tl ;* q, J- e% d- f& m! K+ c
      ds.data=temp/16 ;
+ {( w8 i. Y: l% F     }
) l& H( ~8 d* x9 X9 Z0 Q     else+ w# e) k2 O6 Y' {! q  d5 F: w
     { th=th&0x07 ;
0 t2 E$ H. l. s      temp=th*256 +tl ;2 o0 j1 d$ a# X: o1 i' J! z
      ds.data=temp/16 ;- e7 C$ H2 \! D- F# L
     }0 u  k" a- E6 S' S1 P3 H! P) {
     ds.state=0 ;1 Y4 [5 R7 f; w
     break ;. j* i/ a3 d0 U
    default :  D4 o# n, D" r* U1 Z6 G
     ds.state=0 ;
! Y% D' i$ K# v     break ;
0 h7 {5 m' J# x0 V# n7 J% Z$ `   }
: H! k) T- U3 u  }7 m; v8 d6 M# ~7 M* k1 h: ]+ D
  int_display1(ds.data) ;* Y% q4 ]% `4 H; f* ?4 Z8 ^8 H
  TMR0=210 ;; R* }* a5 u$ v- y( n3 _
}1 t* ?) w. `6 L1 O" P. h
}
# y8 k( l) K3 \3 G( \

该用户从未签到

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-11-24 04:03 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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