STC12芯片和AT89芯片读取ds18b20芯片数据

1. 先简要介绍本博客涉及的芯片:

        (1)IAP15F2K61S2:蓝桥杯单片机赛道所用芯片,下文Code1来自蓝桥杯赛点资源包(做出了一些修改)。

        (2)STC12C5A60S2:课程实验所用芯片,和IAP15F2K61S2都是宏晶公司的产品,因此该芯片也可以使用Code1读取ds18b20的温度。

        (3)AT89S52:Proteus仿真所用芯片。

2. STC12C5A60S2读取温度

        下面是Code1,来自蓝桥杯赛点资源包(做出了一些修改),包含三个函数,分别是延时、读、写一个字节。

#include <REGX51.H>
#include "intrins.h"

sbit DQ = P1^4;

void Delay_OneWire(unsigned int t)
{
	unsigned char i;
	while(t--){
        for(i=0;i<12;i++);
	}
}

void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

Code1

        下面是Code2,函数返回一个浮点型数据,即为温度。该函数可以直接编写在Code1下方

float read_temperature()
{
    float tem=0;
    
    init_ds18b20();
    Write_DS18B20(0xCC);
    Write_DS18B20(0x44);
    
    init_ds18b20();
    Write_DS18B20(0xCC);
    Write_DS18B20(0xBE);
    
    tem=Read_DS18B20();
    tem=Read_DS18B20()*256+tem;
    
    tem=tem/16.0;
    return tem;
}

Code2

        使用Code1和Code2即可读出ds18b20的温度了。

3. AT89S52读取温度

        老师要求有仿真结果,所以对Code1的Delay_OneWire函数做出修改,以适应Proteus的仿真。修改为:注释for循环语句,如Code3。下文会讲解为何注释掉for语句就可以正常读出温度。

void Delay_OneWire(unsigned int t)
{
	unsigned char i;
	while(t--){
//        for(i=0;i<12;i++);
	}
}

Code3

4. 为何注释掉for语句就可以在Proteus中使用AT89S52中读取ds18b20的温度?

(1)一个最简单的解释(不准确,因为我不是科班出身):

        AT89是12T芯片,而STC12是1T芯片,即STC12的速度比AT89快12倍。在相同时间的延时中,STC12需要运行的代码量是AT89的12倍。如果将for循环注释掉刚好把代码量减少为原本的1/12。事实上,注释之后时间减少为1/18。

(2)波形图:

        如果不注释for语句就直接跑仿真,init_ds18b20()函数中的Delay_OneWire(80)的时长为11.05ms(见图1波形图),温度显示为4095,而这个时长一般为600us(查手册可知480~960us都可以,这里折中一下)。

        前者是后者的18.5倍。为了将时间缩短,我们将"i<12"改为"i<1"试试看能不能正确读出温度。结果见图2。测量得到时间为2.25ms。哎不对啊,我明明缩了12倍了啊,咋才变成1/5啊?原来for循环语句包含读取、判断、写入功能,所以for(i=0;i<1;i++);也是很占时间的。

        那我们把for语句注释看看能不能成功,要是不行只能重写延时函数了。

        最后发现:注释for语句后的时间刚好为730us。可以读出正确温度。

图1

图2

图3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值