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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int()
4 k& A4 p& m# r3 m5 _/ |1 b{
6 k5 }$ ]& V6 T0 @  q7 Y// t0_int(&data) ;
/ D) p# ~4 y  M6 c, u7 F8 Wuchar tl ,th ;& m3 Q1 \/ ]2 T3 W. l+ V& e  r
uint temp ;
8 `& y2 r7 |; }2 O# L" e. S4 S8 u$ W/ }if(T0IF)
  S- D3 x8 p2 b7 M& p{& y; n! [/ E' i
  T0IF=0 ;
& _9 |2 y' t* h: `) B( Z  (ds.count)++ ;0 K) }( b: W' E3 j* g, X% Q
  if(ds.count==80)  o4 Z# ~9 G! d4 y( p& p
  {  I0 C5 [3 a2 k& w
   ds.count=0 ;
) a% C6 w( U: _   switch(ds.state)% R, r8 K. g5 C) Y
   {
( x* P0 w" U* v0 G    case 0 :
2 t$ P9 g; C. e     ds.state=1 ;0 z) r  b, F' Y: ~* K0 T+ N5 k
     init_ds18b20() ;
$ R$ v5 {* q* y9 z7 E/ v# Z     write_ds18b20(ROM_SKIP) ;
1 X' Z! G0 x; n# m/ Y     write_ds18b20(MEM_CONVERT) ;
. `* J* _7 M- Z. N$ w2 q- n' Y     break ;
, ^& o3 g; B/ E9 G3 Q' U' J6 c2 \    case 1 :, d- B* W: @$ j; c; i0 R( J) Q
     init_ds18b20() ;
/ g  l0 M4 ~; k' o     write_ds18b20(ROM_SKIP) ;
, r% t/ Y  M1 H* Z     write_ds18b20(MEM_READ) ;
4 v8 p. O+ A1 y* |     tl=read_ds18b20() ;
6 G1 o0 h  `& `  x4 }$ s/ s, b     th=read_ds18b20() ;+ t! ^' B& B6 j5 K* C2 X) ^
     if(!(th&0xf0))
0 c2 }' k6 i0 h" {- U; {! k. c& q! U     {; F8 V* _! j& A3 O% j
      th=th&0x07 ;- x4 n( c: Y$ I/ i. Q; w. ]
      temp=th*256+tl ;) Z  h* V& @! H1 }, S
      ds.data=temp/16 ;6 R/ X* n; X2 C5 ~
     }
8 L7 S6 _. {: J  ?     else
) K1 q% t. u4 V3 h- a. l     { th=th&0x07 ;
* I5 g  B  G9 ~/ B0 F/ \      temp=th*256 +tl ;- t, t' D" l; R' M! s" A8 B; Z
      ds.data=temp/16 ;
' }& F& n3 b  C3 }2 c     }
5 S; K! S6 W. c1 W# V$ x1 l     ds.state=0 ;
9 e$ G" t4 z1 E/ C7 H0 Y5 W     break ;
$ g- l2 b( D5 i7 {7 v7 @+ g    default :# ^; Q4 }2 N! d
     ds.state=0 ;
3 }8 [( N  W' H     break ;
; T+ D* G# q2 C: V% [0 [8 e   }/ {5 n9 o7 f. u/ \
  }
1 Q, ~+ `! [' n# s. K- t  J  int_display1(ds.data) ;( z4 A6 X% l$ E, a  _' `
  TMR0=210 ;
7 p6 e. y; h6 d0 S/ @}  x) P2 O* G, z( Q4 n7 `+ w
}

5 U! y# ~  f6 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-10-13 00:12 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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