1602
仿真可以显示 实际只显示一行,可以帮我看看程序有错吗?
- #include<reg52.h>
- #include<stdlib.h>
- #include<intrins.h>
- #include<eeprom52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define Imax 14000 //此处为晶振为11.0592时的取值,
- #define Imin 8000 //如用其它频率的晶振时,
- #define Inum1 1450 //要改变相应的取值。
- #define Inum2 700
- #define Inum3 3000
- sbit DQ=P2^1;//ds18b20与单片机连接口
- sbit RS=P2^5;
- sbit RW=P2^6;
- sbit EN=P2^7;
- sbit K1=P2^2;
- sbit K2=P2^3;
- sbit K3=P2^4; //按键定义
- sbit PWM=P2^0; //PWM输出
- unsigned char Im[4]={0x00,0x00,0x00,0x00};
- unsigned long m,Tc;
- unsigned char IrOK; //定义红外工作变量
- uchar mode;
- uint TH,TL; //上下限变量
- uchar baif,suiji;
- uchar code zhuanhuan[4]={0,3,5,10};//转换数组
- void jisuan(); //声明计算函数
- char f,dang,count,count1,a_a; //档位
- unsigned char code duan[]={"0123456789abcdef- "};
- unsigned char code str1[]={"L:00.0C H:00.0C"};
- unsigned char code str2[]={"M:0 D:0 T: C"};
- uchar data disdata[5];
- uint tvalue;//温度值
- uchar tflag;//温度正负标志
- void write_eeprom() //内部eeprom写函数
- {
- SectorErase(0x2000); //清空
- SectorErase(0x2c00);
- SectorErase(0x2e00);
- byte_write(0x2c00,TH/256);
- byte_write(0x2c01,TH%256);
- byte_write(0x2c02,TL/256);
- byte_write(0x2c03,TL%256); //将上下限数据保存到eeprom
- byte_write(0x2c04,dang);
- byte_write(0x2c05,mode);
- byte_write(0x2060,0x01);
-
- }
- /******************把数据从单片机内部eeprom中读出来*****************/
- void read_eeprom()
- {
- mode = byte_read(0x2c05);
- dang = byte_read(0x2c04);
- TH = byte_read(0x2c00)*256+byte_read(0x2c01);
- TL = byte_read(0x2c02)*256+byte_read(0x2c03);
- a_a = byte_read(0x2060);
-
- }
- /**************开机自检eeprom初始化*****************/
- void init_eeprom()
- {
- a_a = byte_read(0x2060);
- if(a_a != 1) //新的单片机初始单片机内问eeprom
- {
-
- a_a = 1;
- write_eeprom(); //保存数据
- }
- }
- /*************************lcd1602程序**************************/
- void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
- {unsigned int i,j;
- for(i=0;i<ms;i++)
- for(j=0;j<100;j++);
- }
- void wr_com(unsigned char com)//写指令//
- { delay1ms(10);
- RS=0;
- RW=0;
- EN=0;
- P0=com;
- delay1ms(1);
- EN=1;
- delay1ms(1);
- EN=0;
- }
- void wr_dat(unsigned char dat)//写数据//
- { delay1ms(10);
- RS=1;
- RW=0;
- EN=0;
- P0=dat;
- delay1ms(1);
- EN=1;
- delay1ms(1);
- EN=0;
- }
- void lcd_init()//初始化设置//
- {delay1ms(15);
- wr_com(0x38);delay1ms(5);
- wr_com(0x38);delay1ms(5);
- wr_com(0x08);delay1ms(5);
- wr_com(0x01);delay1ms(5);
- wr_com(0x06);delay1ms(5);
- wr_com(0x0c);delay1ms(5);
- }
- void display(unsigned char *p)//显示//
- {
- while(*p!=' ')
- {
- wr_dat(*p);
- p++;
- delay1ms(2);
- }
- }
- init_play()//初始化显示
- { lcd_init();
- wr_com(0x80);
- display(str1);
- delay1ms(1);
- wr_com(0xc0);
- display(str2);
- }
- /******************************ds1820程序***************************************/
- void delay(unsigned int i)//延时1微秒
- {
- while(i--);
- }
- void ds1820rst()/*ds1820复位*/
- { unsigned char x=0;
- DQ = 1; //DQ复位
- delay(4); //延时
- DQ = 0; //DQ拉低
- delay(100); //精确延时大于480us
- DQ = 1; //拉高
- delay(40);
- }
-
- uchar ds1820rd()/*读数据*/
- { unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- { DQ = 0; //给脉冲信号
- dat>>=1;
- DQ = 1; //给脉冲信号
- if(DQ)
- dat|=0x80;
- delay(10);
- }
- return(dat);
- }
- void ds1820wr(uchar wdata)/*写数据*/
- {unsigned char i=0;
- for (i=8; i>0; i--)
- { DQ = 0;
- DQ = wdata&0x01;
- delay(10);
- DQ = 1;
- wdata>>=1;
- }
- }
-
-
- read_temp()/*读取温度值并转换*/
- {uchar a,b;
- ds1820rst();
- ds1820wr(0xcc);//*跳过读序列号*/
- ds1820wr(0x44);//*启动温度转换*/
- ds1820rst();
- ds1820wr(0xcc);//*跳过读序列号*/
- ds1820wr(0xbe);//*读取温度*/
- a=ds1820rd();
- b=ds1820rd();
- tvalue=b;
- tvalue<<=8;
- tvalue=tvalue|a;
- if(tvalue<0x0fff)
- tflag=0;
- else
- {
- tvalue=~tvalue+1;
-
- tflag=1;
- }
-
- tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
- return(tvalue);
- }
- /*******************************************************************/
-
- void ds1820disp()//温度值显示
- { uchar flagdat;
-
- disdata[1]=tvalue%1000/100+0x30;//十位数
- disdata[2]=tvalue%100/10+0x30;//个位数
- disdata[3]=tvalue%10+0x30;//小数位
-
- if(tflag==0)
- flagdat=0x20;//正温度不显示符号
- else
- flagdat=0x2d;//负温度显示负号:-
-
- wr_com(0xc2);
- wr_dat(duan[mode]);
- wr_com(0xcb);
- wr_dat(disdata[1]);//显示十位
- wr_com(0xcc);
- wr_dat(disdata[2]);//显示个位
- wr_com(0xcd);
- wr_dat(0x2e);//显示小数点
- wr_com(0xce);
- wr_dat(disdata[3]);//显示小数位
- wr_com(0x80+0x02);
- wr_dat(duan[TL%1000/100]);
- wr_com(0x80+0x03);
- wr_dat(duan[TL%100/10]);
- wr_com(0x80+0x05);
- wr_dat(duan[TL%10]);
- wr_com(0x80+0x0b);
- wr_dat(duan[TH%1000/100]);
- wr_com(0x80+0x0c);
- wr_dat(duan[TH%100/10]);
- wr_com(0x80+0x0e);
- wr_dat(duan[TH%10]);
- wr_com(0xc6);
- wr_dat(duan[dang]);
- }
-
- void key() //按键函数
- {
- if(K1==0||(Im[2]==0x47&&IrOK==1)) //按键1按下或者遥控器上的按键按下
- {
- delay(5); //延时去抖
- if(K1==0||(Im[2]==0x47&&IrOK==1)) //再次判断按键按下
- {
- //BUZZ=0;
- //delay(20);
- //BUZZ=1; //按键音
- mode++; //模式加
- if(mode>3) //模式加到大于3
- mode=0; //模式清零
- Im[2]=0;
- IrOK=0; //变量清零
- write_eeprom(); //写入eeprom数据
- while(!K1); //按键释放
- }
- }
- if(K2==0||(Im[2]==0x40&&IrOK==1))
- {
- delay(5);
- if(K2==0||(Im[2]==0x40&&IrOK==1))
- {
- //BUZZ=0;
- //delay(20);
- //BUZZ=1;
- if(mode==0) //模式等于0时
- {
- TH++; //上限加
- if(TH>999) //上限加到大于99.9度
-
- TH=TL+1; //上限等于下限加一
- }
- else if(mode==1) //模式等于1时
- {
- TL++; //下限加
- if(TL>=TH) //下限加到大于等于上限
- TL=TH-1; //下限等于上限减一
- }
- else if(mode==3) //模式等于3时
- {
- dang++; //档位加一
- if(dang>3) //档位大于3时
- dang=0; //档位清零
- }
- Im[2]=0;
- IrOK=0; //红外变量清零
- write_eeprom(); //写入eeprom数据
- while(!K2); //按键释放
- }
- }
- if(K3==0||(Im[2]==0x19&&IrOK==1))
- {
- delay(5);
- if(K3==0||(Im[2]==0x19&&IrOK==1))
- {
- //BUZZ=0;
- //delay(20);
- //BUZZ=1;
- if(mode==0)
- {
- TH--;
- if(TH<=TL)
- TH=TL+1;
- }
- else if(mode==1)
- {
- TL--;
- if(TL>=TH)
- TL=TH-1;
- }
- else if(mode==3)
- {
- dang--;
- if(dang<0)
- dang=3;
- }
- //Im[2]=0;
- //IrOK=0;
- write_eeprom();
- while(!K3);
- }
- }
- }
- void jisuan() //计算函数
- {
- if(mode==0||mode==1||mode==2) //模式0、1、2并且热释电有信号时
- {
- if(tvalue<=TL) //温度小于下限时
- PWM=1; //关闭输出,占空比0%
- else if(tvalue>=TH) //温度大于等于上限
- PWM=0; //打开输出,占空比100%
- else //其他状态时
- {
- baif=(((tvalue-TL)*50)/(TH-TL)); //占空比控制变量计算得到
- //计算方法:当前温度减去下限值乘以5再除以上限减下限
- if(count1>baif) //根据变量判断占空比大小
- PWM=0; //关闭风扇
- else
- PWM=1; //打开风扇
- }
- }
- else if(mode==3) //模式3时
- {
- if(count1>=(zhuanhuan[dang]*5)) //根据档位计算出占空比
- PWM=1;
- else
- PWM=0;
- }
- }
- /********************主程序***********************************/
- void main()
- {
- //定义变量
- unsigned int i=0,j=0;
- EA=1; //打开中断总开关
- EX1=1; //打开外部中断1
- IT1=1; //下降沿有效
- TMOD=0x11; //定时器工作方式
- TR0=0; //关闭T0
- TH0=0;
- TL0=0; //初值0
- ET1=1; //T1允许中断
- TR1=1; //T1打开中断
- TH1=0xfc;
- TL1=0x18; //T1初值1ms
- mode=0; //初始模式0
- TH=300;
- TL=200; //上下限初始值
- init_eeprom(); //初始化eeprom
- read_eeprom(); //读取eeprom数据
-
- init_play(); //初始化显示
- while(1) //进入循环
- {
- jisuan(); //计算函数
- /* count++; //变量加
- if(count>200) //加到大于200
- {
- count=0; //清零
- TR1=0; //关闭定时器T1
- // read_temp();//读取温度
-
- TR1=1; //打开定时器T1
- } */
- read_temp();//读取温度
- ds1820disp();
- jisuan(); //计算函数
- //显示函数 */
- key(); //按键函数
- jisuan(); //计算函数
- }
-
- }
- void timer1() interrupt 3 //定时器T1工作函数
- {
- TH1=0xfc;
- TL1=0x18; //重新赋初值
- count1++; //加
- if(count1>50)
- {
- count1=0;
- }
- }
- void intersvr1(void) interrupt 2 //红外工作函数
- {
- TR0=1;
- Tc=TH0*256+TL0;//提取中断时间间隔时长
- TH0=0;
- TL0=0; //定时中断重新置零
- if((Tc>Imin)&&(Tc<Imax))
- {
- m=0;
- f=1;
- return;
- } //找到启始码
- if(f==1)
- {
- if(Tc>Inum1&&Tc<Inum3)
- {
- Im[m/8]=Im[m/8]>>1|0x80; m++;
- }
- if(Tc>Inum2&&Tc<Inum1)
- {
- Im[m/8]=Im[m/8]>>1; m++; //取码
- }
- if(m==32)
- {
- m=0;
- f=0;
-
- if(Im[2]==~Im[3])
- {
- IrOK=1;
- TR0=0;
- }
- else
- {
- IrOK=0; //取码完成后判断读码是否正确
- }
- }
- //准备读下一码
- }
- }
复制代码
-
-
一周热门 更多>