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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int()
" L2 O% m! R8 X) U: B4 a6 x6 e{! j; x  f/ l  g3 u0 W
// t0_int(&data) ;
7 |1 Z$ Q! |5 r: ?uchar tl ,th ;' `; X% \6 d/ y0 R5 y% m
uint temp ;
( h7 c! j: p, K7 S& u; Fif(T0IF)9 X. s7 e( ^9 d  F4 m9 m' x" z
{6 r& N( u1 F% F
  T0IF=0 ;( @" r0 M% u' w
  (ds.count)++ ;
9 F$ E' J) n6 Y; }* S4 Q  if(ds.count==80)
6 F7 u' Y3 C6 _+ Y( R, F9 F; o1 [  {8 d0 x- H9 }' ~& S8 }5 w
   ds.count=0 ;8 Z" |3 o* M) U# L" J
   switch(ds.state)2 Z9 r+ g! R% g! r5 R* y' o
   {
9 v5 ~* W4 I* u2 E; f6 K6 i    case 0 :
- O( |. l  {& Z" D! a     ds.state=1 ;
) q# ]/ R% a/ N+ j     init_ds18b20() ;* D3 M3 P5 c# S- H) S
     write_ds18b20(ROM_SKIP) ;
0 {* ^, X% I% `( p+ z- u     write_ds18b20(MEM_CONVERT) ;( [$ H6 ~7 k- n# l8 r! C* C
     break ;
' @  y. O. R# N    case 1 :
) m8 K- Y1 t2 v6 e4 X7 i" t" U     init_ds18b20() ;
, _6 O+ U+ J+ x8 \" h     write_ds18b20(ROM_SKIP) ;. O/ h; d2 L6 K
     write_ds18b20(MEM_READ) ;
# C' `7 V5 p0 W" h2 @0 e2 _     tl=read_ds18b20() ;
. o# f- G/ \7 w     th=read_ds18b20() ;
) }, }" k- u2 Q  f     if(!(th&0xf0))
" q! d6 x7 e  {( W. L1 Q2 ?     {5 X: l! X- f% r4 ?) x$ ~( h" D0 _
      th=th&0x07 ;
! I1 T8 I# Y, M% U' i      temp=th*256+tl ;8 W3 I  c# `! f  Z8 P
      ds.data=temp/16 ;4 J, v9 h: H! u' f
     }
; p1 r9 k/ c1 j# z$ v1 W     else1 D! j4 i0 Q: [8 q' V1 @! Y
     { th=th&0x07 ;1 \" ~! S* H) f1 c+ Q
      temp=th*256 +tl ;  s6 S$ a" `$ k2 G
      ds.data=temp/16 ;4 ]0 r  S" v# h' L5 e1 N
     }9 ^( K7 p2 B6 z. T: @
     ds.state=0 ;; q8 Y( w" i* R" N( e# s0 k& l
     break ;
4 p3 X. y0 U& t- x, L4 j    default :
4 _) j8 I( I6 N! d8 R4 V     ds.state=0 ;
! v: u: Y% u7 E. W  j# L: V/ b- j) n( h) f     break ;/ ]1 {) f: ?6 _: Q5 s0 p
   }
! ~1 N% M2 k" ]7 H, C  }
1 {2 @* f3 m( N0 `& J, Y4 y' R  int_display1(ds.data) ;. p% b0 s2 Z  {9 }6 N
  TMR0=210 ;
; z; l2 t- Z2 O# Y' d}6 K7 p- [! r* ^: t
}
1 r; P# `0 S4 Q

该用户从未签到

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 05:08 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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