【单片机】单片机课程设计(测温打铃)附完整代码和电路图


前言

一、测温打铃是什么?

测温打铃是在单片机的基础上实现的一种温度报警装置。它可以通过自己设定报警温度,当温度传感器的温度达到报警温度发出报警声。(本项目添加生日快乐的报警音乐)有想法的可以自己动手实践,做一个真正的单片机实体项目。

二、具体实现

1.电路图

电路图首先要了解需要哪些元件,我在本项目中添加了微调电容、外部晶振、温度传感器、LCD显示屏、排阻、三极管、蜂鸣器、AT89C52。下面是具体电路图。

在这里插入图片描述

2.代码

代码注释很清晰,具体代码如下:

#include <reg52.h> //头文件
#include <intrins.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int

sbit DQ=P3^0; //数据传输线接单片机的相应的引脚 
sbit beepIO=P3^1; //接PNP型三极管

sbit RS = P3^2;//液晶接口,rs0命令,1数据;外部中断0
sbit RW = P3^3;//外部中断1
sbit E = P3^4;//液晶使能端E,控制信号输入端,下降沿使能

sbit k3 = P3^5;//k3开关,播放音量
sbit k2 = P3^6;//k2开关,温度上限减
sbit k1 = P3^7;//k1开关,温度上限加

float Temp;//温度
uint Temp_H = 60;//温度上限
unsigned char tempL=0; //设全局变量//用于温度进制转化
unsigned char tempH=0; 
uchar bz1;//k3按下

uchar m,n; 
uchar code T[49][2]={
    
    {
    
    0,0},//各个音调的初始值
{
    
    0xF8,0x8B},{
    
    0xF8,0xF2},{
    
    0xF9,0x5B},{
    
    0xF9,0xB7},{
    
    0xFA,0x14},{
    
    0xFA,0x66},{
    
    0xFA,0xB9},{
    
    0xFB,0x03},{
    
    0xFB,0x4A},{
    
    0xFB,0x8F},{
    
    0xFB,0xCF},{
    
    0xFC,0x0B},
{
    
    0xFC,0x43},{
    
    0xFC,0x78},{
    
    0xFC,0xAB},{
    
    0xFC,0xDB},{
    
    0xFD,0x08},{
    
    0xFD,0x33},{
    
    0xFD,0x5B},{
    
    0xFD,0x81},{
    
    0xFD,0xA5},{
    
    0xFD,0xC7},{
    
    0xFD,0xE7},{
    
    0xFE,0x05},
{
    
    0xFE,0x21},{
    
    0xFE,0x3C},{
    
    0xFE,0x55},{
    
    0xFE,0x6D},{
    
    0xFE,0x84},{
    
    0xFE,0x99},{
    
    0xFE,0xAD},{
    
    0xFE,0xC0},{
    
    0xFE,0x02},{
    
    0xFE,0xE3},{
    
    0xFE,0xF3},{
    
    0xFF,0x02},
{
    
    0xFF,0x10},{
    
    0xFF,0x1D},{
    
    0xFF,0x2A},{
    
    0xFF,0x36},{
    
    0xFF,0x42},{
    
    0xFF,0x4C},{
    
    0xFF,0x56},{
    
    0xFF,0x60},{
    
    0xFF,0x69},{
    
    0xFF,0x71},{
    
    0xFF,0x79},{
    
    0xFF,0x81}
};
uchar code music[][2]={
    
    {
    
    0,4},
{
    
    17,6},{
    
    17,2},{
    
    19,8},{
    
    17,8},{
    
    22,8},{
    
    21,16},
{
    
    17,6},{
    
    17,2},{
    
    19,8},{
    
    17,8},{
    
    24,8},{
    
    22,16},{
    
    17,6},{
    
    17,2},{
    
    29,8},{
    
    26,8},{
    
    22,8},{
    
    21,8},{
    
    19,8},{
    
    27,6},{
    
    27,2},{
    
    26,8},{
    
    22,8},{
    
    24,8},{
    
    22,16},
{
    
    0xFF,0xFF}};


/***********************************************************延时函数**********************************************************/

void delayms(uint x)
{
    
    
	uchar i;
	while(x--)for(i = 0; i < 120; i++);
}
void delay(unsigned char i)
{
    
    
 for(i;i>0;i--);
}
/***********************************************************************液晶显示*******************************************/



//写指令
void Write_Order(uchar x)
{
    
    
	delayms(1);
	RS = 0;//低电平选择指令寄存器
	RW = 0;//低电平写数据
	P0 = x;//P0端口设为x
	E = 1;//使能端高电平(下降沿,赋给传感器)
	_nop_();//指令延时1us,延时一个机器周期
	E = 0;//使能端低电平
	/*让EN引脚从低电平到高电平变化,然后EN引脚再从高电平到低电平出现下降沿,
	检测到下降沿后,就会读取D0~D7的数据*/
	RW = 1;//高电平进行读操作
}

//写数据
void Write_Data(uchar x)
{
    
    
	delayms(1);
	RS = 1;//高电平选择数据寄存器
	RW = 0;//低电平写数据
	P0 = x;//P0端口设为x
	E = 1;//使能端高电平
	_nop_();//指令延时1us,延时一个机器周期
	E = 0;//使能端低电平
	RW = 1;//高电平进行读操作
}

//初始化LCD(液晶显示器)
void Init_1602(void)
{
    
    
	Write_Order(0x38);//显示设置:8位数据接口,2行,16×2显示,5×7点阵
	Write_Order(0x08);//显示关闭
	Write_Order(0x01);//清屏(包含数据指针清零,所有显示清零)
	Write_Order(0x06);//输入方式:光标右移,屏幕不动
	Write_Order(0x0c);//整体显示,有光标,不闪烁
}

//显示一个字节
void Write_Byte(uchar x,uchar y,uchar dod)
{
    
    
	if(x)
	y |= 0x40;//逻辑"或"1000000(0x40),X=X|0x40, 即将X的第6位赋值为1。
	y |= 0x80;//10000000(0x80),即将X的第7位,也就是最高位赋值为1。
	Write_Order(y);//写y指令
	Write_Data(dod);//写数据
}

//显示一个字符串
void Write_String(uchar x,uchar y,uchar *p)
{
    
    
	uchar i = 0;
	if(x == 0)y|=0x80;//将X的第7位,也就是最高位赋值为1。
	if(x == 1)y|=0xc0;
	if(x == 2)y|=0x94;
	if(x == 3)y|=0xd4;
	Write_Order(y);//写字符串指令y
	while(p[i] != 0)
	{
    
    
		Write_Data(p[i++]);//写字符串数据p[i++]
	}
}
//LCD显示字符
void Display(void)
{
    
    
	uchar Buff[20];
	sprintf(Buff,"Temp:%3.1f H%d  ",Temp,Temp_H);//显示测试温度和报警上限温度
	Write_String(0,0,Buff);//LCD显示字符串
	
}



/*************************************************************温度检测******************************************************/


//*******************************************************初始化程序 **********************************************************//

void Init_DS18B20(void) 
{
    
    
	 unsigned char x=0;
	 DQ=1; //DQ先置高 
	 delay(8); //稍延时
	 DQ=0; //发送复位脉冲 
	 delay(80); //延时(>480us) 
	 DQ=1; //拉高数据线 
	 delay(5); //等待(15~60us) 
	 x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 
	 delay(20); 
} 


//**********读一个字节************//

ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
    
    
	unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
	unsigned char dat=0; 
	for (i=8;i>0;i--) //一个字节有8位 
	{
    
    
		 DQ=1; //DQ先置高 
		 delay(1); 
		 DQ=0;//发送复位脉冲
		 dat>>=1; 
		 DQ=1; //拉高数据线 
		 if(DQ) 
		 dat|=0x80; 
		 delay(4);
	} 
	return(dat);
} 



//*********************** **写一个字节**************************//

void WriteOneChar(unsigned char dat) 
{
    
     
  unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
  for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 
  {
    
    
	   DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。 
	   DQ=dat&0x01; 
	   delay(5); 
	   DQ=1; //继续至高电平
	   dat>>=1;
  } 
  delay(4);
} 


//读温度值(低位放tempL;高位放tempH;)
void ReadTemperature(void) 
{
    
    
	  int TempINT;
	  Init_DS18B20(); //初始化
	  WriteOneChar(0xcc); //跳过读序列号的操作
	  WriteOneChar(0x44); //启动温度转换
	  delay(125); //转换需要一点时间,延时 
	  Init_DS18B20(); //初始化
	  WriteOneChar(0xcc); //跳过读序列号的操作 
	  WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位) 
	  tempL=ReadOneChar(); //读出温度的低位LSB
	  tempH=ReadOneChar(); //读出温度的高位MSB 
	  TempINT = tempH<<8|tempL;
	  Temp = TempINT*0.0625;
}
void CL(void)
{
    
    
	ReadTemperature();//读温度值
}
/*********************************************************按键扫描********************************************************/
void keyscand()
{
    
    
		
	if(k1==0)//k1开关按下,温度上限加
	{
    
    
		delayms(100);//延时
		if(k1==0)//k1依然处于低电平状态
		{
    
    
			Temp_H++;//温度上限加1
			bz1=0;
			EA=0;
		}
	}

	if(Temp_H==100)//如果温度上限等于100
	{
    
    
		Temp_H=50;	//超过元件最大温度,至为50
	}

	if(k2==0)//k2开关按下,温度上限减
	{
    
    
		delayms(100);
		if(k2==0)//k2依然处于低电平状态
		{
    
    
			Temp_H--;//温度上限减1
			bz1=0;
			EA=0;
		}
	}
	if(Temp_H==0)//k3开关,播放音量
	{
    
    
		Temp_H=50;	
	}
}
/**********************************************BAOJING************************************************************/
void  bj()//报警
{
    
    
	if(Temp>Temp_H)//温度大于温度上限
	{
    
    
		beepIO=0;//蜂鸣器鸣叫
		delayms(200);//超过上限报警
	}
	if(Temp<Temp_H)//温度小于温度上限
	{
    
    
		beepIO=1;//蜂鸣器关闭
	}

}
//k3按键(播放音调)
void k3scand()
{
    
    
	if(k3==0)//如果k3被按下
	{
    
    
		delayms(100);//延时
		if(k3==0)
		{
    
    
			bz1++;
		}
	}
	if(bz1==2)
	{
    
    
		bz1=0;
	}//k3按下标志取值01

}

/********************************************************主函数***********************************************************/




//中断T0
void T0_int() interrupt 1
{
    
    
	 beepIO=!beepIO;
	 TH0=T[m][0];
	 TL0=T[m][1];
}
//主函数
void main()
{
    
    
	 uchar i=0; 
	 TMOD=0x01; //开启定时器0,0x10时使用定时器,0x11时启动两个
	 EA=1;//开放所有中断
	 ET0=1; //允许T0中断
	 Init_1602();//初始化LCD(液晶显示器)
	 while(1) 
	 {
    
    
		k3scand();//k3按键
		if(bz1==0)//k3未按下
		{
    
    
			EA=0;//关闭所有中断
			CL();//读温度值
			Display();//LCD显示温度
			delayms(50);//延时
			keyscand();//按键扫描
			bj();//报警
		}
		if(bz1==1)//k3按下
		{
    
    
			EA=1;//开放所有中断
			m=music[i][0];
			n=music[i][1]; 
			if(m==0x00)
			{
    
    
				TR0=0;//关闭定时器计数器0
				delayms(n*100);
				i++;
			} 
			else if(m==0xFF)
			{
    
    
				TR0=0;//关闭定时器计数器0
				delayms(30*100);
				i=0;
			} 
			else if(m==music[i+1][0]) 
			{
    
    	TR0=1;//打开定时器计数器0
				delayms(n*100);
				TR0=0;
				delayms(100);
				i++;
			}
			else
			{
    
    
				TR0=1;//开放定时器计数器0
				delayms(n*100);
				i++;
			}
		}				 
	 }
}

程序效果图

链接: https://pan.baidu.com/s/1CFJgNWwhgXQfjJPz5pfX_w
提取码:64kl

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_48701521/article/details/111883642