|
功能:1.显示温度;
2.显示温度上下限;
3.上下限可调;
4.显示温度传感器序列码;
5.温度异常,分阶段报警。
源程序:
- //////////////////////////////////////////////////////////////////// /////////////////////////////////////////
- /*
- 按键控制LCD显示内容,(id号与当前温度/上下限以及)
- 按键可调温度的上下限。
- */
- #include<reg52.h>
- #include<intrins.h> //nop
- #define uchar unsigned char
- #define uint unsigned int
- sbit ds = P2^2; //DS18b20-->DS
- sbit beep = P2^3; //buzz
- sbit wela = P2^7; //
- sbit dula = P2^6; //
- sbit LCDEN = P3^4; // EN
- sbit rs = P3^5; //数据 命令选择端
- sbit rw = P3^6; //读写选择端
- uchar datstr[] = "Temperature:";
- uchar str[4]; //uchartostr函数转换的字符串 同时可以把16进制转成10进制 存高低温上下限
- uchar str1[5]; //uchartostr1函数转换的字符串 同时可以把16进制转成10进制 存温度
- //sbit IDcheck=P2^5;
- //sbit IDready=P3^1;
-
- int flip=0; // 用来读flip1 用于反转
- int flip1=1; //=1 开单键&用于双键反转
- bit flag;//ds初始化成功标志
- uchar ds_rom[16]; //存序列码 存入的是字节
-
- uchar H=40,L=10,Key_value; //初始上下限温度,
- uchar code table[]={'0','1','2','3','4',
- '5','6','7','8','9',
- 'A','B','C','D','E','F' //序列码字节转ASCII专用数组
- };
- void delay(uint z); //延时函数 1602专用
- void write_com(uchar com); //写命令
- void write_data(uchar date); //写数据
- void init_1602(); //初始化1602
- uchar *uchartostr(uchar num); //将一个字节的数据转换为字符串 或10进制 返回数组 上下限显示用
- uchar *uchartostr1(uint num); //将一个字节的数据转换为字符串 或10进制 返回数组 温度显示用
- void lcd_dis(uchar X,uchar Y,uchar *dis); //显示数据数组
- void lcd_distostr(uchar X,uchar Y);//显示字符串temperature 数组
-
- void TempDelay(uchar us) //delay
- {
- while(us--); //6.51us
- }
- void ds_reset() //ds18b20 init
- {
- ds=1;
- _nop_(); //1us
- ds=0;
- TempDelay(80); //延时略长些
- ds=1;
- TempDelay(6);
- if(ds==0)
- flag=0; //记录应答电平
- else
- flag=1; //失败
- TempDelay(20); //延时
- ds=1; //置1结束
- }
- bit ds_read_bit() //(||)read a bit
- {
- bit dat;
- ds=0; //DQ已经是1了
- _nop_(); //1us delay
- _nop_();
- ds=1;
- _nop_();
- dat=ds; //读一位
- TempDelay(12); //延时稍长
- return dat;
- }
- uchar ds_read_byte() //read a byte
- {
- uchar i,j,value;
- for(i=0;i<8;i++)
- {
- j=ds_read_bit(); //1 bit上一个函数 @先读到的位为最低位
- value=(j<<7)|(value>>1); //新bit左移7位,旧状态右移一位空出最高位,组合
- }
- return value;
- }
- void ds_write_byte(uchar dat) //写一字节
- {
- uchar i,onebit;
- for(i=0;i<8;i++) //8bit
- {
- onebit=dat&0x01; //取最低位
- if(onebit) //最低位为1 写1
- {
- ds=0;
- TempDelay(1);
- ds=1;
- _nop_();
- }
- else //写0
- {
- ds=0;
- TempDelay(11); //delay 长一些 因为省去ds=0
- ds=1;
- _nop_();
- }
- dat>>=1; //右移一位
- }
- }
- void ds_change() //jump rom &start temp convert
- {
- ds_reset() ;
- while(flag!=0); // //检测到设备 成功返回0
- ds_write_byte(0xcc); //jump ROM
- ds_write_byte(0x44); //TEMP convert
- }
- void Read_ROM() //序列码读入数组 ds_rom[i]
- {
- int i;
- uchar a; //序列码缓冲
- ds_reset();
- while(flag!=0);
- ds_write_byte(0x33); //read rom序列码
- for(i=15;i>0;i--)
- {
- a=ds_read_byte();
- ds_rom[i--]=(0x0f&a); //取低四位 15
- ds_rom[i]=((0xf0&a)>>4); //取高四位 14
- }
- // ds_rom[16]='\0';
- }
- uint get_temperature() // 温度采集
- {
- uint temp;
- float ftemp;
- uchar a,b;
- ds_reset();
- while(flag!=0);
- ds_write_byte(0xcc); //jump ROM
- ds_write_byte(0xbe); //read 标签存储器
- a=ds_read_byte(); //read low8
- b=ds_read_byte(); //read high8
-
- temp=b;
- temp<<=8;
- temp|=a; //高低8位结合
- ftemp=temp*0.0625; //12bit-->0.0625*10 (除以16,2^4,右移4位)
- ftemp=ftemp*10+0.5; //取1位小数后四舍五入
- temp=ftemp; //现在为10倍temp的整数 便于显示
- return temp;
- }
- void IDshow(); //显示序列码
- void WarningShow(); //温度上下限显示
- void key() // 有问题 按键扫描
- {
- Key_value = P3;
- Key_value = Key_value & 0x0f;
- if ( Key_value != 0x0f )
- {
- delay(5);
- if ( Key_value != 0x0f ) //qu dou
- {
- if( Key_value == 0x0c ) //s2s3同时按下
- {
- delay(5);
- if( Key_value == 0x0c ) //
- {
- flip=flip1; //状态反转 读上一次状态 每同时按一次 反转一次
- if(flip==1)
- {
- IDshow();
- flip1=0; //flip1==1 关闭单键调节功能
- }
- else if(flip==0)
- {
- WarningShow(); //显示上下限
- flip1=1; //flip1==1 时才能监测其他按键来调上下限
- }
- }
- }
-
- if( (Key_value == 0x0e)&(flip1==1) )
- { //*
-
- H++;
- if (H==100)
- H=40;
-
- }
- if( (Key_value == 0x0d)&(flip1==1) )
- {
- H--;
- if (H==0)
- H=99;
- if (H==L)
- H=H+1;
- }
- if( (Key_value == 0x0b)&(flip1==1) )
- {
- L++;
- if (L==H)
- L=0;
- }
- if( (Key_value == 0x07)&(flip1==1) )
- {
- L--;
- if (L==0)
- if(H>10)
- L=10;
- else
- L=H-1;
- }
- }
- }
-
- }
- void IDshow()
- {
- uint i;
- Read_ROM();
- write_com( 0x80 + 0 + 0 );
- for(i=0;i<16;i++)
- {
- write_data(table[ds_rom[i]]); //
- }
-
- }
- void WarningShow()
- {
- write_com( 0x80 + 0 + 0);
- write_data( ' ' );
- write_data( ' ' );
- write_data( ' ' );
- write_com( 0x80 + 0 + 3);
- write_data( 'H' );
- write_data( ':' );
- write_com( 0x80 + 0 + 7);
- write_data( ' ' );
- write_com( 0x80 + 0 + 8);
- write_data( 'L' );
- write_data( ':' );
- write_com( 0x80 + 0 + 12);
- write_data( ' ' );
- write_data( ' ' );
- write_data( ' ' );
- write_data( ' ' );
- lcd_dis( 0,5,uchartostr( H ) );
- lcd_dis( 0,10,uchartostr( L ) );
- }
- /****************************************************MAIN*************************************************************/
- /****************************************************MAIN*************************************************************/
- /****************************************************MAIN*************************************************************/
- void main()
- {
- uint i;
- // rd = 0;
- init_1602(); //
-
- WarningShow();
- // H = 40;
- // L = 10;
- lcd_dis( 0,5,uchartostr( H ) );
- lcd_dis( 0,10,uchartostr( L ) );
- lcd_distostr(1,0); //TEMPERATURE
- //init warn
-
- ds_change();
- delay(800); ////85C
- while(1)
- {
- ds_change();
- i = get_temperature(); //采温度
-
- lcd_dis( 1,12,uchartostr1( i ) ); //str1 显示温度
- if(flip1==0);
- else if(flip1==1) //启动单键时
- {
- lcd_dis( 0,5,uchartostr( H ) ); //上下限-->str
- lcd_dis( 0,10,uchartostr( L ) );
- }
-
- //报警
- if ( i >=(10*H) )
- {
- P1 = 0x33;
- }
- else if (i<=(10*L))
- {
- P1 = 0xcc;
- }
- else
- {
- P1 = 0xff;
- }
- key();
- }
- }
- //1602辅助小函数
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=120;y>0;y--);
- }
- void write_com(uchar com) //写命令
- {
- P0=com;
- rs=0; //写命令
- LCDEN=0;
- delay(10);
- LCDEN=1;
- delay(10);
- LCDEN=0;
-
- }
- void write_data(uchar date) //写数据
- {
- P0=date;
- rs=1; //写数据
- LCDEN=0;
- delay(10);
- LCDEN=1;
- delay(10);
- LCDEN=0;
-
- }
- void init_1602() //初始化1602
- {
- rw=0;
- dula=0;
- wela=0; //防止数码管乱闪
- write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
- delay(20);
- write_com(0x0c); //显示模式设置:开显示 不显示光标 也不闪烁
- delay(20);
- write_com(0x06); //显示模式设置:光标右移,字符不移,不移动屏幕
- delay(20);
- write_com(0x01); //清屏幕指令,将以前的显示内容清除
- delay(20);
- }
- /////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////x数组 准备显示//////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- uchar *uchartostr(uchar num) //将一个字节的数据转换为字符串 或10进制 返回数组首地址 (上下限)
- {
- uchar x1,x0,i;
- x1=num%100/10;
- x0=num%100%10;
- i=0; //数组第一元素
- str[i]=x1+48; //变ASCII码
- i++;
- str[i]=x0+48;
- i++;
- str[i]='\0'; //结束符
- return str;
- }
- uchar *uchartostr1(uint num) //将一个字节的数据转换为字符串 或10进制 返回数组(温度专用)
- {
- uchar x2,x1,x0,i;
- x2=num/100;
- x1=num%100/10;
- x0=num%10;
- i=0; //数组第一元素
- if(x2!=0)
- {
- str1[i]=x2+48; //变ASCII码 十位
- i++;
- }
- if(1)
- {
- str1[i]=x1+48; //个位
- i++;
- str1[i]=46; // "." 小数点
- i++;
- }
- str1[i]=x0+48; //十分位
- i++;
- str1[i]='\0'; //结束符
- return str1;
- }
- /////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////x显示////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- void lcd_dis(uchar X,uchar Y,uchar *dis) //显示数据数组
- {
- uchar pos; //位置
- switch(X)
- {
- case 0:X=0x00; // line1
- break;
- case 1:X=0x40; //line2
- break;
- break;
- default:break;
- }
- pos =0x80+X+Y; //
- write_com(pos); //写入显示地址设置
- while(*dis!='\0') //
- {
- write_data(*dis++);
- }
- }
- void lcd_distostr(uchar X,uchar Y)//显示字符串temperature 数组
- {
- uchar pos,i;
- i=0; //设定从数组中的第几个字符串开始显示
- switch(X)
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
下载:
ds18b20_oo.zip
(60.74 KB, 下载次数: 36)
|
评分
-
查看全部评分
|