|
166879.png (116.28 KB, 下載次數(shù): 50)
下載附件
原理圖
2020-4-28 10:43 上傳
這是完整代碼,幫我看看RHTke'y那部分,主程序我按下去1602顯示屏數(shù)值不會改變,是為什么,那里錯了?
這個沒有程序錯誤,我覺得是邏輯寫錯了,搞不來,求大神指導一下.。。
單片機源程序如下:
- #include <stdio.h>
- #include <reg52.h>
- #include <intrins.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulongint unsigned long int
- uint code tab[2][11]={0,10,20,30,40,50,60,70,80,90,100,7351,7224,7100,6976,6853,6728,6600,6468,6330,6186,6033};//濕敏電容表格
- ulongint F=0;
- ulongint T0_count=0,T1_count=0;
- bit flag=0;//flag的取值只能是0或1
- ulongint RH=0;
- ulongint u=50;//濕度上限值
- ulongint j=25;//濕度下限值
- int h=25;//溫度上限值
- int g=10;//溫度下限值
- void delay1ms()//(3j+2)*i,延時1ms
- {
- unsigned char i,j;
- for(i=0;i<10;i++)
- for(j=0;j<33;j++);
- }
- void delaynms(unsigned char n)//延時若干毫秒
- {
- unsigned char i;
- for(i=0;i<n;i++)
- delay1ms();
- }
- sbit fmq=P3^3;//蜂鳴器
- sbit k1=P2^4;//加
- sbit k2=P2^3;//減
- sbit k3=P2^2;//濕度上下限調(diào)節(jié)
- sbit k4=P2^1;//溫度上下限調(diào)節(jié)
- void delay500us()//500us基準延時
- {
- unsigned char j;
- for(j=0;j<57;j++);
- }
- void beep()//產(chǎn)生1KHZ頻率聲音
- {
- unsigned int t;
- for(t=0;t<1000;t++)
- {
- fmq=~fmq;
- delay500us();
- }
- fmq=1;
- delaynms(1000);
- }
- //對lcd1602操作
- sbit lcdrs = P2^5;//寄存器選擇位,將rs位定義為P2.5引腳
- sbit lcdrw = P2^6;//讀寫選擇位,將rw位定義為P2.6引腳
- sbit lcden = P2^7;//使能信號位,將e位定義為P2.7引腳
- sbit lcdBF = P0^7;//忙碌標志位,14號引腳
- bit BusyTest(void)//判斷1602忙碌狀態(tài),1忙碌,0不忙
- {
- bit result;
- lcdrs=0;//rs為低電平,rw為高電平時,可以讀狀態(tài)
- lcdrw=1;
- lcden=1;//e=1,才允許讀寫
- _nop_();//空操作
- _nop_();
- _nop_();
- _nop_();//空操作4個周期,給硬件反應時間
- result=lcdBF;//將忙碌標志位給result
- lcden=0;//將e恢復低電平
- return result;
- }
- void LcdWriteCommand(unsigned char dictate)//將顯示地址寫入1602
- {
- while(BusyTest()==1);//如果忙就等待
- lcdrs=0;
- lcdrw=0;//rs和rw同時為低電平,可以寫入指令
- lcden=0;//e給低電平,讓e從0到1發(fā)生正跳變,所以先置0
- _nop_();
- _nop_();
- P0=dictate;//將數(shù)據(jù)送入P0口,即寫入指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- lcden=1;//給高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- lcden=0;//當e由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令
- }
- void LcdWriteData(unsigned char y)//將數(shù)據(jù)寫入液晶模塊
- {
- while(BusyTest()==1);//如果忙就等待
- lcdrs=1;
- lcdrw=0;//rs和rw同時為低電平,可以寫入指令
- lcden=0;//e給低電平,讓e從0到1發(fā)生正跳變,所以先置0
- P0=y;//將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- lcden=1;//給高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- lcden=0;//當e由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令
- }
- void LcdInitiate(void)//對LCD的顯示模式進行初始化設置
- {
- delaynms(15);//延時15ms
- LcdWriteCommand(0x38);//顯示模式設置:16×2顯示,5×7點陣,8位數(shù)據(jù)接口
- delaynms(5);//延時5ms
- LcdWriteCommand(0x38);
- delaynms(5);//延時5ms
- LcdWriteCommand(0x38);//連續(xù)三次,確保初始化成功
- delaynms(5);
- LcdWriteCommand(0x08);//顯示關閉
- delaynms(5);
- LcdWriteCommand(0x0c);//顯示模式設置:顯示開,有光標,光標閃爍
- delaynms(5);
- LcdWriteCommand(0x06);//顯示模式設置:光標右移,字符不移
- delaynms(5);
- LcdWriteCommand(0x01);//清屏幕指令,將以前的顯示內(nèi)容清除
- delaynms(5);
- }
- void Disp1Char(unsigned char x,unsigned char y,unsigned char N)//在某個位置顯示一個字符。x-列坐標,y-行坐標,N-顯示的字符數(shù)據(jù)
- {
- if(y==0)
- {
- LcdWriteCommand(0x80 + x);//第一行顯示
- }
- else
- {
- LcdWriteCommand(0xC0 + x);//第二行顯示
- }
- LcdWriteData(N);
- }
- void DispNChar(uchar x,uchar y,uchar n,uchar *ptr)//讓液晶屏從某個位置連續(xù)顯示N個字符。n-字符個數(shù),ptr-指向字符存放位置的指針
- {
- uchar i;
- for(i=0;i<n;i++)
- {
- Disp1Char(x++,y,ptr[i]);
- if(x==0x0f)
- {
- x=0;
- y^=1;
- }
- }
- }
- void DispStr(uchar x,uchar y,uchar *ptr)//讓液晶從某個位置連續(xù)顯示一個字符串。ptr-指向字符串存放位置的指針
- {
- uchar *temp;
- uchar i,n=0;
- temp = ptr;
- while(*ptr++ != '\0')
- n++;//計算字符串有效字符的個數(shù)
- for(i=0;i<n;i++)
- {
- Disp1Char(x++,y,temp[i]);
- if(x==0x0f)
- {
- x=0;
- y^=1;
- }
- }
- }
- void Welcome()//歡迎界面
- {
- DispStr(0,0,"Welcome");
- DispStr(0,1,"WaiT");
- }
- void Disp_RH(ulongint f_data)//顯示最終結果RH
- {
- unsigned char lcd_table[3];
- ulongint aa;
- aa=f_data;
- lcd_table[0]=aa/100;//百位
- lcd_table[1]=aa%100/10;//十位
- lcd_table[2]=aa%100%10;//個位
- DispStr(0,0,"RH=");
- Disp1Char(3,0,(lcd_table[0]+0x30));
- Disp1Char(4,0,(lcd_table[1]+0x30));
- Disp1Char(5,0,(lcd_table[2]+0x30));//加上0x30以便直接得到相應ASCII碼去顯示
- Disp1Char(6,0,('%'));
- }
- void Disp_u(ulongint u_data,ulongint d_data)//顯示初始設定濕度數(shù)值
- {
- Disp1Char(5,1,(u_data/100+0x30));
- Disp1Char(6,1,(u_data%100/10+0x30));
- Disp1Char(7,1,(u_data%100%10+0x30));
- Disp1Char(8,1,(d_data%100/10+0x30));
- Disp1Char(9,1,(d_data%100%10+0x30));
- }
- void Disp_t(int u_data,int d_data)//顯示初始設定溫度數(shù)值
- {
- Disp1Char(11,1,(u_data%100/10+0x30));
- Disp1Char(12,1,(u_data%100%10+0x30));
- Disp1Char(14,1,(d_data%100/10+0x30));
- Disp1Char(15,1,(d_data%100%10+0x30));
- }
- void Disp_F(ulongint f_data)//顯示頻率
- {
- unsigned char lcd_table[4];
- ulongint aa;
- aa=f_data;
- lcd_table[0]=aa/1000;
- lcd_table[1]=aa%1000/100;
- lcd_table[2]=aa%100/10;
- lcd_table[3]=aa%10;
- DispStr(0,0,"F=");
- Disp1Char(2,0,(lcd_table[0]+0x30));
- Disp1Char(3,0,(lcd_table[1]+0x30));
- Disp1Char(4,0,(lcd_table[2]+0x30));
- Disp1Char(5,0,(lcd_table[3]+0x30));
- Disp1Char(6,0,('H'));
- Disp1Char(7,0,('Z'));
- }
- void Timer_Iint()//定時器T0,T1初始化
- {
- TMOD=0x51;//T1計數(shù),T0定時,方式1:16位計數(shù)
- TH0=(65536-50000)/256;//定時器T0的高8位賦初值
- TL0=(65536-50000)%256;//定時器T0的低8位賦初值
- TH1=0x00;//計數(shù)初值,0
- TL1=0x00;
- EA=1;//開總中斷
- ET0=1;//定時器T0終端允許
- ET1=1;//計數(shù)器T1中斷允許
- TR0=1;
- TR1=1;//開始計數(shù)
- }
- void RHTkey()
- {
- uchar k3n=0;
- uchar k4n=0;
- if(k3==0)
- {
- delaynms(10);
- if(k3==0)
- {
- while(!k3)
- k3n++;
- if(k3n==3)
- k3n=0;
- switch(k3n)
- {
- case 1:break;//按一下
- case 2:break;//按兩下
- case 0:break;//按三下返回
- }
- }
- }
- if(k4==0)
- {
- delaynms(10);
- if(k4==0)
- {
- while(!k4)
- k4n++;
- if(k4n==3)
- k4n=0;
- switch(k4n)
- {
- case 1:break;//按一下
- case 2:break;//按兩下
- case 0:break;//按三下
- }
- }
- }
- if(k3n!=0)//如果按k3,不按k4調(diào)節(jié)濕度上下限
- {
- if(k1==0)//加
- {
- delaynms(10);
- if(k1==0)
- {
- while(!k1);
- switch(k3n)
- {
- case 1:
- u++;
- if(u==100)/濕度/上線
- {
- u=99;
- }
- break;
- case 2:
- j++;
- if(j==u)//溫度下限
- {
- j=u-1;
- }
- break;
- }
- }
- Disp_u(u,j);
- }
- if(k2==0)//減
- {
- delaynms(10);
- if(k2==0)
- {
- while(!k2);
- switch(k3n)
- {
- case 1:
- u--;
- if(u==j)//濕度上線
- {
- u=j+1;
- }
- break;
- case 2:
- j--;
- if(j==0)//?
- {
- j=1;
- }
- break;
- }
- }
- Disp_u(u,j);
- }
-
- }
- if(k3n==0)//如果按k4,不按k3調(diào)節(jié)溫度上下限
- {
- if(k1==0)//加
- {
- delaynms(10);
- if(k1==0)
- {
- while(!k1);
- switch(k4n)
- {
- case 1:
- h++;
- if(h==50)//溫度上線
- {
- h=49;
- }
- if(h<0)
- Disp1Char(10,1,('-'));
- break;
- case 2:
- g++;
- if(g==h)//溫度下限
- {
- g=h-1;
- }
- if(g<0)
- Disp1Char(13,1,('-'));
- break;
- }
- }
- Disp_t(h,g);
- }
- if(k2==0)//減
- {
- delaynms(10);
- if(k2==0)
- {
- while(!k2);
- switch(k4n)
- {
- case 1:
- h--;
- if(h==g)//溫度上限
- {
- h=g+1;
- }
- if(h<0)
- Disp1Char(10,1,('-'));
- break;
- case 2:
- g--;
- if(g==-30)//溫度下限
- {
- g=-29;
- }
-
- if(g<0)
- Disp1Char(13,1,('-'));
- break;
- }
- }
- Disp_t(h,g);
- }
-
- }
- }
- void HS1101()//查表等差法F-RH轉(zhuǎn)換
- {
- //unsigned char i;//沒用可刪除
- if(flag==1)
- {
- flag=0;
- F=T1_count*65536+TH1*256+TL1;//存儲頻率值
- //LcdWriteCommand(0x01);//清屏幕指令
- //Disp_F(F);//不顯示可刪除
- if(F<=7351&&F>=6033)
- {
- if(F>7224)
- RH=((7351-F)/12.7);//去掉+0.5了
- else if(F>6600)
- RH=(10+(7224-F)/12.4);
- else if(F>6186)
- RH=(60+(6600-F)/13.8);
- else
- RH=(90+(6186-F)/15.3);
- }
- Disp_RH(RH);
- if(RH>u)
- {
- beep();
- DispStr(0,1,"RHh");
- delaynms(20);
- }
- if(RH<j)//當濕度大于30時,蜂鳴器響
- {
- beep();
- DispStr(0,1,"RHl");
- delaynms(20);
- }
- T0_count=0;
- TH0=(65536-50000)/256;//定時器T0的高8位賦初值
- TL0=(65536-50000)%256;//定時器T0的低8位賦初值
- T1_count=0;
- TH1=0x00;
- TL1=0x00;
- TR0=1;
- TR1=1;//開始計數(shù)
- }
- }
- void main()
- {
- Timer_Iint();//初始化
- LcdInitiate();
- Welcome();
- while(1)
- {
- Disp_u(u,j);//顯示濕度
- Disp_t(h,g);//顯示溫度
- HS1101();
- RHTkey();
- }
- }
- void Time1(void)interrupt 3//定時器2中斷。這是計數(shù)器1
- {
- TH1=0x00;
- TL1=0x00;//重裝初值,0
- T1_count++;
- }
- void Time0(void)interrupt 1//定時器1中斷,其后的0為定時器T0的中斷編號
- {
- TH0=(65536-50000)/256;//定時器T0的高8位賦初值
- TL0=(65536-50000)%256;//定時器T0的低8位賦初值
- T0_count++;
- if(T0_count==20)
- {
- flag=1;
- TR1=0;
- TR0=0;
- T0_count=0;
- }
- }
復制代碼
|
|