基于STC8系列单片机对DS18B20和TM1650的电子温度计设计

电子温度计

利用温度传感器DS18B20TM1650驱动的数码管模块实现温度检测和显示功能,温度显示含一位小数。

头文件和库的引用:

包含了一些头文件,如 <stc8h.h>、"TM1650.h" 和 <INTRINS.h>。定义了一些数据类型,如 INT8U 和 INT16U。

定义全局变量:

DSFlag: DS18B20是否响应的标志位。

temp: 用于存放温度整数和小数部分的数组。

tempdata: 存放读取到的温度数据。

e: 存放温度的整数值。

定义DS18B20相关的IO引脚和延时函数:

使用 sbit 定义DS18B20单总线引脚 DS 和其他IO引脚。定义了不同精度的延时函数,如 Delay1us()、Delay5us()、Delay50us()、Delay240us() 和 Delay800ms()。

DS_setup() 函数:

初始化DS18B20传感器,发送初始化序列,包括拉低总线、释放总线、等待DS18B20响应等步骤。检查DS18B20是否响应,如果未响应,设置 DSFlag 标志位为1。

DS_WriteData() 函数:

用于向DS18B20写入数据。通过位操作将一个字节的数据写入DS18B20。

DS_ReadData() 函数:

用于从DS18B20读取数据。通过位操作读取8位数据。

readTemperature() 函数:

向DS18B20发送温度转换指令,并读取温度数据。处理温度数据,包括负温度的处理。

displayTemp() 函数:

根据读取到的温度数据,将温度数据以BCD码的形式写入TM1650LED数码管,实现温度显示。

main() 函数:

初始化端口和TM1650数码管。进入无限循环,不断读取温度并根据DSFlag来选择是否显示温度。如果DSFlag为1,说明DS18B20未响应,数码管显示全“FF”表示异常。否则,显示温度,并通过延时控制温度的刷新速度。实现了从DS18B20温度传感器读取温度数据,并在TM1650数码管上显示温度值。同时,还处理了DS18B20未响应的情况,以及负温度的显示。

主函数:

//STC8H1K28

#include <stc8h.h>
#include "TM1650.h"
#include <INTRINS.h>

typedef unsigned char INT8U;
typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
int e;

unsigned char temp[2] = {'\0'}; //存放温度整数和小数
uchar tempdata;

sbit DS  = P2^2;   //DS18B20单总线


void DS_setup()
{

	DS = 1;
	Delay1us();
	DS = 0;   //拉低电平 
	Delay480us();
    Delay240us();  //480us-960us之间均可
	DS = 1;   //拉高电平
	Delay50us();   //等待15us-60us
	if(DS == 1) //如果未响应
	{
		DSFlag = 1; //DS18B20未响应 标志位置1
	}
	Delay240us();	
	
}

void DS_WriteData(unsigned char com)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		DS=1;
		Delay1us();
		Delay1us();
		DS= 0; //拉低电平//延时至少1us
		Delay5us();
		Delay1us();
		Delay1us();
		DS=com&0x01;
		Delay50us(); //至少60us直到周期结束
		Delay5us();
		Delay5us();
		DS= 1;
		com=com>>1; //右移一位
	}	
  P12=0;	
}
/*DS18B20读数据函数*/
unsigned char DS_ReadData()//DLA,P13
{
	unsigned char i,j;
	unsigned char dat = 0; //接收数据
	P13=1;
	j=1;
	for(i=0;i<8;i++)
	{
		bit x;
		DS=1;
		Delay1us();
		Delay1us();
		DS=0;  //拉低电平至少1us
		Delay1us();
		Delay1us();
		Delay1us();
		Delay1us();
		Delay1us();
		Delay1us();
		DS=1; //释放总线
		Delay1us();
		Delay1us();
		Delay1us();
		Delay1us();
		x=DS;
		Delay50us();
		if(x==1) //如果是1
		{
			dat=dat+(j<<i);
		}
	}
	tempdata=dat;
	P13=0;
	return dat;
	
}

void readTemperature()
{
	unsigned char tempLow;  //温度低字节
	unsigned char tempHigh; //温度高字节
	unsigned char tempFlag = 0; //温度正负标志位
	DS_setup();	//初始化DS18B20
	DS_WriteData(0xcc); //跳过ROM
	DS_WriteData(0x44); //启动温度转换指令
	//Delay800ms();//延时一段时间
	DS_setup(); //每一次写命令都需要初始化
	DS_WriteData(0xcc); //跳过ROM
	DS_WriteData(0xbe); //读暂存器内容
	tempLow =DS_ReadData();	 //获取温度的第一个字节
	tempHigh =DS_ReadData(); //获取温度的第二个字节
	if(tempHigh>=128)  //温度是负数
	{
		tempLow= ~tempLow+1;
		tempHigh= ~tempHigh;
		tempFlag = 1;
	}
	temp[0]=tempLow;
	temp[1]=tempHigh;
    e=temp[1]*256+temp[0];		
}

void displayTemp()
{
	int a,b,c,d
	a=(int)(e*0.000625)%10;
	b=(int)(e*0.00625)%10;
	c=(int)(e*0.0625)%10;
	d=(int)(e*0.625)%10;
	TM1650_write_data(0x68,tab[a]);
	TM1650_write_data(0x6a,tab[b]);
	TM1650_write_data(0x6c,tab[c]|0x80);//强与0x80添加小数点
	TM1650_write_data(0x6e,tab[d]);
	if(a==0)
		if(b==0)
			if(c==0)
				if(d==0)
				{DSFlag=1;}
}



void main()
{
	P1=0x00;
	P2M0=0xff;
	P2M1=0xff;
	TM1650_Init();
	TM1650_clear();
	while(1)
	{
		readTemperature();		
		displayTemp();
		Delay200ms();	
	}
		
	
	
}













I2C头文件: 

#include "intrins.h"	 	 bit busy;
/***********初始化***********/
#ifndef _IICHEAD_H_
#define _IICHEAD_H_
void I2C_init()
{
P_SW2 = 0x80;//因为I2C的寄存器在扩展的SFR中(XFR外部RAM),所以使用前必须将P_SW2最高位EAXFR置1。
P1M1 = 0;
P1M0 = 0;
I2CCFG = 0xe0; //允许I2C,主机模式,等待时钟数16
I2CMSST = 0x00;//清空状态标志位
EA = 1;
}

/***********开始信号***********/
void Start()
{
busy = 1;
I2CMSCR = 0x81; //开启中断允许位,发送START命令
while (busy);
}

/***********发送一个字节数据***********/
void SendData(char dat)
{
I2CTXD = dat; //写数据到数据缓冲区
busy = 1;
I2CMSCR = 0x82; //发送SEND命令
while (busy);
}

/***********等待接收从机返回接收成功的信号***********/
void RecvACK()
{
busy = 1;
I2CMSCR = 0x83; //发送读ACK命令
while (busy);
}
/***********停止信号***********/
void Stop()
{
busy = 1;
I2CMSCR = 0x86; //发送STOP命令
while (busy);
}
/***********中断,清除标志位***********/
void I2C_Isr() interrupt 24
{
if (I2CMSST & 0x40)
{
I2CMSST &= ~0x40; //清中断标志
busy = 0;
}
}

#endif

 TM1650头文件:

#include <IICHEAD.h>
#include <stdio.h>
#include <stc8h.h>
#ifndef _TM1650_H_
#define _TM1650_H_
//typedef unsigned char uchar;
//                     0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
unsigned char tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

//================================================================
// 描述: TM1650写函数
// 参数: add:地址;dat:数据.
// 返回: none.
//================================================================
void TM1650_write_data(unsigned char add,unsigned char dat)
{
Start(); //开始信号
SendData(add); //发送显存地址(控制字)
RecvACK();
SendData(dat); //发送待显示数据(操作数)
RecvACK();
Stop(); //停止命令
}
//================================================================
// 描述: TM1650初始化
// 参数: none.
// 返回: none.
//================================================================
void TM1650_Init()
{
 I2C_init();
 TM1650_write_data(0x48,0x31); // 开显示、8段显示方式、3级亮度
}
//================================================================
// 描述: TM1650清除
// 参数: none.
// 返回: none.
//================================================================
void TM1650_clear()
{
 unsigned char i;
for(i=0; i<4;i++)
{
 TM1650_write_data(0x68+i*2,0);
}
}


#endif

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于STC8单片机以汇编语言实现DS18B20数字温度计设计代码: ``` #include <reg52.h> #include <intrins.h> typedef unsigned char byte; typedef unsigned int word; sbit DQ=P2^4; // DS18B20数据线接在P2.4上 byte code temp_table[]={ // DS18B20温度转换表 0x0c,0x1c,0x2c,0x3c,0x4b,0x5b,0x6b,0x7b, 0x8a,0x9a,0xaa,0xba,0xc9,0xd9,0xe9,0xf9 }; void delay(word i) // 延时函数 { while(i--); } void ds18b20_init() // DS18B20初始化函数 { DQ=1; // 数据线输入1 delay(8); DQ=0; // 发送复位脉冲 delay(80); DQ=1; // 释放数据线 delay(8); } void write_byte(byte dat) // 写入一个字节的数据 { byte i; for(i=0; i<8; i++) { DQ=0; // 发送数据位 _nop_(); DQ=dat&0x01; delay(5); DQ=1; // 释放数据线 dat>>=1; } } byte read_byte() // 读取一个字节的数据 { byte i,dat=0; for(i=0; i<8; i++) { dat>>=1; DQ=0; // 发送读取命令 _nop_(); DQ=1; _nop_(); dat|=(DQ<<7); delay(5); } return dat; } void convert() // DS18B20转换函数 { ds18b20_init(); // 发送初始化命令 write_byte(0xcc); // 跳过ROM操作 write_byte(0x44); // 启动温度转换 } byte get_temp() // 获取温度值函数 { byte temp_l,temp_h; ds18b20_init(); // 发送初始化命令 write_byte(0xcc); // 跳过ROM操作 write_byte(0xbe); // 发送读取温度命令 temp_l=read_byte(); // 读取温度值低字节 temp_h=read_byte(); // 读取温度值高字节 return (temp_h<<4)+(temp_l>>4); // 返回温度值 } void main() { byte temp; while(1) { convert(); // 发送转换命令 delay(1000); // 等待转换完成 temp=get_temp(); // 获取温度值 P1=temp_table[temp>>4]; // 在P1口显示温度值 } } ``` 这段代码实现DS18B20数字温度计的初始化、温度转换和读取温度值等功能,并将温度值在P1口进行显示。你可以根据自己的需要进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值