这是完整代码,帮我看看RHTke'y那部分,主程序我按下去1602显示屏数值不会改变,是为什么,那里错了?
这个没有程序错误,我觉得是逻辑写错了,搞不来,能仔细帮我看看吗?
#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;//湿度上下限调节
sbit k4=P2^1;//温度上下限调节
void delay500us()//500us基准延时
{
unsigned char j;
for(j=0;j<57;j++);
}
void beep()//产生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忙碌状态,1忙碌,0不忙
{
bit result;
lcdrs=0;//rs为低电平,rw为高电平时,可以读状态
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发生正跳变,所以先置0
_nop_();
_nop_();
P0=dictate;//将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
lcden=1;//给高电平
_nop_();
_nop_();
_nop_();
_nop_();
lcden=0;//当e由高电平跳变成低电平时,液晶模块开始执行命令
}
void LcdWriteData(unsigned char y)//将数据写入液晶模块
{
while(BusyTest()==1);//如果忙就等待
lcdrs=1;
lcdrw=0;//rs和rw同时为低电平,可以写入指令
lcden=0;//e给低电平,让e从0到1发生正跳变,所以先置0
P0=y;//将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();
lcden=1;//给高电平
_nop_();
_nop_();
_nop_();
_nop_();
lcden=0;//当e由高电平跳变成低电平时,液晶模块开始执行命令
}
void LcdInitiate(void)//对LCD的显示模式进行初始化设置
{
delaynms(15);//延时15ms
LcdWriteCommand(0x38);//显示模式设置:16×2显示,5×7点阵,8位数据接口
delaynms(5);//延时5ms
LcdWriteCommand(0x38);
delaynms(5);//延时5ms
LcdWriteCommand(0x38);//连续三次,确保初始化成功
delaynms(5);
LcdWriteCommand(0x08);//显示关闭
delaynms(5);
LcdWriteCommand(0x0c);//显示模式设置:显示开,有光标,光标闪烁
delaynms(5);
LcdWriteCommand(0x06);//显示模式设置:光标右移,字符不移
delaynms(5);
LcdWriteCommand(0x01);//清屏幕指令,将以前的显示内容清除
delaynms(5);
}
void Disp1Char(unsigned char x,unsigned char y,unsigned char N)//在某个位置显示一个字符。x-列坐标,y-行坐标,N-显示的字符数据
{
if(y==0)
{
LcdWriteCommand(0x80 + x);//第一行显示
}
else
{
LcdWriteCommand(0xC0 + x);//第二行显示
}
LcdWriteData(N);
}
void DispNChar(uchar x,uchar y,uchar n,uchar *ptr)//让液晶屏从某个位置连续显示N个字符。n-字符个数,ptr-指向字符存放位置的指针
{
uchar i;
for(i=0;i<n;i++)
{
Disp1Char(x++,y,ptr);
if(x==0x0f)
{
x=0;
y^=1;
}
}
}
void DispStr(uchar x,uchar y,uchar *ptr)//让液晶从某个位置连续显示一个字符串。ptr-指向字符串存放位置的指针
{
uchar *temp;
uchar i,n=0;
temp = ptr;
while(*ptr++ != '\0')
n++;//计算字符串有效字符的个数
for(i=0;i<n;i++)
{
Disp1Char(x++,y,temp);
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)//显示初始设定湿度数值
{
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)//显示初始设定温度数值
{
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计数,T0定时,方式1:16位计数
TH0=(65536-50000)/256;//定时器T0的高8位赋初值
TL0=(65536-50000)%256;//定时器T0的低8位赋初值
TH1=0x00;//计数初值,0
TL1=0x00;
EA=1;//开总中断
ET0=1;//定时器T0终端允许
ET1=1;//计数器T1中断允许
TR0=1;
TR1=1;//开始计数
}
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调节湿度上下限
{
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调节温度上下限
{
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转换
{
//unsigned char i;//没用可删除
if(flag==1)
{
flag=0;
F=T1_count*65536+TH1*256+TL1;//存储频率值
//LcdWriteCommand(0x01);//清屏幕指令
//Disp_F(F);//不显示可删除
/*for(i=0;i<=10;i++)//查表法
{
if(F<=tab[1]&&F>tab[1][i+1])
{
RH=tab[0]+(tab[1]-F)/((tab[0][i+1]-tab[0])/10);
break;
}
}*/
/*if(F>=6033&&F<=7351)
{
if(F>6033)
RH=(588-0.08*F)+0.5;
else
RH=(586-0.08*F)+0.5;
}*/
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;//开始计数
}
}
void main()
{
Timer_Iint();//初始化
LcdInitiate();
Welcome();
while(1)
{
Disp_u(u,j);//显示湿度
Disp_t(h,g);//显示温度
HS1101();
RHTkey();
}
}
void Time1(void)interrupt 3//定时器2中断。这是计数器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;
}
}
|