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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个4连体数码管显示从DS18b20中采集的温度值,4位连体数码管当然只能使用动态扫描方法来显示数据,并且这个动态扫描不能在主程序中执行,因为在主程序动态扫描效果很容易收到中断程序的影响,而使显示效果下降,因此必须使用定时器来控制延时实现动态扫描,但是ds18b20的读写时序对延时的精度要求也是相当高的,如果在主程序中,中断程序造成的延时必然会对ds18b20采集数据的延时精确度造成干扰,而不能采集正确的数据!因此DS18b20采集数据的程序也不能够放在主程序中,当然我们可以使用两个定时器来实现!这里我们使用一个定时器来实现,由于DS18B20温度转换时间比较长12位精度的温度转换需要接近1秒的时间,这对动态扫描是无法容忍的,可行的办法是将启动转换,读取温度值放在同一个中断的不同状态,也就是在任务中实现状态机,从而避免了在中断中出现长时间的等待,而影响系统的性能!以下中断函数的具体实现:
void interrupt main_int()
5 X* c7 t: @/ x- X1 w0 D2 K{+ P1 H9 n, k# V5 o
// t0_int(&data) ;. x$ {( h$ F( f, D/ L# d- [; {  l4 k
uchar tl ,th ;: o: [+ v* _. @+ E, o/ d) T5 U
uint temp ;
9 u8 n  _! o$ ?8 W. E. ^3 l! w+ x4 @if(T0IF)
6 t0 x* e' q3 ~- M# f{2 V) n$ U) ]; U2 C: }
  T0IF=0 ;0 U: w5 G, @8 x
  (ds.count)++ ;2 |' [, z# X: U) f  ]
  if(ds.count==80)0 ^* D" t; P1 C$ d
  {/ L( t0 B, N5 Q' M5 V; r2 ]$ e
   ds.count=0 ;
- h9 q% @9 u& X% @/ l   switch(ds.state)$ x9 V- w  m7 |! r
   {
3 u8 e7 F) o$ h9 J    case 0 :  o, r. o# e( y, @
     ds.state=1 ;
" e& ~/ S8 e( X- I) P  J     init_ds18b20() ;- z( F0 V$ A+ c8 i/ `9 R! }
     write_ds18b20(ROM_SKIP) ;
1 O! @/ _0 J# ?     write_ds18b20(MEM_CONVERT) ;
5 q6 F6 F/ r1 v, _     break ;2 i5 C2 i2 O3 ]3 S2 m
    case 1 :
1 \7 @  g4 d% Z$ m7 W     init_ds18b20() ;2 V0 O  A& I1 Z9 u
     write_ds18b20(ROM_SKIP) ;
! {8 @7 g+ M2 M% Q0 }     write_ds18b20(MEM_READ) ;
" T4 T1 r* Y6 N2 g: F3 c     tl=read_ds18b20() ;
( u) s7 F+ \$ f     th=read_ds18b20() ;
9 ^" Q9 Q- I% M. W# B     if(!(th&0xf0)): z  C, c6 N/ r+ @
     {. m8 e% U/ m% N$ ^
      th=th&0x07 ;
8 ?: W# S3 e4 X$ V$ z( I      temp=th*256+tl ;
6 z, d3 F3 i0 m, N$ \      ds.data=temp/16 ;
5 W% ^6 ~) s! y     }& o( I! H% i& Q- }7 \) y
     else
! ~. v- _0 S! J. s' Q     { th=th&0x07 ;8 Q( D& ?0 I4 C' v2 _& R7 v
      temp=th*256 +tl ;
4 o& ?6 m1 y: i5 p7 ?. `- \- r      ds.data=temp/16 ;
5 o5 D; R0 d, k% Q6 {1 P* K     }+ b' q; B; E* y+ l
     ds.state=0 ;! w4 K7 h% y* c; ]8 N) }% e3 q! i
     break ;
- y9 j8 |* F( _. w; j- J    default :
2 M4 x/ V  {7 c8 u' ]     ds.state=0 ;
/ w% u2 H5 m$ j$ T' |6 E5 Z$ i' r     break ;
# @& _0 V, S% L6 u   }
/ D6 s' [+ ~* Y# {) m. p! n( V$ ^% Z  }
- h3 Y' s! r% \+ w& Z( s* O  int_display1(ds.data) ;% s7 ?6 |9 f* i( b) G& b/ b' m# U
  TMR0=210 ;
. r! |; r# ?4 a5 Y/ F- g: e}/ e( B& S9 ^8 {0 X, o5 w" A
}

7 }6 Z9 y% X7 V: i/ H

该用户从未签到

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

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

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

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