基于PIC16F877单片机与DS18B20的温度采集与显示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

河北联合大学轻工学院
QINGGONG COLLEGE, HEBEI UNITED UNIVERSITY 《PIC单片机课程设计》
学生姓名:肖晓峰
学号:201124520121
学部:信息科学技术部
专业班级:电信1
指导教师:曹义
2014年7 月 4 日
本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICC C语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。

2.1 设计题目:
基于PIC16F877单片机与DS18B20的温度采集与显示
2.2 功能实现:
实时温度显示,并具有超限报警功能。

输出显示采用LCD1602。

2.3 设计要求:
自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus 仿真,最终可实现脱机运行。

三、设计原理说明
3.2 显示模块
如用LCD1602作为显示设备,要求显示屏分两行显示,第一行显示日期(年-月-日)和星期,第二行显示时间(时:分:秒)和温度。

显示秒由00一直加到59,分钟数也由00加到59,小时采用24小时制,由00加到23,如此循环显示。

3.3 按键模块
按键用来作为时间调整。

要求至少设计4个按键,按键1作为设置键;按键2、按键3分别为增加、减少键,在设置键按下时,此两个按键方有效;按键4是确定键,在设置键按下时方才有效。

3.4 温度采集模块
DS18B20是美国DALLAS公司推出的单总线数字温度传感器。

DS18B20内部集成了温敏元件、数据转换芯片、存储器芯片和计算机接口芯片等多功能模块。

其主要技术特点有:具有独特的单线接口方式;可以通过数据线供电,具有超低功耗工作方式;测温范围为-55℃~125℃,测温精度为0.5℃;温度转换精度9~12位可编程,直接将温度转换值以二进制数码的方式串行输出。

四、硬件原理图(含原理图、电路仿真图)
图2电路仿真图
五、软件设计
(含流程图、带注释的程序清单)程序设计流程图
主文件he
//**********************************************/
#include<pic.h>
__CONFIG(0x3B31);
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
//宏定义
#define DQ RC1 //温度数据口
#define DQ_HIGH() TRISC1=1
#define DQ_LOW() TRISC1=0;DQ=0
#define uchar unsigned char
#define uint unsigned int
#define RS RA0 //LCD功能选择位
#define RW RA1 //读写选择
#define EN RA2 //使能
//变量定义
int temper;
char f = 0 ;
uchar a1,a2,a3,a4;
uchar Prompt[]="P1ress K1 - K3 To Start Demo Prog";
//各种申明
void init();
void DelayMS(uint ms);
uchar Busy_Check();
void Write_LCD_Command(uchar cmd);
void Write_LCD_Data(uchar dat);
void Initialize_LCD();
void ShowString(uchar x,uchar y,uchar *str);
void Showword0(uchar x,uchar y,char word );
void Showword1(char word );
void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4);
//18b20
void delay(uint x);
void delayus(uint,uchar);
void init();
void write_byte(uchar date);
uchar read_byte();
void get_tem();
//***子函数****************************************/
//系统初始化函数
void init()
{
ADCON1=0X07; //设置A口为普通数字口
TRISA =0X00; //设置A口方向为输出TRISB =0x00;
OPTION=0x00; //B口电阻上拉TRISC = 1;
PORTC = 0x20;
TRISD =0X00;
TRISD =0x00;
}
//延时函数
void delayus(uint x,uchar y)
{
uint i;
uchar j;
for(i=x;i>0;i--);
for(j=y;j>0;j--);
}
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
//ds18b20复位函数
void reset()
{
uchar st=1;
DQ_HIGH(); //开始于高电平NOP();NOP(); //延时2us
while(st)
{
DQ_LOW();
delayus(70,30); //750
DQ_HIGH(); //释放总线
delayus(4,4); //等70
if(DQ==1) //应答判断
st=1;
else
st=0;
delayus(50,10); //延时450
}
}
//ds18b20写函数
void write_byte(uchar date)
{
uchar i,temp;
DQ_HIGH(); //开始于高电平
NOP();NOP();
for(i=8;i>0;i--)
{
temp=date&0x01;//01010101 //分位写入
DQ_LOW();
delayus(0,0); //15
if(temp==1)
DQ_HIGH();
delayus(2,2); //45
DQ_HIGH();
date=date>>1;//00101010
}
}
//ds18b20读函数
uchar read_byte()
{
uchar i,date;
static bit j;
for(i=8;i>0;i--)
{
date=date>>1;
DQ_HIGH(); //开始于高电平
NOP();NOP();
DQ_LOW();
NOP();NOP();NOP();NOP();NOP();NOP(); //6
DQ_HIGH();
NOP();NOP();NOP();NOP(); //4
j=DQ; //读取总线
if(j==1)
date=date|0x80;//1000 0000
delayus(1,1); //30 }
return (date); //返回函数值
}
//温度读取处理函数
void get_tem()
{
uchar tem1,tem2,num;
float aaa;
reset(); //复位
write_byte(0xCC);//跳过ROM
write_byte(0x44);//温度转换
reset();
write_byte(0xCC); //跳过ROM
write_byte(0xBE); //温度传递
tem1=read_byte(); //读取低8位
tem2=read_byte();//读取高8位
if(tem2>7) //符号判断
{tem2=255-tem2;
tem1=255-tem1;
f=1;
}
else {f=0;}
aaa=(tem2*256+tem1)*6.25*8; //转化为实际温度值temper=(int)aaa; //强行转化位整数a1=temper/1000; //十进制分位
a2=temper%1000/100;
a3=temper%100/10;
a4=temper%10;
if(a1>7||a1<5) RD7=1;
else RD7=0;
}
//延时
void DelayMS(uint ms) //毫秒
{
uchar i;
while(ms--) for(i=0;i<120;i++);
}
//LCD忙检查函数
uchar Busy_Check()
{
uchar LCD_Status;
RS=0; //寄存器选择(0指令1数据)RW=1; //读状态寄存器
EN=1; //开始读
DelayMS(1);
LCD_Status=PORTB;
EN=0;
return LCD_Status;
}
//写LCD命令函数
void Write_LCD_Command(uchar cmd)
{
// while((Busy_Check()&0x80)==0x80); //忙等待
RS=0; //选择命令寄存器
RW=0; //写
EN=0;
PORTB=cmd;EN=1;DelayMS(1);EN=0;
}
//LCD发送数据函数
void Write_LCD_Data(uchar dat)
{
// while((Busy_Check()&0x80)==0x80); //忙等待
RS=1;RW=0;EN=0;PORTB=dat;EN=1;DelayMS(1);EN=0;
}
//LCD初始化函数
void Initialize_LCD()
{
Write_LCD_Command(0x38);DelayMS(1); //38:数据长8位,两行显示,字体5*7点阵(80)
Write_LCD_Command(0x01);DelayMS(1); //清屏
Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移
Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关;0x0e 是开光标
}
//显示字符函数
void Showword0(uchar x,uchar y,char word ) //y:行地址,x:列地址{
if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置(x,0)第一行
if(y==1) Write_LCD_Command(0xc0|x); // (x,1)第二行
Write_LCD_Data(word+0x30); //str[i]等价于*(str+i)
}
//显示温度函数
void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4)
{
if(f){Showword0(0,0,-3 );} //负号
Showword0(1,0,num1 ); //十位
Showword0(2,0,num2 );
Showword0(3,0,-2 ); //小数点
Showword0(4,0,num3 );
Showword0(5,0,num4 );
DelayMS(5);
}
//主函数
void main()
{
init(); //调用系统初始化函数Initialize_LCD(); //LCD初始化
while (1)
{ get_tem(); //读取温度
write_shuzi(a1,a2,a3,a4 ); //显示
}
}
六、设计总结
1 打好基础,清楚硬件工作原理,性能,以便于编程。

2 程序调试要一步一步想清楚,思路清晰,知道每一步是要做什么,一步一调试,不然某些错误很难找到原因。

3 程序模块化,方便以后调用,
4 仿真现象和计算机的性能有关,不同的计算机性能对同一程序的仿真,会有一定的差异,单是对程序运行时间长度的仿真是精确的。

设计成绩:教师签名:
年月日。

相关文档
最新文档