打印
[51单片机]

定时器跑时间状态机采集18B20数据已成功,STC15W204S。

[复制链接]
3291|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
oufuqiang|  楼主 | 2015-5-6 01:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 没有使用软件延时的18B20驱动程序  (STC15W204S 1T 8051) 使用标准8051单片机需要将_nop_();的个数减少到2个。

很简单,只要把定时器设置为模式1,并开启总中断,定时器中断,再把这个中断程序贴进去就可以了。
在需要使用温度数据的地方,查询convfinsh标志状态,如果这个标志变成1,那么说明一个温度数据已经采集到了。拿去用即可
                if(convfinsh==1)
                {
                        dispval=TempRes*625L;
                        sendbuff[5]='0'+(dispval%10000000)/1000000;
                        sendbuff[6]='0'+(dispval%1000000)/100000;
                        sendbuff[7]='0'+(dispval%100000)/10000;
                        sendbuff[9]='0'+(dispval%10000)/1000;
                        sendbuff[10]='0'+(dispval%1000)/100;
                        sendbuff[11]='0'+(dispval%100)/10;
                        sendbuff[12]='0'+(dispval%10);
                        send(sendbuff,17);
                        while(sending);
                        convfinsh=0;
                }

以下是中断服务程序:
void timer0(void) interrupt 1
{
        static unsigned char step=1,cmd,bitcount;
        DQ=1;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        switch(step)
        {
        case 1:DQ=0;TH0=(65536-480)/256;TL0=(65536-480)%256;step=2;break;
        case 2:DQ=1;TH0=(65536-70)/256;TL0=(65536-70)%256;step=3;break;
        case 3:if(DQ==1){step=1;}else{TH0=(65536-300)/256;TL0=(65536-300)%256;step=4;}break;
        case 4:cmd=0xcc;step=5;bitcount=0;break;
        case 5:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=cmd&0x01;cmd=cmd>>1;TH0=(65536-80)/256;TL0=(65536-80)%256;
  bitcount++;if(bitcount==8){cmd=0x44;step=6;bitcount=0;}break;
        case 6:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=cmd&0x01;cmd=cmd>>1;TH0=(65536-80)/256;TL0=(65536-80)%256;
  bitcount++;if(bitcount==8){step=7;}break;
        case 7:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=1;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        if(DQ==1){step=8;}TH0=(65536-6000)/256;TL0=(65536-6000)%256;break;
        case 8:DQ=0;TH0=(65536-480)/256;TL0=(65536-480)%256;step=9;break;
        case 9:DQ=1;TH0=(65536-70)/256;TL0=(65536-70)%256;step=10;break;
        case 10:if(DQ==1){step=1;}else{TH0=(65536-300)/256;TL0=(65536-300)%256;step=11;}break;
        case 11:cmd=0xcc;step=12;bitcount=0;break;
        case 12:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=cmd&0x01;cmd=cmd>>1;TH0=(65536-80)/256;TL0=(65536-80)%256;
  bitcount++;if(bitcount==8){cmd=0xbe;step=13;bitcount=0;}break;
        case 13:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=cmd&0x01;cmd=cmd>>1;TH0=(65536-80)/256;TL0=(65536-80)%256;
  bitcount++;if(bitcount==8){step=14;bitcount=0;}break;
        case 14:
        DQ=0;
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
        DQ=1;
        tempbindata=tempbindata>>1;if(DQ==1){tempbindata=tempbindata|0x8000;}
        bitcount++;if(bitcount==16){TempRes=tempbindata;convfinsh=1;step=1;}
        TH0=(65536-80)/256;TL0=(65536-80)%256;break;
  }
}

相关帖子

沙发
ayb_ice| | 2015-5-6 08:04 | 只看该作者
在主循环里搞个状态机,根本不需要什么长延时,关键时刻关中断即可

你这一样受高级中断的影响

使用特权

评论回复
板凳
oufuqiang|  楼主 | 2015-5-6 09:35 | 只看该作者
ayb_ice 发表于 2015-5-6 08:04
在主循环里搞个状态机,根本不需要什么长延时,关键时刻关中断即可

你这一样受高级中断的影响 ...

在主循环里面搞状态机,在写位数据的时候关闭中断,这个我已经写过了,在等待转换结束的逻辑里面看着不是很舒服,虽然用状态机等这750mS并不会阻塞程序的运行。现在写成定时器的,就当做后台服务一样,不用管它,要取温度的时候去拿数据就可以了。

其实我写之前为了避免无畏的重复已经搜索过别人写的状态机,包括主循环里面的,定时器的,VHDL硬件的等等。看着都不是很爽,所以就自己写了个。

使用特权

评论回复
地板
ayb_ice| | 2015-5-6 11:04 | 只看该作者
oufuqiang 发表于 2015-5-6 09:35
在主循环里面搞状态机,在写位数据的时候关闭中断,这个我已经写过了,在等待转换结束的逻辑里面看着不是 ...

写成这种形式

bit ds18b20_call(U8* p)
{
        ....
}

主循环一直调用这个函数,判断返回值成功后,从P中获取结果,

内部完成细节,每10MS循环一次,这个函数不会大于10MS的阻塞,

我一般都是这样做的,内部其实也就是个状态机,把一个长的过程转换成了多个步骤

使用特权

评论回复
5
wangpeng59| | 2015-12-2 22:53 | 只看该作者
在时间上,我也是一直很困扰,写这个程序很容易把自己绕进去

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

106

主题

1424

帖子

20

粉丝