资源描述
单片机课程设计汇报
课题:基于单片机数字温度计设计
1 方案设计
2 系统硬件设计
3.1 主控制器
3.2 显示电路
3.3 温度传感器工作原理
3.4 温度传感器接口电路
3 系统软件设计
3.1 程序
3.2 温度测量
3.3 数码管显示
4 系统测试和总结
附录1 原理图
附录2 源程序清单
1方案设计
本设计关键是介绍了单片机控制下温度检测系统,具体介绍了其硬件和软件设计,并对其各功效模块做了具体介绍,其关键功效和指标以下:
●利用温度传感器(DS18B20)测量某一点环境温度
●测量范围为-55℃~+125℃,精度为±0.5℃
●用数码管进行实际温度值显示
采取AT89S52单片机P3 .5口控制温度传感器DS18B20温度测量,以四位数码感形式输出测量温度。
图2.1 DS18B20和单片机接口原理
图2.2 总体设计方框图
2 系统硬件设计
2.1 主控制器
STC89C52是STC企业生产一个低功耗、高性能CMOS8位微控制器,含有 8K 在系统可编程Flash存放器 。STC89C52使用经典MCS-51内核,但做了很多改善使得芯片含有传统51单片机不含有功效。在单芯片上,拥有灵巧8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效处理方案。 含有以下标准功效: 8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,stc89c52MAX810复位电路,3个16 位定时器/计数器,4个外部中止,一个7向量4级中止结构(兼容传统515向量2级中止结构),全双工串行口。另外 STC89X52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,许可RAM、定时器/计数器、串口、中止继续工作。掉电保护方法下,RAM内容被保留,振荡器被冻结,单片机一切工作停止,直到下一个中止或硬件复位为止。最高运作频率35MHz,6T/12T可选。
图3.1 时钟电路和复位电路
2.2显示电路
显示采取4位数码管,图3.2.1为数码管段驱动,图3.2.2为数码管位驱动,图3.2.3为温度显示电路
图3.2.1数码管段驱动
图3.2.2数码管位驱动
图3.2.3温度显示电路
2.3 温度传感器工作原理
DS18B20温度传感器是美国DALLAS半导体企业最新推出一个改善型智能温度传感器,和传统热敏电阻等测温元件相比,它能直接读出被测温度,而且可依据实际要求经过简单编程实现9~12位数字值读数方法。DS18B20性能特点以下:
• 独特单线接口仅需一个端口引脚进行通讯
• 简单多点分布应用
• 无需外部器件
• 可经过数据线供电
• 零待机功耗
• 测温范围-55~+125℃,以0.5℃递增。华氏器件-67~+2570F,以0.90F 递增
• 温度以9 位数字量读出
• 温度数字量转换时间200ms(经典值)
• 用户可定义非易失性温度报警设置
• 报警搜索命令识别并标志超出程序限定温度(温度报警条件)器件
DS18B20测温原理图3.3.3所表示,图中低温度系数晶振振荡频率受温度影响很小用于产生固定频率脉冲信号送给减法计数器1,高温度系数晶振随温度改变其震荡频率显著改变,所产生信号作为减法计数器2脉冲输入,图中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生时钟脉冲后进行计数,进而完成温度测量.计数门开启时间由高温度系数振荡器来决定,每次测量前,首先将-55 ℃所对应基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在-55 ℃所对应一个基数值。
减法计数器1对低温度系数晶振产生脉冲信号进行减法计数,当减法计数器1预置值减到0时温度寄存器值将加1,减法计数器 1预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值累加,此时温度寄存器中数值即为所测温图2中斜率累加器用于赔偿和修正测温过程中非线性其输出用,于修正减法计数器预置值,只要计数门仍未关闭就反复上述过程,直至温度寄存器值达成被测温度值,这就是DS18B20测温原理。
图3.3.3 DS18B20测温原理图
在正常测温情况下,DS1820测温分辨力为0.5℃,可采取下述方法取得高分辨率温度测量结果:首先用DS1820提供读暂存器指令(BEH)读出以0.5℃为分辨率温度测量结果,然后切去测量结果中最低有效位(LSB),得到所测实际温度整数部分Tz,然后再用BEH指令取计数器1计数剩下值Cs和每度计数值CD。考虑到DS1820测量温度整数部分以0.25℃、0.75℃为进位界限关系,实际温度Ts可用下式计算:
2.4 温度传感器接口电路
图3.4.1温度传感器接口电路
3 系统软件设计
3.1 主程序
/*------------------ 主函数 --------------------*/
void main()
{ uchar a;
do
{
tmpchange();
for(a=10;a>0;a--)
{ display(tmp()); //在数码管上显示温度
}
}
while(1);
}
3.2 温度测量
3.2.1 初始化DS18B20
/*--------------- 初始化DS18B20 ----------------*/
void dsreset(void) //send reset and initialization command初始化DS18B20
{
uint i;
DS=0;
i=103;
while(i>0)
i--;
DS=1;
i=4;
while(i>0)
i--;
}
3.2.2 DS18B20读字节
/*---------------- 读取一位数据 ----------------*/
bit tmpreadbit(void) //read a bit读一位
{
uint i;
bit dat;
DS=0;
i++; //i++ for delay小延时一下
DS=1;
i++;
i++;
dat=DS;
i=8;
while(i>0)
i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1);//读出数据最低位在最前面,这么刚好一个字节 在DAT里
}
return(dat);
}
3.2.3 DS18B20写字节
/*---------------- 写入字节数据 ----------------*/
void tmpwritebyte(uchar dat) //write a byte to ds18b20 写一个字节到DS18B20里面
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{ testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;
i++;
DS=1;
i=8;
while(i>0)
i--;
}
else
{ DS=0; //write 0 写0部分
i=8;
while(i>0)
i--;
DS=1;
i++;
i++;
}
}
}
3.2.4 开启温度测量
/*---------------- 开启温度测量----------------*/
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset();//初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // address all drivers on bus 跳过序列号命令
tmpwritebyte(0x44); // initiates a single temperature conversion发送温度转换命令
}
uint tmp() //get the temperature取得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable 两字节合成一个整型变量
temp=temp|a;
tt=temp*0.0625;//得到真实十进制温度值,因为DS18B20
//能够正确到0.0625度,所以读回数据最低位代表是
//0.0625度。
temp=tt*10+0.5;//放大十倍,这么做目标将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp;
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
dula=0;
P0=table[A1]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A2]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
3.2.5算法步骤图
图4.2.5主程序步骤图
开始
温度零下?
温度值取补码置“—”标志
计算小数位温度BCD值
计算整数位温度BCD值
结束
置“+”标志
N
Y
图 3.2.5DS18B20初始化步骤图
发DS18B20复位命令
发跳过ROM命令
发温度转换开始命令
结束
图3.2.5 温度转换步骤图
图3.2.5 计算温度步骤图
3.3 数码管显示
/*---------------- 数码管显示 -----------------*/
void Display()
{
uchar i,j;
j=0x08;
for(i=0;i<4;i++)
{
P1=j; //数码管位码输出
LOCK=1; //打开锁存
if(i==2) P0=led[disp[i]]|0x01; //显示小数点
else P0=led[disp[i]]; //数码管段码输出
LOCK=0; //关闭锁存
j=j>>1; //调整位码
Delay(125);
P0=0x00;
}
}
4 系统测试和总结
4.1 测试时图片
图5.1.1温度传感器
图5.1.2测试时室内温度显示
图5.1.3测试时手握住传感器时温度显示
4.2 总结
此次单片机课程设计是我们第一次单片机设计,第一次总是不顺利,在过程中我们经历了部分困难,不过经过我们三个不停努力,最终完成了此次设计。
设计之初,我们先确定了设计题目,安排了一下试验步骤,分配了每个人任务。明确了每个步骤目标和操作,我们便开始了这次课程设计,编程序和画电路图是比较麻烦事情,为了能做到愈加好,我们上网搜索了部分信息,也去图书馆查阅了部分资料,在过程中每个人不仅全部认真负责做好自己那一部分,还不时去帮助小伙伴们。
经过此次课程设计,我们对数字温度计有了深入了解,对单片机、ds18b520、晶振电路等有了更深认识。此次设计不仅是考验了我们平时学习书本上知识,也考验了我们在课外对单片机及相关知识了解。
即使在课程设计中,我们碰到了部分问题,有过争吵,有过做不好时烦闷和当初一时气话放弃,但不管怎样我们在争吵、郁闷、生气以后全部重拾了这次设计。每个人全部想愈加好地做好设计,尽自己最大努力。所以此次课程设计,不仅让我们学习了更多单片机知识,增强了我们动手能力,锻炼了我们耐心和细心;还让我们明白了团结意义,和合作愉快。
附录1 原理图
附录2 源程序清单
#define uchar unsigned char
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //send reset and initialization command初始化DS18B20
{
uint i;
DS=0;
i=103;
while(i>0)
i--;
DS=1;
i=4;
while(i>0)
i--;
}
bit tmpreadbit(void) //read a bit读一位
{
uint i;
bit dat;
DS=0;
i++; //i++ for delay小延时一下
DS=1;
i++;
i++;
dat=DS;
i=8;
while(i>0)
i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1);//读出数据最低位在最前面,这么刚好一个字节 在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20 写一个字节到DS18B20里面
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{ testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;
i++;
DS=1;
i=8;
while(i>0)
i--;
}
else
{ DS=0; //write 0 写0部分
i=8;
while(i>0)
i--;
DS=1;
i++;
i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset();//初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // address all drivers on bus 跳过序列号命令
tmpwritebyte(0x44); // initiates a single temperature conversion发送温度转换命令
}
uint tmp() //get the temperature取得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable 两字节合成一个整型变量
temp=temp|a;
tt=temp*0.0625;//得到真实十进制温度值,因为DS18B20
//能够正确到0.0625度,所以读回数据最低位代表是
//0.0625度。
temp=tt*10+0.5;//放大十倍,这么做目标将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp;
}
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
dula=0;
P0=table[A1]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A2]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main()
{ uchar a;
do
{
tmpchange();
for(a=10;a>0;a--)
{ display(tmp()); //在数码管上显示温度
}
}
while(1);
}
展开阅读全文