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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int(), t$ u& V" E. U( s) h
{- q' i" D, v, h4 P) C& @& p( {
// t0_int(&data) ;
  f. e( j; Y4 Fuchar tl ,th ;" A( F- p9 Q. a& E) c. w
uint temp ;# p1 L1 e: H# y1 a/ T
if(T0IF)
# H' ~. E8 L2 Y: l/ y! B$ [8 `{7 X, }% n+ o+ S) q% R( o6 l1 c
  T0IF=0 ;
' K. [  T, l# k: W5 W$ N, K  (ds.count)++ ;
) h+ z# T, C6 F& z! {: y% H8 Q  if(ds.count==80)
5 |3 S2 A4 {1 A  {5 w. ?, [4 l2 s. |# h
   ds.count=0 ;. L, s) s5 s# V+ ~' C. W/ ^
   switch(ds.state)
3 |5 h: ]! W1 H8 R/ z   {
& ~; W" S3 u- j) [, i0 N/ ?    case 0 :
) ^- Z# y/ \; e     ds.state=1 ;/ s/ T7 w7 D5 a7 j2 `9 x# }
     init_ds18b20() ;0 G3 f6 e' |% P4 z2 Z
     write_ds18b20(ROM_SKIP) ;! s1 k# R6 e, g* E7 X
     write_ds18b20(MEM_CONVERT) ;
3 h* _& O' p' @2 I     break ;
; Q) V7 D& r, u    case 1 :, Z) S3 j- c- c' q; e2 ~( {
     init_ds18b20() ;
+ M+ E* Y5 q7 v$ X# h2 a+ C2 t     write_ds18b20(ROM_SKIP) ;+ E+ ~9 j" m' A6 k$ g% U5 |0 B
     write_ds18b20(MEM_READ) ;
8 _# n: q7 c, L: \     tl=read_ds18b20() ;
9 R% y7 D4 A  r4 w8 E     th=read_ds18b20() ;% T/ m9 Z+ b! U- }: |
     if(!(th&0xf0)): G8 @0 r; ~. F$ Q' ^! c  r
     {$ n, j: U$ M9 w9 y
      th=th&0x07 ;6 B! v) l1 D1 l$ W% }' X) v; o
      temp=th*256+tl ;3 s2 O$ w0 K' E" J2 f* D
      ds.data=temp/16 ;; F9 {9 ~8 T  I! W5 \$ s
     }
. C# W/ c/ b7 ?- h7 e2 z     else9 t) [* e' Y2 {- Z7 ^* ^
     { th=th&0x07 ;0 a- J0 h& j% x2 P/ d* X1 o1 B
      temp=th*256 +tl ;% Z' x8 @( Z3 X6 o: y5 G" M
      ds.data=temp/16 ;
' B& g. V) b1 A& Y& g3 Q: o     }2 p5 u" s* K( f
     ds.state=0 ;
) N; G) T9 i, n  ^+ [& o( s  R     break ;
% n2 x: O! ^) E3 ~) b    default :& f1 x/ E% l) j' |0 Q$ [5 i) _
     ds.state=0 ;
' i, P2 L8 ~( u: k     break ;, i1 R+ A2 v5 [& V6 l8 j' ?
   }
+ C9 a1 h7 i6 i  }8 O4 l  w2 Y$ j; _5 j# L& c" Q
  int_display1(ds.data) ;
4 U1 q0 g7 A* J9 D  TMR0=210 ;
1 z9 y9 }0 P) L% N}
$ B; e& \' [2 g* @7 O}

. _( K' b' G' G9 q9 c5 k2 A6 \

该用户从未签到

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 18:22 , Processed in 0.156250 second(s), 24 queries , Gzip On.

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

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

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