如图所示,使用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); } |
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |