如图所示,使用DS18B20数字测温传感器,通过LCD1602显示实时温度,温度超出上下限后蜂鸣器响铃表示警报。 工程分几个文件,Main.c是主函数所在的代码文件,Ctl是温度控制代码文件,Disp是液晶显示代码文件

SysHeader.h:
#ifndef SYSHEADER_H
#define SYSHEADER_H
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define delayNOP( ) {_nop_();_nop_();_nop_();_nop_();}
#endif
Main.c:
#include"SysHeader.h" //系统头文件
#include"Disp.h" //显示温度
#include"Ctl.h" //模拟控制
void main()
{
TMOD=0x01; //方式一
IE=0x82; //10000010b:允许T0中断
TR0=0; //0定时器停止工作
//Song_Tone_Pointer=Song1_Tone;//初始化音符序列基址
//Song_Time_Pointer=Song1_Time;//音乐延时序列基址
InitLCD();
Read_Temperature( );
Delay(50000);
Delay(50000);
while(1)
{
if(Read_Temperature( ))
{
Display_Temperature( );
}
DelayXus(100);
}
}
Ctl.h
#ifndef CTL_H
#define CTL_H
#include"SysHeader.h"
#include"Disp.h"
//extern sbit DQ; //控制器输入
extern char DS18B20_IS_OK; //控制器状态
//延时2
void Delay(uint x);
//初始化DS18B20
uchar Init_DS18B20( );
//读一字节
uchar ReadOneByte( );
//写一字节
void WriteOneByte(uchar dat);
//读取温度值
uchar Read_Temperature( );
#endif
Ctl.c
#include"Ctl.h"
sbit DQ =P3^0; //控制器输入
char DS18B20_IS_OK=1;//控制器状态
//延时2
void Delay(uint x)
{
while(--x);
}
//初始化DS18B20
uchar Init_DS18B20( )
{
uchar status;
DQ=1;
Delay(8);
DQ=0;
Delay(90);
DQ=1;
Delay(8);
status=DQ;
Delay(100);
DQ=1;
return status;
}
//读一字节
uchar ReadOneByte( )
{
uchar i,dat=0;
DQ=1;_nop_( );
for(i=0;i<8;i++)
{
DQ=0;dat>>=1;
DQ=1;
_nop_( );
_nop_( );
if(DQ) dat|=0x80;
Delay(30);
DQ=1;
}
return dat;
}
//写一字节
void WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
}
}
//读取温度值
uchar Read_Temperature( )
{
if(Init_DS18B20( )==1) //DS18B20故障
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xcc); //跳过序列号
WriteOneByte(0x44); //启动温度转换
Init_DS18B20( );
WriteOneByte(0xcc); //跳过序列号
WriteOneByte(0xbe); //读取温度寄存器
Temp_Value[0]=ReadOneByte( ); //温度低8位
Temp_Value[1]=ReadOneByte( ); //温度高8位
DS18B20_IS_OK=1;
}
return DS18B20_IS_OK;
}
Disp.h
#ifndef DISP_H
#define DISP_H
#include"SysHeader.h"
extern uchar Temp_Value[2];
//音符指针,延时指针
extern uchar *Song_Tone_Pointer,*Song_Time_Pointer;
//音乐音符序列
extern uchar code Song1_Tone[];
//音乐延时序列
extern uchar code Song1_Time[];
void InitSong();
//延时1
void DelayXus(int x);
//LCD忙等待
bit LCD_Busy_Check();
//写指令
void Write_LCD_Command(uchar cmd);
//写数据
void Write_LCD_Data(uchar dat);
//初始化LCD
void InitLCD();
//在LCD上显示当前温度
void Display_Temperature( );
//设置显示位置
void Set_LCD_POS(uchar pos);
#endif
Disp.c
#include"Disp.h"
sbit BEEP=P3^1; //报警声输出
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_EN=P1^2;
uchar code Temp_Disp_Title[] = ("Safe Temp<=37 C");
uchar Current_Temp_Display_Buffer[] = ("Temp: ");
//温度字符
uchar code Temperature_Char[8] = {0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};
//温度小数位对照表
uchar code df_Table[] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar CurrentT = 0; //当前读取的温度整数部分
uchar Temp_Value[2] = {0x00,0x00}; //DS18B20读取的温度值
uchar Display_Digit[] = {0,0,0,0}; //待显示的各温度数位
//声响延时
uint code ToneDelay=65000;
//延时
void DelayMS(uint ms)
{
uchar t;
while(ms--)
for(t=0;t<120;t++);
}
//T0定时器控制播放
void Timer0_Play_Music( ) interrupt 1
{
TH0=ToneDelay/256;
TL0=ToneDelay%6;
BEEP=!BEEP;
}
void PlaySound()
{
int i;
for(i=0;i<10;i++)
{
//Tone_Index=Song_Tone_Pointer[ i];
TR0=1;//启动定时器0
DelayMS(15);
TR0=0;//关闭定时器0
}
}
//延时1
void DelayXus(int x)
{
uchar i;
while(x--)
for(i=0;i<200;i++);
}
//LCD忙等待
bit LCD_Busy_Check()
{
bit result;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
delayNOP();
result=(bit)(P2&0x80);
LCD_EN=0;
return result;
}
//写指令
void Write_LCD_Command(uchar cmd)
{
while(LCD_Busy_Check( ));
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
_nop_( );
_nop_( );
P2=cmd;
delayNOP();
LCD_EN=1;
delayNOP();
LCD_EN=0;
}
//写数据
void Write_LCD_Data(uchar dat)
{
while(LCD_Busy_Check( ));
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P2=dat;
delayNOP();
LCD_EN=1;
delayNOP();
LCD_EN=0;
}
//初始化LCD
void InitLCD()
{
Write_LCD_Command(0x01);
DelayXus(5);
Write_LCD_Command(0x38);
DelayXus(5);
Write_LCD_Command(0x0c);
DelayXus(5);
Write_LCD_Command(0x06);
DelayXus(5);
}
//在LCD上显示当前温度
void Display_Temperature( )
{
uchar i;
//延时值与负号标识
uchar t=150,ng=0;
//高5位全为1(0xF8)则为负数,为负数时取反加1,并设置负数标识
if((Temp_Value[1]&0xf8)==0xf8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00) Temp_Value[1]++;
ng=1;//负号标识置1
}
//查表得到温度小数部分
Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];
//获取温度整数部分(高字节中的低3位与低字节中的高4位,无符号)
CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
//将整数部分分解为3位待显示数字
Display_Digit[3]=CurrentT/100;
Display_Digit[2]=CurrentT0/10;
Display_Digit[1]=CurrentT;
//刷新LCD显示缓冲
Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';
Current_Temp_Display_Buffer[10]='.';
Current_Temp_Display_Buffer[ 9]=Display_Digit[1]+'0';
Current_Temp_Display_Buffer[ 8]=Display_Digit[2]+'0';
Current_Temp_Display_Buffer[ 7]=Display_Digit[3]+'0';
//高位为0时不显示
if(Display_Digit[3]==0)
Current_Temp_Display_Buffer[7]=' ';
//高位为0且次高位为0时,次高位不显示
if(Display_Digit[2]==0&&Display_Digit[3]==0)
Current_Temp_Display_Buffer[8]=' ';
//负号显示在恰当位置
if(ng)
{
if(Current_Temp_Display_Buffer[8]==' ')
Current_Temp_Display_Buffer[8]='-';
else if(Current_Temp_Display_Buffer[7]==' ')
Current_Temp_Display_Buffer[7]='-';
else
Current_Temp_Display_Buffer[6]='-';
}
//在第一行显示标题
Set_LCD_POS(0x00);
for(i=0;i<16;i++)
{
Write_LCD_Data(Temp_Disp_Title[ i]);
}
//在第二行显示当前温度
Set_LCD_POS(0x40);
for(i=0;i<12;i++)
{
Write_LCD_Data(Current_Temp_Display_Buffer[ i]);
}
//显示温度符号
Set_LCD_POS(0x4e);
Write_LCD_Data(0x00);
Set_LCD_POS(0x4c);
Write_LCD_Data(0x00);
Set_LCD_POS(0x4d);
Write_LCD_Data('C');
//超过预设温度,报警
if(CurrentT>37)
{
PlaySound();
}
}
//设置显示位置
void Set_LCD_POS(uchar pos)
{
Write_LCD_Command(pos|0x80);
}
|
|