基于51单片机课程设计报告 - 图文
更新时间:2024-03-06 07:27:01 阅读量: 综合文库 文档下载
单片机课程设计
课 题:基于51单片机的交通灯设计 专 业: 机械设计制造及其自动化 学 号: 指导教师: 邵添 设计日期: 2017/12/18 成 绩:
重庆大学城市科技学院电气学院
基于51单片机数字温度计设计报告
一、设计目的作用
本设计是一款简单实用的小型数字温度计,所采用的主要元件有传感器DS18B20,单片机AT89C52,,四位共阴极数码管一个,电容电阻若干。DS18B20支持“一线总线”接口,测量温度范围-55°C~+125°C。在-10~+85°C范围内,精度为±0.5°C。18B20的精度较差,为±2°C 。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。
本次数字温度计的设计共分为五部分,主控制器,LED显示部分,传感器部分,复位部分,按键设置部分,时钟电路。主控制器即单片机部分,用于存储程序和控制电路;LED显示部分是指四位共阴极数码管,用来显示温度;传感器部分,即温度传感器,用来采集温度,进行温度转换;复位部分,即复位电路,按键部分用来设置上下限报警温度。测量的总过程是,传感器采集到外部环境的温度,并进行转换后传到单片机,经过单片机处理判断后将温度传递到数码管显示。
二、设计要求
(1).利用DS18B20传感器实时检测温度并显示。 (2).利用数码管实时显示温度。
(3).当温度超过或者低于设定值时蜂鸣器报警,LED闪烁指示。 (4).能够手动设置上限和下限报警温度。
三、设计的具体实现
1、系统概述
方案一:由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦。 方案设计框图如下:
热敏电阻组成的感温电路 AD转换 数码管显示电路 方案二:考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,
可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。
从以上两种方案,很容易看出,采用方案二,电路比较简单,软件设计也比较简单,故采用了方案二。
2、 单元电路设计与分析
1、硬件设计
按照系统设计功能的要求,确定系统由3个模块组成:主控制器、测温电路和显示电路。
数字温度计总体电路结构框图所示:
电源 按键设置模块 AT89C51单片机 数码管显示 蜂鸣器报LED闪烁
警模块 报警模块
单片机的选择
DB18B20温度传感器 单片机AT89S52具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用系统可用二节电池供电。由于器件问题,我们使用了通用的手机5V充电器接口。
复位电路模块
单片机系统的复位电路在这里使用的是上电+按钮的复位电路模式,其中电阻R采用的是10KΩ的阻值,电容采用电容值为10uF的电解电容,电路图如下:
温度显示模块
四位共阴极数码管,能够显示小数。列扫描用P2.4~P2.7口来实现,列驱动直接51接单片机驱动。电路图如下:
温度传感器模块
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进
型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。电路图如下:
按键模块
按键是用来设置报警的上下限温。K1是用来进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能, K1是实现减1功能,K3是用来设定上下限温度正负的。
2、软件设计
主要包括主程序、读出温度子程序、温度转换命令子程序、计算温度子程序和现实数据刷新子程序等。
主程序 主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量温度值。温度测量每1S进行一次。主流程图如下:
/******************************************************/ /* 获取温度函数
/
/*****************************************************/ void get_temperature(bit flag) {
uchar a=0,b=0,c=0,d=0; uinti;
ds18b20_init(); ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令 ds18b20_write(0x44); //写启动DS18B20进行温度转换命令,转换结果存入内部RAM
if(flag==1) { //首次启动DS18B20进行温度转换需要500ms,若转换时间不够就出错,读出的是85度的错误值。 display1(1); //用开机动画耗时 度
} else
ds18b20_delayms(1); ds18b20_init(); ds18b20_write(0xcc); ds18b20_write(0xbe); a=ds18b20_read(); b=ds18b20_read(); if(flag==1)
//读内部RAM (LSB) //读内部RAM (MSB) //局部位变量f=1时读上下线报警温
{
max=ds18b20_read(); min=ds18b20_read();
//读内部RAM (TH) //读内部RAM (Tl)
}
if((max&0x80)==0x80) //若读取的上限温度的最高位(符号位)为‘1’表明是负温度
{f_max=1;max=(max-0x80);} //将上限温度符号标志位置‘1’表示负温度,将上限温度装换成无符号数。 if((min&0x80)==0x80) //若读取的下限温度的最高位(符号位)为
‘1’表明是负温度
{f_min=1;min=(min-0x80);} //将下限温度符号标志位置‘1’表示负温度,将下限温度装换成无符号数。 i=b; i>>=4; if (i==0) {
f=0; temp=((a>>4)|(b<<4));
a=(a&0x0f); temp_d=a; } else { f=1;
//i为0,正温度,设立正温度标记 //整数部分
//小数部分
//i为1,负温度,设立负温度标记
a=~a+1; b=~b;
temp=((a>>4)|(b<<4)); a=(a&0x0f);
//整数部分 //小数部分
temp_d=a; } }
/******************************************************/ /* 存储极限温度函数
/
/*****************************************************/ void store_t() {
if(f_max==1) //若上限温度为负,将上限温度转换成有符号数(最高位为1是负,为0是正) max=max+0x80; if(f_min==1) 号数
min=min+0x80; ds18b20_init();
//若下限温度为负,将上限温度转换成有符
ds18b20_write(0xcc); ds18b20_write(0x4e); 和TL)命令
ds18b20_write(max); ds18b20_write(min); ds18b20_write(0xff); ds18b20_init(); ds18b20_write(0xcc); ds18b20_write(0x48); 容写入EEPROM }
//向DS18B20发写字节至暂存器2和3(TH
//向暂存器TH(上限温度暂存器)写温度 //向暂存器TL(下限温度暂存器)写温度 //向配置寄存器写命令,进行温度值分辨率设置
//向DS18B20发将RAM中2、3字节的内
//DS18B20上电后会自
动将EEPROM中的上下限温度拷贝到TH、TL暂存器
/******************************************************/ /* 温度超限报警函数 /
/*****************************************************/ void alarm() { //若上限值是正值
if(f_max==0) {
if(f_min==0)
{ if(f==0)
//若下限值是正值 //若测量值是正值
警
{ if(temp<=min||temp>=max) {w=1;TR1=1;} //当测量值小于最小值或大于最大值时报
if((temp
不报警
}
if(f==1){w=1;TR1=1;} //若测量值是负值时报警
//若下限值是负值 //若测量值是正值
}
if(f_min==1)
{ if(f==0)
{ if(temp>=max)//当测量值大于最大值时报警
{w=1;TR1=1;}
if(temp {w=0;} } if(f==1) //若测量值是负值 { if(temp>=min)//当测量值大于最小值时报警 {w=1;TR1=1;} if(temp {w=0;} } } } if(f_max==1) //若下限值是负值 //若下限值是负值 //若测量值是负值 { if(f_min==1) { if(f==1) 警 { if((temp<=max)||(temp>=min)) {w=1;TR1=1;} //当测量值小于最大值或大于最小值时报 if((temp 不报警 } if(f==0){w=1;TR1=1;} //若测量值是正值时报警 } } } #endif /********************************************************************** * 程序名; ds18b20keyscan函数 * 功能:通过键盘设定设定上下限报警温度 * 编程者:彭明闯 * 编程时间:2014/5/30 **********************************************************************/ #ifndef __keyscan_H__ //定义头文件 #define __keyscan_H__ sbit key1=P2^2; sbit key2=P2^1; sbit key3=P2^0; sbit key4=P3^3; uchari=0; //定义全局变量i用于不同功能模式的选择,‘0’正常模式,‘1’上限调节模式,‘2’下限调节模式 uchar a=0; //定义全局变量a用于不同模式下数码管显示的选择 bit k4=0; //K4按键双功能选择位,k4=0时K4按键选择消按键音的功能,k4=1时K4按键选择正负温度设定功能 bit v=0; //K2、K3按键双功能选择位,v=0时选择上下限查看功能,v=1时选择上下限温度加减功能 bit v1=0; //v1=1时定时1250ms时间到自动关闭报警上下限查看功能 bit v2=0; //消按键音功能调整位,为‘0’时开按键音,为‘1’时关按键音 /******************************************************/ /* 读键盘延时子函数 / /*****************************************************/ void keyscan_delay(uint z) //延时1ms左右 { uinti,j; for(i=z;i>0;i--) for(j=120;j>0;j--); } /******************************************************/ /* 温度调节函数 / /*****************************************************/ inttemp_change(intcount,bit f) //上下限温度调整 { if(key2==0) //判断K2是否按下 //v2=0开按键音,否则消按键音 //延时10ms //再次判断K2是否按下(实现按按键时消抖) //K2按下关按键音 //若温度为正 { if(v2==0)beer=0; keyscan_delay(10); if(key2==0) { beer=1; if(f==0) { count++; //每按一下K2温度上调1 if(a==1){if(count>125) count=125;}//当温度值大于125时不上调 if(a==2){if(count>125) count=125;} //若温度为负 } if(f!=0) { count++; //每按一下K2温度下调1 if(a==1){if(count>55) count=55;}//当温度值小于-55时不再下调 if(a==2){if(count>55) count=55;} } } while(key2==0); //K2松开按键时消抖 keyscan_delay(10); } if(key3==0) { if(v2==0)beer=0; keyscan_delay(10); if(key3==0) { //K3按按键时消抖 } beer=1; count--; //每按一下K3温度为正时下调1,为负时上调1 if(a==1){if(count<0) count=0;}//当温度值达到0时不再调 if(a==2){if(count<0) count=0;} } while(key3==0); keyscan_delay(10); //K3松开按键时消抖 } return count; /******************************************************/ /* 读键盘函数 / /*****************************************************/ void keyscan() { if(key1==0) { if(v2==0)beer=0; keyscan_delay(10); if(key1==0) //K1按按键时消抖 { beer=1; TR1=1; //开定时器1,通过s标志位的变化,实现在上下限温度调整时温度显示时闪烁的功能 k4=1; //在上下温度调节功能模式下选择K4的调整上下限温度正负的功能 v=1; //在上下温度调节功能模式下选择K2、K3的温度加减功能 i++; //K1按一下i加1,i=‘0’进入正常模式,i=‘1’进入调上限模式,i=‘2’进入调下限模式 if(i>2) //K1按下三次后退出调节模式 { i=0; TR1=0; //进入正常模式 //关定时器1 k4=0; //在正常模式下选择K4的消按键音功能 //在正常模式下选择K2、K3的查看上下限 v=0; 报警温度功能 store_t(); } switch(i) //存储调整后的上下限报警温度 //显示选择 { case 0:a=0;break; //a=0选择显示测得的温度 case 1:a=1;break; //a=1选择显示上限温度 case 2:a=2;break; //a=2选择显示下限温度 default:break; } } while(key1==0); //K1松按键时消抖 keyscan_delay(10); } if(a==1&&v==1) //a=1选择显示上限温度且v=1时选择上 下限温度加功能 {led=0;max=temp_change(max,f_max);}//显示上限温度 else if(a==2&&v==1) //a=2选择显示下限温度且v=1时选择上下限温度减功能 {led=1;min=temp_change(min,f_min);} else; if(k4==1) //k4=1时K4按键选择正负温度设定功能 { if(key4==0) { if(v2==0)beer=0; keyscan_delay(5); if(key4==0) { beer=1; if(a==1) {if(max>55) f_max=0;else f_max=~f_max;}//当温度大于55度时,只能设定为正温度 if(a==2) {if(min>55) f_max=0;else f_min=~f_min;}//当温度大于55度时,只能设定为正温度 } while(key4==0); keyscan_delay(10); } } if(v==0) { if(key2==0) { if(v2==0)beer=0; keyscan_delay(10); if(key2==0) { beer=1; a=1; TR1=1; s1=1; 出 } while(key2==0); keyscan_delay(10); } if(key3==0) { if(v2==0)beer=0; keyscan_delay(10); if(key3==0) { beer=1; a=2; TR1=1; s1=1; //v=0时选择上下限查看功能 //选择上限显示 //开定时器1开始定时一分钟左右 //上限显示不闪烁,显示一分钟左右自动退 //选择下限显示 //开定时器1开始定时1s //下限显示不闪烁,显示1s自动退出 } while(key3==0); keyscan_delay(10); } if(v1==1) //v1=1时定时1s时间到自动关闭报警上下限查看功能 {a=0;v1=0;TR1=0;} //a=0显示实测温度,v1清零,关定时器1 if(k4==0) //k4=0时K4按键选择消按键音的功能 { if(key4==0) { if(v2==0)beer=0; keyscan_delay(10); if(key4==0) { beer=1; v2=~v2; //为‘0’时开按键音,为‘1’时关按键音 } while(key4==0); keyscan_delay(10); } } } } #endif /********************************************************************** * 程序名; ds18b20数码管动态显示头文件 * 功能:通过定时器0延时是数码管动态显示 * 编程者:彭明闯 * 编程时间:2014/5/30 **********************************************************************/ #ifndef __ds18b20_display_H__ #define __ds18b20_display_H__ #define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位) #define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位) sbit wei1=P2^4; sbit wei2=P2^5; sbit wei3=P2^6; sbit wei4=P2^7; ucharnum=0; 值为‘0’ //可位寻址变量定义,用wei1表示P2.4口 //用wei2表示P2.5口 //用wei3表示P2.6口 //用wei4表示P2.7口 //定义num为全局无符号字符型变量,赋初 uchar code temperature1[]={ 0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; //定义显示码表0~9 uchar code temperature2[]={ 0xbf,0x86,0xdb,0xcf,0xe6, 0xed,0xfd,0x87,0xff,0xef}; //带小数点的0~9. uchar code temperature3[]={ 0x00,0x80,0x40,0x76,0x38}; //依次是‘不显示’‘.’‘-’‘H’‘L’ /******************************************************/ /* 延时子函数 / /*****************************************************/ void display_delay(uint t) //延时1ms左右 { uinti,j; for(i=t;i>0;i--) for(j=120;j>0;j--); } /******************************************************/ /* 定时器1初始化函数 / /*****************************************************/ void timer1_init(bit t) { TMOD=0x10; TH0=0x3c; TL0=0xb0; EA=1; ET1=1; TR1=t; // 局部变量t为1启动定时器1,为0关闭定时器1 } /******************************************************/ /* 定时器1中断函数 / /*****************************************************/ void timer1() interrupt 3 { TH0=0x3c; TL0=0xb0; num++; 加1一次) //重新赋初值,定时50ms //每进入一次定时器中断num加1(每50ms if(num<5) {s=1;if(w==1){beer=1;led=1;}else{beer=1;led=1;}} else //进入4次中断,定时200ms时若报警标志位w为‘1’则启动报警,不为‘1’不启动 //实现间歇性报警功能 {s=0;if(w==1){beer=0;led=0;}else{beer=1;led=1;}} if(num>20) //进入20次中断,定时1s //num归0,重新定开始定时1s //定时1s时间到时自动关闭报警上下限显示 { num=0; s1=0; 功能 v1=1; //定时1s时间到时自动关闭报警上下限查看 功能 } } /******************************************************/ /* 调整报警上下限选择函数 / /*****************************************************/ void selsct_1(ucharf,uchar k) //消除百位的0显示,及正负温度的显示选择 { if(f==0) 不显示百位,不为0则显示 //若为正温度,百位为0则 { if(k/100==0) P0=temperature3[0]; else P0=temperature1[k/100]; } if(f==1) //若为负温度,若十位为 0,百位不显示,否则百位显示‘-’ { if(k0/10==0) P0=temperature3[0]; else P0=temperature3[2]; } } void selsct_2(bit f,uchar k) //消除十位的0显示,及正负温度的显示选择 { if(f==0) 则不显示十位,否则显示十位 //若为正温度,百位十位均为0 { if((k/100==0)&&(k0/10==0)) P0=temperature3[0]; else P0=temperature1[k0/10]; } if(f==1) //若为负温度,若十位为 0,十位不显示,否则十位显示‘-’ { if(k0/10==0) P0=temperature3[2]; else P0=temperature1[k0/10]; } } /******************************************************/ /* 主函数显示 / /*****************************************************/ void display(uchart,uchart_d) //用于实测温度、上限温度的显示 { uchari; for(i=0;i<4;i++) { switch(i) { case 0: //选通第一个数码管 wei2=1; //关第二个数码管 wei3=1; //关第三个数码管 wei4=1; //关第四个数码管 wei1=0; //开第一个数码管 if(a==0){selsct_1(f,t);} //若a=0则在第一个数码管上显示测量温度的百位或‘-’ if(a==1) { P0=temperature3[3]; //若a=1则在第一个数码管上显示‘H’ } if(a==2) { P0=temperature3[4]; //若a=2则在第一个数码管上显示‘L’ } break; //依次从左至右选通数码管显示,实现动态显示 case 1: //选通第二个数码管 wei1=1; wei3=1; wei4=1; wei2=0; if(a==0){selsct_2(f,t);} //若a=0则在第二个数码管上显示测量温度的十位或‘-’ if(a==1) //若a=1则在第二个数码管上显示上限报警温度的百位或‘-’ { if(s==0) selsct_1(f_max,max);//若s=0则显示第二个数码管,否则不 显示 else P0=temperature3[0]; //通过s标志位的变化实现调节上下限报警温度时数码管的闪烁 if(s1==1) selsct_1(f_max,max);//若s1=1则显示第二个数码管(s1标志位用于上下限查看时的显示) } if(a==2) 上显示下限报警温度的百位或‘-’ { //若a=2则在第二个数码管 if(s==0) selsct_1(f_min,min); else P0=temperature3[0]; if(s1==1) selsct_1(f_min,min); } break; case 2: //选通第三个数码管 wei1=1; wei2=1; wei4=1; wei3=0; if(a==0){P0=temperature2[t];}//若a=0则在第三个数码管上显示测量温度的个位 if(a==1) //若a=1则在第三个数码管上显示上限报警温度的十位或‘-’ { if(s==0) selsct_2(f_max,max);//若s=0则显示第三个数码管,否则不显示 else P0=temperature3[0]; if(s1==1) selsct_2(f_max,max);//若s1=1则显示第三个数码管 //若a=2则在第三个 } if(a==2) 数码管上显示下限报警温度的十位或‘-’ { if(s==0) selsct_2(f_min,min); else P0=temperature3[0]; if(s1==1) selsct_2(f_min,min); } break; case 3: //选通第四个数码管 wei1=1; wei2=1; wei3=1; wei4=0; if(a==0){P0=temperature1[t_d];}//若a=0则在第四个数码管上显示测量温度的小数位 if(a==1) //若a=1则在第四个数码管上显示上限报警温度的个位 { if(s==0) P0=temperature1[max];//若s=0则显示第四个数码管,否则不显示 else P0=temperature3[0]; if(s1==1) P0=temperature1[max];//若s1=1则显示第四个数码管 //若a=2则在第 } if(a==2) 四个数码管上显示下限报警温度的个位 } { if(s==0) P0=temperature1[min]; else P0=temperature3[0]; if(s1==1) P0=temperature1[min]; } break; } display_delay(10); //每个数码管显示3ms左右 } /******************************************************/ /* 开机显示函数 / /*****************************************************/ void display1(uint z) //用于开机动画的显示 { uchari,j; bit f=0; for(i=0;i //‘z’是显示遍数的设定 for(j=0;j<4;j++) //依次从左至右显示‘-’ { switch(j) { case 0: wei2=1; wei3=1; wei4=1; wei1=0; break; P0=temperature3[2];//第一个数码管显示 case 1: wei1=1; wei3=1; wei4=1; wei2=0;break; P0=temperature3[2];//第二个数码管显示 case 2: wei1=1; wei2=1; wei4=1; wei3=0;break; P0=temperature3[2];//第三个数码管显示 case 3: wei1=1; wei2=1; wei3=1; wei4=0;break; P0=temperature3[2];//第四个数码管显示 } display_delay(400); //每个数码管显示200ms左右 } } } #endif 六、参考文献 (1).郭天祥.51单片机c语言教程.电子工业出版社.2009.12 (2).李群芳.单片微型计算机与接口技术.电子工业出版社.2012.12
正在阅读:
基于51单片机课程设计报告 - 图文03-06
天然药物化学名词解释10-11
过零丁洋历年中考鉴赏阅读试题(最新整理)08-20
湘教版美术二年级上册美术教案(上)04-23
高等数学 课后习题答案 第十章04-21
2022年安全生产月活动总结07-31
颜色词在英汉语言中的文化差异11-01
四超车辆及大件车运输措施11-30
诸葛武侯巧连神术(完全版)01-29
- 清真菜谱
- 我国国民经济和社会发展十二五规划纲要(全文)
- 高三物理机械振动和机械波复习2
- 浙江省公路山岭隧道机械化装备应用指导手册 doc - 图文
- 2018届高三数学文科二轮复习:专题检测(九) 导数的简单应用
- 2015年上海市公务员录用考试《行政职业能力测验》试卷(B类)
- 七年级道德与法制下册
- 大班户外游戏教案
- 病虫害预警 - 图文
- 某养鱼场为了提高经营管理水平
- 汉中市勉县尧柏余热汽机规程 10
- 烹饪试卷
- 事业单位考试公共基础知识专项分类题库训练
- 语文:第2课 走一步,再走一步 课堂导学案(人教版 七上)
- 天汉使用手册
- 人教版小学三年级数学下册教学计划
- 房地产销售管理完全操作手册122页
- 2009年评审通过具有中学高级教师专业技术资格人员名单...
- 《15秋公共关系学》作业1
- 2017最新版监理公司三标一体管理手册
- 单片机
- 基于
- 课程
- 图文
- 报告
- 设计
- 模拟人生3Nraas指南
- 山东省14市2016届高三上学期期末数学理试题分类汇编:圆锥曲线 -
- 围标模板1
- 《工程材料成形工艺》单元练习题及答案完整版
- 第七章 现代生物进化理论练习
- 兰州石化职业技术学院暑期社会实践总结报告范文最新原创
- 阳江国贸中心合同
- 我爱我的祖国文艺晚会主持词
- 《咏雪》复习题
- 自学考试《物流企业财务管理》计算题(有答案)
- 往来客户信用评级授信管理制度
- IELTS—Writing第五课时—Discuss类
- 2018版中国背光模组市场调查分析报告目录
- 天河区网球场检测鉴定初步结果 - 图文
- 每个人一生中值得去尝试一次的5大好工作(双语)
- 古代文学考试复习资料
- 钢板分类及用途
- 七选五阅读
- 小学六年级英语 四种时态复习
- 2007年江西高考理科数学试题及答案