- #include < reg51.h >
- #include < intrins.h >
- #define uchar unsigned char
- #define uint unsigned int
- //#define lcddata P0
- #define lcddata P1
- sbit dj=P3^3;
- sbit LCDRS=P2^7;
- sbit LCDRW=P2^6;
- sbit LCDEN=P2^5;
- sbit key1=P3^5;//控制温度
- sbit key2=P3^6;//温度加1
- sbit key3=P3^7;//温度减1
- void write_com(uchar com);
- void zdyzfxs();
- unsigned char code mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ;
- sbit DQ = P3^4;//定义DS18B20端口DQ
- bit presence; //ds18b20 DQ被拉低 信号0允许,1禁止
- uint cc,cc2;//变量cc中保存读出的温度值
- float cc1;
- uchar flag;//温度值正负,1负0正
- uint shang,xia;//对比温度暂存变量
- uchar dang;//档位显示
- uchar flagg;
- uchar d1,d2,d3;//显示数据暂存变量
- void write_com(uchar com);
- uchar code cdis0[ ] = "CHECKING";
- uchar code cdis1[ ] = " on " ;
- uchar code cdis5[ ] = "wendu: ";
- uchar cdis2[ ] = "+00.00";
- uchar cdis9[ ] = "00";
- uchar cdis10[ ] = "00";
- uchar cdis11[ ] = "0";
- uchar code cdis6[ ] = "H:";
- uchar code cdis7[ ] = "L:";
- uchar code cdis8[ ] = "dang:";
- uchar code cdis3[ ] = " DS18B20 BUSY " ;
- uchar code cdis4[ ] = " PLEASE CHECK " ;
- unsigned char data temp_data[2] = {0x00,0x00} ;
- //----------------------------------
- void delaylcd(uint z)
- {uchar x,y;
- for(x=z;x>0;x--)
- {for(y=110;y>0;y--);
- }
- }
- /*lcd1602初始化 */
- void lcd_init(void)
- {
- LCDRW=0; //低电平为写
- LCDEN=0;
- write_com(0x38); //使用8位数据开关,显示两行,使用5*7字形
- write_com(0x0c); //显示器开,光标关,字符不闪烁 0x0e 光标开
- write_com(0x06); //字符不动,光标自动右移动一位
- write_com(0x01); //清屏
- }
- /*写命令to lcd */
- /**********************************/
- void write_com(uchar com)//写命令
- {
- LCDRW=0; //低电平为写
- LCDRS=0; //低电平为命令选择
- lcddata=com;
- delaylcd(5);
- LCDEN=1;
- delaylcd(5);
- LCDEN=0;
- }
- /*写数据to lcd */
- /**********************************/
- void write_data(uchar date)
- {
- LCDRW=0; //低电平为写
- LCDRS=1; //高电平为数据选择
- lcddata=date;
- delaylcd(5);
- LCDEN=1;
- delaylcd(5);
- LCDEN=0;
- }
- /*设定显示位置 */
- /********************************/
- void lcd_pos(uchar pos)
- { //第一行第几列直接写pos为几,第二行pos从0x40开始
- write_com(pos | 0x80) ; //数据指针=80+地址变量
- }
- /*自定义字符写入CGRAM */
- /*********************************/
- void mywritetab()
- {
- unsigned char i ;
- write_com(0x40) ; //写CGRAM
- for(i=0;i<8;i++)
- {write_data(mytab[i]);}
- }
- /*******************************ds18b20*******************************************/
- /*ms级别 */
- void ddelay(uint ms)
- {
- uint i;
- uchar j;
- for(i=0;i<ms;i++)
- for(j=0;j<250;j++)
- {
- _nop_(); //一个机器周期,1us
- _nop_(); //适用于精度高的
- _nop_();
- _nop_();
- }
- }
- /*us级延时,延时时间约4+2*i*/
- void Delayus(uchar i)
- {
- while(--i);
- }
- /*复位,每次读写之前都要进行复位*/
- /**********************************/
- bit ow_reset(void)
- {
- DQ = 1 ; //DQ复位
- Delayus(8) ; //稍做延时
- DQ = 0; //拉低约600us
- Delayus(150);
- Delayus(150);
- DQ = 1;//产生上升沿,延时约15~60us
- Delayus(30);
- if(DQ==0) {presence=0;}
- else presence=1;
- return(presence); //等待应答信号 0允许,1禁止
- }
- /*读取数据一位 */
- //---------------------------------
- bit Read_bit()
- {
- uint i = 0;
- bit b = 0;
- DQ = 0; //产生读时隙
- i++; //维持低电平至少1us
- DQ = 1; //1us以上后拉高
- Delayus(2); //延时8us,DO下降沿15内ds18b20输出的数据才有效
- b = DQ; //读取数据
- Delayus(40); //每个读时隙至少持续60us
- return(b);
- }
- /*读取一个字节 */
- //------------------------------------
- uchar Read_byte()
- {
- uchar byte_read = 0;
- uchar i, j;
- for(i=0; i<8; i++)
- {
- j = Read_bit();
- byte_read = (j<<i) | byte_read; //低位读起
- }
- return(byte_read);
- }
- //-----------------------------------------
- /*写一个字节 */
- void Write_byte(uchar byte_to_write)
- {
- uchar i = 0;
- uchar j = 0;
- bit write_bit = 0;
- for(j=0; j<8; j++)
- {
- write_bit = (byte_to_write & 0x01);
- if(write_bit == 1) //写1
- {
- DQ = 0; //产生写时隙
- Delayus(3); //延时15us
- DQ = 1; //写1
- Delayus(40); //延时,写时隙不得低于60us
- }
- else
- {
- DQ = 0; //产生写时隙
- Delayus(50); //延时,保持低约60us~120us
- DQ = 1;
- i++;
- }
- byte_to_write = byte_to_write >> 1;
- }
- }
- //-----------------------------------
- /*读取温度,启动温度转换*/
- /*启动温度转换*/
- void start_convert()
- {
- ow_reset(); // 发出复位脉冲,每次操作都从复位开始
- ddelay(1);
- Write_byte(0xcc); //skip room命令,跳过序列号命令字
- Write_byte(0x44); //启动温度转换命令
- }
- /*读取温度值*/
- void read_tempreture()
- {
- ow_reset(); // 发出复位脉冲,每次操作都从复位开始
- ddelay(1);
- Write_byte(0xcc); //skip room命令
- Write_byte(0xbe); //读取暂存器命令
- temp_data[0] = Read_byte(); //存储温度低字节值 (整数部分低四位和小数部分) 先从低字节读取
- temp_data[1] = Read_byte(); //存储温度高字节值 (其中高五位为符号位)
- }
- //--------------------------------------
- /* CHECKING...显示 */
- void lcd_display()
- {
- uchar m ;
- lcd_init() ; //初始化LCD
- lcd_pos(0) ; //设置显示位置为第一行的第1个字符
- m = 0 ;
- while(cdis0[m] != '\0')
- { //显示字符
- write_data(cdis0[m]) ;
- m++ ;
- }
- }
- //--------------------------------------
- /* DS18B20 OK 显示菜单 */
- void Ok_Menu ()
- {
- uchar m ;
- lcd_init() ; //初始化LCD
- lcd_pos(0) ; //设置显示位置为第一行的第1个字符
- m = 0 ;
- while(cdis1[m] != '\0')
- { //显示字符
- write_data(cdis1[m]) ;
- m++ ;
- }
- }
- //-----------------------------------
- /*DS18B20 ERR0R */
- /*PLEASE CHECK 显示 */
- void Error_Menu ()
- {
- uchar m ;
- lcd_init() ; //初始化LCD
- lcd_pos(0) ; //设置显示位置为第一行的第1个字符
- m = 0 ;
- while(cdis3[m] != '\0')
- {
- write_data(cdis3[m]) ; //显示字符
- m++ ;
- }
- lcd_pos(0x40) ; //设置显示位置为第二行第1个字符
- m = 0 ;
- while(cdis4[m] != '\0')
- {
- write_data(cdis4[m]) ; //显示字符
- m++ ;
- }
- }
- //------------------------------------
- /*Temp: ℃显示 */
- void temp_c()
- {
- uchar m;
- lcd_init() ;
- lcd_pos(0);
- m=0;
- while(cdis5[m]!='\0')
- {
- write_data(cdis5[m]);
- m++;
- }
- // write_data(0xDF); //°
- zdyzfxs();lcd_pos(13);
- write_data('C');
- }
- //-----------------------------------
- /*自定义字符显示 */
- void zdyzfxs()
- {
- mywritetab();
- lcd_pos(12);
- write_data(0x00);
- }
- //显示上下限
- void shangxian()
- {
- uchar m;
- cdis9[0]=shang/10+0x30;
- if(cdis9[0]==0x30)
- {cdis9[0]=0x20;
- }
- cdis9[1]=shang%10+0x30;
- lcd_pos(0x42); //显示字母H 和上限温度值
- m=0;
- while(cdis9[m]!='\0')
- {
- write_data(cdis9[m]); //调用显示函数
- m++;
- }
- }
- void dangwei()
- {
- uchar m;
- cdis11[0]=dang+0x30;
- lcd_pos(0x4f); //显示字母H 和上限温度值
- m=0;
- while(cdis11[m]!='\0')
- {
- write_data(cdis11[m]); //调用显示函数
- m++;
- }
- }
- void xiaxian()
- {
- uchar m;
- cdis10[0]=xia/10+0x30;
- if(cdis10[0]==0x30)
- {cdis10[0]=0x20;
- }
- cdis10[1]=xia%10+0x30;
- lcd_pos(0x47); //显示字母H 和上限温度值
- m=0;
- while(cdis10[m]!='\0')
- {
- write_data(cdis10[m]); //调用显示函数
- m++;
- }
- }
- void zi_keyscan()//自动模式按键扫描函数
- {
- if(key1==0) //设置键按下
- {
- Delayus(10); //延时去抖
- if(key1==0)flagg=1; //再次判断按键,按下的话进入设置状态
- while(key1==0);//松手检测 //按键释放
- }
- while(flagg==1) //进入设置上限状态
- {
- if(key1==0) //判断设置键是否按下
- {
- Delayus(10); //延时去抖
- if(key1==0)flagg=2; //按键按下,进入设置下限模式
- while(key1==0);//松手检测
- }
- if(key2==0) //加键按下
- {
- Delayus(10); //延时去抖
- if(key2==0) //加键按下
- {
- shang++; //上限加5
- if(shang>=100)shang=100; //上限最大加到100
- }while(key2==0);//松手检测
- }
- if(key3==0) //减键按下
- {
- Delayus(10); //延时去抖
- if(key3==0) //减键按下
- {
- shang--; //上限减1
- if(shang<=10)shang=10; //上限最小减到10
- }while(key3==0);//松手检测
- }
- shangxian();
- }
- while(flagg==2) //设置下限
- {
- //显示字母L 显示下限温度值
- //以下注释同上
- if(key1==0)
- {
- Delayus(10);
- if(key1==0)flagg=0;
- while(key1==0);//松手检测
- }
- if(key2==0)
- {
- Delayus(10);
- if(key2==0)
- {
- xia+=1;
- if(xia>=99)xia=99;
- }while(key2==0);//松手检测
- }
- if(key3==0)
- {
- Delayus(10);
- if(key3==0)
- {
- xia-=1;
- if(xia<=0)xia=0;
- }while(key3==0);//松手检测
- }
- xiaxian();
- }
- /* while(flagg==0) //设置下限
- {
- //显示字母L 显示下限温度值
- if(key1==0)
- {
- Delayus(10);
- if(key1==0)flagg=1;
- while(key1==0);//松手检测
- }
- }*/
- }
- void zi_dong()//自动温控模式
- {
- uchar i;
- //dangwei();
- zi_keyscan();//按键扫描函数
- //调用显示函数
- //调用显示函数
- if(cc1<xia){dj=0;dang=0;}//低于下限 档位为0 电机停止
- dangwei();
- if((cc1>=xia)&&(cc1<=shang))//温度大于下限,小于上限 1挡
- {
- dang=1; //档位置1
- for(i=0;i<3;i++){dj=0;dangwei();zi_keyscan();} //PWM通过延时得到
- for(i=0;i<6;i++){dj=1;dangwei();zi_keyscan();}
- }
- if(cc1>shang){dj=1;dang=2;}//高温全速
- dangwei();
- }
- //------------------------------------
- /*温度显示 */
- void temperature_display()
- {
- uchar m;
- flag=0;
- ddelay(2);
- EA=0; //DS18B20读写数据按照严格的时序,最好不要被打断,故把所有中断关闭
- start_convert(); //启动温度转换
- ddelay(250);
- read_tempreture(); //读取温度
- EA=1;
- cc=temp_data[1]*256.0+temp_data[0];
- if(temp_data[1]>0xF8) {flag=1;cc=~cc+1;} else flag=0;
- cc1=cc*0.0625;
- cc2=cc1*100;
- cdis2[1]=cc2/1000+0x30;
- if(cdis2[1]==0x30)
- {cdis2[1]=0x20;}
- cdis2[2]=cc2/100%10+0x30;
- cdis2[4]=cc2%100/10+0x30;
- cdis2[5]=cc2%10+0x30;
- if(flag==1)
- cdis2[0]='-';
- else
- cdis2[0]='+';
- lcd_pos(6) ; //设置显示位置为第一行的第6个字符
- m=0;
- while(cdis2[m]!='\0')
- { //显示字符
- write_data(cdis2[m]) ;
- m++;
- }
-
- }
- void test()
- {
- uchar m;
- lcd_pos(0x40);
- m=0;
- while(cdis6[m]!='\0')
- {
- write_data(cdis6[m]);
- m++;
- }
- lcd_pos(0x45);
- m=0;
- while(cdis7[m]!='\0')
- {
- write_data(cdis7[m]);
- m++;
- }
- lcd_pos(0x4B);
- m=0;
- while(cdis8[m]!='\0')
- {
- write_data(cdis8[m]);
- m++;
- }
- }
- //---------------------------------
- /*主函数 */
- void main()
- {
- uchar j;
- shang=30;
- xia=20;
- lcd_display();
- ddelay(100);
- ow_reset();
- if(presence==0)
- {
- Ok_Menu ();
- ddelay(100);
- temp_c();zdyzfxs();
- test();
- shangxian();xiaxian();
- while(1)
- {
- temperature_display(); //读取温度值
- for(j=0;j<100;j++) zi_dong();
- }
- }
- else
- {
- Error_Menu ();
- while(1)
- {
- ow_reset();
- if(presence==0)
- {
- Ok_Menu ();
- ddelay(1000);
- temperature_display();
- }
- }
- }
- }
复制代码 |