单片机项目——温度计项目逐句解析

电路图

程序设计

主要程序。

// main.c
#include<reg51.h>
#include<DS18B20.c>
unsigned char cp1,cp2,cp3;
char temp;
bit flag;
unsigned char  seven_seg[] = 
{
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
};
void timer0_isr(void) interrupt 1
{
	TH0 = (65536 - 2000) / 256;
	TL0 = (65536 - 2000) % 256;
	// 获取温度的定时器
	cp1++;
	// 循环四个显示
	cp3++;
	// 意思是都赋值为0xff,就是都不亮,在下面对要亮的灯进行控制
	P0 = 0xff;
	// 显示小数点后一位
	if(cp3 == 1){P0 = seven_seg[c];P2 = 0x01;}
	// 显示个位	    获取高八位,与0x7f的原因是消掉符号位的值。 
	if(cp3 == 2){P0 = seven_seg[temp % 10] & 0X7f;P2 = 0x02;}
	// 显示十位
	if(cp3 == 3){P0 = seven_seg[temp / 10];P2 = 0x04;}
	// 显示负号
	if(cp3 == 4)
	{
		// 0xff就是不显示的意思
		// 如果flag=0,负号取消,否则负号显示。
		if(flag == 0)P0 = 0xff;
		if(flag == 1)P0 = 0xbf;
		P2 = 0x08;
	}
	// 复位cp3
	if(cp3 >= 4)cp3 = 0;
}
void timer0_init(void)
{
	TMOD = 0x01;
	TH0 = (65536 - 2000) / 256;
	TL0 = (65536 - 2000) % 256;
	EA = 1;
	ET0 = 1;
	TR0 = 1;
}
void main(void)
{
	// 启动中断
	timer0_init();
	while(1)
	{
		// 半秒
		if(cp1 >= 250)
		{
			// cp1复位
			cp1 = 0;
			// 读取一下数值
			temp = Read_Temperature();
			// temp是获取的8位温度整数部分,最高位为符号位。 与0x80最终的值要么是0x80要么是0x00,如果是0x80,意味着当前温度为负数,需要设定flag值,然后在中断函数中显示出负号
			if((temp & 0x80) == 0x80)
			{
				flag = 1;
				// 255 - 补码,就是负数原来的样子
				temp  = 0xff - temp;
				// 小数点后一位也要转换
				c = (0x0f - c) * 0.625;
			} 
			else
			{
			 	flag = 0;
				c = c * 0.625;	
			}

		}
	}
}

温度计的驱动程序

// DS18B20.c
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P1^2;							//定义单片机的P2.7与DS18B20数据端口连接在一起                                    													 
/********延时函数********/
void delay(uint x)
{
	while(x--); 
}
/********初始化函数********/
void Init_DS18B20(void)					//基本操作函数1
{
	unsigned char x = 255;
	DQ = 1;								//先让DQ置1
	DQ = 0;								//单片机将DQ拉低
	delay(80);							//延时480-960us
	DQ = 1;								//释放总线
	while(DQ && x--);					//等待返回的低电平响应 如果没有响应,则做适量延时自动往下执行
	delay(20);
}
/********从DS18B20中读一个字节********/
uchar Read_OneChar(void)				//基本操作函数2
{
	uchar i = 0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	{
  		DQ = 0;							//发送启动信号
  		dat >>= 1;									  	
  		DQ = 1;							//释放总线
  		if(DQ)							//判断总线是否为高电平
  		dat |= 0x80;					//如果是高电平,则把dat的最高位置1,如果不是,默认置0
  		delay(10);
	}
	return(dat);
}
/********向18B20中写一个字节********/
void Write_OneChar(uchar dat)			//基本操作函数3
{
	uchar i=0;
	for(i=8; i>0; i--)
	{
		DQ = 0;
		DQ = dat & 0x01;				//取dat的最低位
		delay(10);
		DQ = 1;
		dat >>= 1;
	}
	delay(8);
}
/********读取温度********/
uchar a,b,c;
uchar Read_Temperature(void)			//应用操作函数1
{
	uchar i = 0,t = 0;
	Init_DS18B20();

	Write_OneChar(0xcc);				// 跳过ROM,不需要读序号列号
	Write_OneChar(0x44);				// 启动温度转换
	
	Init_DS18B20();

	Write_OneChar(0xcc);				//跳过读序号列号的操作
	Write_OneChar(0xbe);				//读取温度寄存器等(共可读9个寄存器)前两个就是温度
	
	a = Read_OneChar();					//读取温度值低位
	b = Read_OneChar();					//读取温度值高位
	
	c = 0x0f & a;						//得到小数部分
	a = a >> 4;							//低位右移4位
	
	b = b << 4;							//高位左移4位

    t = a | b;							//得到8位温度的整数部分,最高1位为符号位
	return(t);
}
/********保存温度上下限********
void write_temprom(uchar temp_up_set,uchar temp_down_set )	//应用操作函数2
{
 	Init_DS18B20();
	Write_OneChar(0xcc);				//跳过读序号列号的操作
	Write_OneChar(0x4e);				//写准备 
	Write_OneChar(temp_up_set);			//向18B20的暂存写上限		 
	Write_OneChar(temp_down_set);		//向18B20的暂存写下限
	Write_OneChar(0x7f);
	Init_DS18B20();
	Write_OneChar(0xcc); 
	Write_OneChar(0x48);				//向18B20的rom中写数据
	Init_DS18B20();
	Write_OneChar(0xcc);
	Write_OneChar(0xb8);
} 
/********读取温度上下限********
uchar  temp_up,temp_down;				//温度上下限值
void read_temprom(void)					//应用操作函数3
{
   	uchar i;
	Init_DS18B20();
	Write_OneChar(0xcc);				//跳过读序号列号的操作        	
	Write_OneChar(0xbe);				//读取温度寄存器等(共可读9个寄存器) 前两个就是温度
	i = Read_OneChar();					//读0地址寄存器,扔掉
	i = Read_OneChar();					//读1地址寄存器,扔掉
	temp_up = Read_OneChar();			//读2地址寄存器
	temp_down = Read_OneChar();			//读3地址寄存器
}
*/
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacob_云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值