在单片机体系中,有许多情况下需求等候某个事情的产生,来持续下一步操作,假如有一个使命还好说,单片机能够无限等候事情的产生,可是假如单片机要处理多个事情时,这种体系一般不能完结,除非用中止,对!用中止,可是中止源的数量是有限的,而且有许多中止源是针对特别用途,这样能给我自在分配的中止源就只有定时器中止和外部中止,假如仅运用这几个中止源来完结异步,这样可完结的异步事情时十分有限的,每个中止源完结一个异步事情,功率是适当低,大大降低了体系的功能,降低了定时器的利用率.
因而在这儿我考虑运用定时器中止来完结多个事情的异步,一个定时器怎么完结多个使命的并发?
在这儿运用一个使命一个计数器,依据使命实时性的强弱,来规划使命计数器的计数溢出值,每个使命的变量经过一个大局结构体来界说,当然这个结构体有必要包含这个计数溢出值。每到一个定时器中止,各个使命计数器都加一,然后查看计数器是否溢出,假如计数溢出就履行相应的使命,一起将此使命的计数器值清零,,假如溢出履行相应的使命,假如没有,则此使命就不履行!但必定要注意在中止程序,千万不能有死循环,假如有等候必定要进行超时检测,来防止死机!
这儿举个比如,刚刚成思路,因而写的不是很好!这个程序运用一个4连体数码管显现从DS18B20中收集的温度值,4位连体数码管当然只能运用动态扫描方法来显现数据,而且这个动态扫描不能在主程序中履行,因为在主程序动态扫描作用很简单收到中止程序的影响,而使显现作用下降,因而有必要运用定时器来操控延时完结动态扫描,可是ds18b20的读写时序对延时的精度要求也是适当高的,假如在主程序中,中止程序形成的延时必定会对ds18b20收集数据的延时精确度形成搅扰,而不能收集正确的数据!因而DS18b20收集数据的程序也不能够放在主程序中,当然咱们能够运用两个定时器来完结!这儿咱们运用一个定时器来完结,因为DS18B20温度转化时刻比较长12位精度的温度转化需求挨近1秒的时刻,这对动态扫描是无法忍受的,可行的方法是将发动转化,读取温度值放在同一个中止的不同状况,也就是在使命中完结状况机,然后防止了在中止中呈现长时刻的等候,而影响体系的功能!以下中止函数的详细完结:
void interrupt main_int()
{
//t0_int(&data) ;
uchar tl ,th ;
uint temp ;
if(T0IF)
{
T0IF=0 ;
(ds.count)++ ;
if(ds.count==80)
{
ds.count=0 ;
switch(ds.state)
{
case 0 :
ds.state=1 ;
init_ds18b20() ;
write_ds18b20(ROM_SKIP) ;
write_ds18b20(MEM_CONVERT) ;
break ;
case 1 :
init_ds18b20() ;
write_ds18b20(ROM_SKIP) ;
write_ds18b20(MEM_READ) ;
tl=read_ds18b20() ;
th=read_ds18b20() ;
if(!(th&0xf0))
{
th=th&0x07 ;
temp=th*256+tl ;
ds.data=temp/16 ;
}
else
{th=th&0x07 ;
temp=th*256+tl ;
ds.data=temp/16 ;
}
ds.state=0 ;
break ;
default :
ds.state=0 ;
break ;
}
}
int_display1(ds.data) ;
TMR0=210 ;
}
}