找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5009|回复: 2
打印 上一主题 下一主题
收起左侧

MCU定时器实现多任务

[复制链接]
跳转到指定楼层
楼主
ID:77367 发表于 2015-4-19 02:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在单片机系统中,有许多情况下需要等待某个事件的发生,来继续下一步操作,如果有一个任务还好说,单片机可以无限等待事件的发生,但是如果单片机要处理多个事件时,这种系统一般不能实现,除非用中断,对!用中断,但是中断源的数量是有限的,并且有很多中断源是针对特殊用处,这样能给我自由分配的中断源就只有定时器中断和外部中断,如果仅使用这几个中断源来实现异步,这样可实现的异步事件时非常有限的,每个中断源完成一个异步事件,效率是相当低,大大降低了系统的性能,降低了定时器的利用率.
因此在这里我考虑使用定时器中断来实现多个事件的异步,一个定时器如何实现多个任务的并发?
在这里使用一个任务一个计数器,根据任务实时性的强弱,来设计任务计数器的计数溢出值,每个任务的变量通过一个全局结构体来定义,当然这个结构体必须包括这个计数溢出值。每到一个定时器中断,各个任务计数器都加一,然后检查计数器是否溢出,如果计数溢出就执行相应的任务,同时将此任务的计数器值清零,,如果溢出执行相应的任务,如果没有,则此任务就不执行!但一定要注意在中断程序,千万不能有死循环,如果有等待一定要进行超时检测,来避免死机!
这里举个例子,刚刚成思路,因此写的不是很好!这个程序使用一个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 ;
    }
}





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:76944 发表于 2015-5-2 17:16 | 只看该作者
没有太明白
回复

使用道具 举报

板凳
ID:109246 发表于 2016-6-23 10:42 | 只看该作者
不是很懂哎,希望楼主描述详细一点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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