📄 chengxu.txt
字号:
//-------------------------------------------------------------------------------------
//函数声明,变量定义
//时间:2006年11月28日
//DS18B20好用程序 条件:11.0592晶振 TMDA 上拉4.7K电阻
//此程序已与2008.02.26完成
//-------------------------------------------------------------------------------------
#include <at89x52.h>
#include <stdio.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit TMDAT=P3^0; //18b20数据口
char up=35;
char down=10;
bit signx=0;
bit signy=0;
char dqz=10;
uint i,q,w;
#define LCM_RS P3_3 //定义引脚
#define LCM_RW P3_4
#define LCM_E P3_5
#define LCM_Data P2
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
Delay5Ms(); //延时
LCM_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
//P1口流水灯
void liushuideng(void)
{
P1=0X0FD;
for(i=0;i<=4;i++)
{P1=P1<<1;
Delay5Ms();
//break;
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
void Delay(void)
{
unsigned char TempCycA = 25;
unsigned int TempCycB;
while(TempCycA--)
{ TempCycB=8000;
while(TempCycB--);
};
}
/***************************************************************************************/
//-------------------------------------------------------------------------------------
//函数名称:dmsec
//入口参数:count
//函数功能:延时子程序
//-------------------------------------------------------------------------------------
void dmsec(uint count)
{
uint i;
while(count--)
{
for(i=0;i<125;i++){}
}
}
//-------------------------------------------------------------------------------------
//函数名称:tmreset
//入口参数:无
//函数功能:
//-------------------------------------------------------------------------------------
void tmreset(void)
{
uint i;
TMDAT=0;
i=103;while(i>0) i--; //大约900us
TMDAT=1;
i=4;while(i>0) i--;
}
//-------------------------------------------------------------------------------------
//函数名称:tmpre
//入口参数:无
//函数功能:等待DS18B20应答
//-------------------------------------------------------------------------------------
void tmpre(void)
{
uint i;
while(TMDAT);
while(~TMDAT);
i=4;while(i>0) i--;
}
//-------------------------------------------------------------------------------------
//函数名称:tmrbit
//入口参数:无
//返回值: dat
//函数功能:在总线上读一位
//-------------------------------------------------------------------------------------
bit tmrbit(void)
{
uint i;
bit dat;
TMDAT=0;i++;
TMDAT=1;i++;i++;
dat=TMDAT;
i=8;while(i>0) i--;
return(dat);
}
//-------------------------------------------------------------------------------------
//函数名称:tmrbyte
//入口参数:无
//返回值: dat
//函数功能:读一个字节
//-------------------------------------------------------------------------------------
uchar tmrbyte(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmrbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
//-------------------------------------------------------------------------------------
//函数名称:tmwbyte
//入口参数:dat
//函数功能:写命令
//-------------------------------------------------------------------------------------
void tmwbyte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
TMDAT=0; //写1
i++;i++;
TMDAT=1;
i=8;while(i>0) i--;
}
else
{
TMDAT=0; //写0
i=8;while(i>0) i--;
TMDAT=1;
i++;i++;
}
}
}
//-------------------------------------------------------------------------------------
//函数名称:tmstart
//入口参数:无
//函数功能:开始转换
//-------------------------------------------------------------------------------------
void tmstart(void)
{
tmreset();
tmpre();
dmsec(1);
tmwbyte(0xcc);
tmwbyte(0x44);
}
bit xiaoshudian=0;
//-------------------------------------------------------------------------------------
//函数名称:tmrbyte
//入口参数:无
//函数功能:读取温度值
//-------------------------------------------------------------------------------------
uchar tmrtemp(void)
{
uchar a,b,y1,y2,y3;
tmreset();
tmpre();
dmsec(1);
tmwbyte(0xcc);
tmwbyte(0xbe);
a=tmrbyte();
b=tmrbyte();
if( (a & 0x08)==0x08)
xiaoshudian=1;
else
xiaoshudian=0;
y1=a>>4;
y2=b<<4;
y3=y1|y2;
return(y3);
}
void delay_1ms(unsigned int i)
{
unsigned char he;
while(i--)
{
for(he=0;he<125;he++);
}
}
/********* 串口设置部分 *******/
uchar get_data=0;
/*******************************
函数名称:seriel_ino()
函数功能:串口初始化
具体设置:使用定时器T1,方式二,自动装载,
串口方式三,波特率9600;不倍频
参数使用:无
********************************/
void seriel_init()
{
TMOD=0x20; //定时器1方式二,自动装载
TH1=0XFD;
TL0=0XFD; //波特率9600
TR1=0; //发送的时候执1 ,开始启动定时器1
SCON=0X50; //方式1
//接受初始化
EA=1;
TR1=1;
ES=1;//允许接受中断
}
/*******************************
函数名称:send(uchar hh)
函数功能:串口发送
具体设置:
入口参数: 要发送的数据
参数使用:无
********************************/
void send(unsigned char one_shuju)
{
TR1=1; //打开定时器1,准备发送数据
SCON=0x40;//串口不允许接收,发送过程禁止中断
ES=0; //关串口中断
SBUF=one_shuju;
while(!TI)//等待发送完成
{}
TI=0;
SCON=0x50;//每次发送串口完成后就回到可以接收状态
ES=1; //开串口中断,允许接收中断
}
/*********-------------以上是串口发送和接收, 系统计时-----------------------********/
//参数设置
uchar last=0; //存储温度
/********************************************************************
函 数 名:bcd_8bit(unsigned char k)
功 能:当前时间,温度
说 明:
调 用:
调用参数:
返 回 值:无
设 计:loushaofeng 日 期:2008-02-26
修 改: 日 期:
**************************************************************/
void bcd_8bit(unsigned char last)
{
send((last/10)*16+last%10);
}
uchar kao=0;
/********************************************************************
函 数 名:chuankou_disp()
功 能:当前温度
说 明:
调 用:send_one(realy_time[i]);
***********************************************************************/
void chuankou_disp()
{
uchar gao=0,di=0;
//获取温度值
kao++;
tmstart();
last=tmrtemp();
if(kao>10)
{
if((last>up)||(last==up&&xiaoshudian==1))
P1_6=0;
else
P1_6=1;
if(last<down)
P1_7=0;
else
P1_7=1;
bcd_8bit(last);
gao=last/10;
di=last%10;
DisplayOneChar(3, 0, gao+'0');
DisplayOneChar(4, 0, di+'0');
if(xiaoshudian==1)
{
DisplayOneChar(5, 0, '.');
DisplayOneChar(6, 0, '5');
}
else
{
DisplayOneChar(5, 0, '.');
DisplayOneChar(6, 0, '0');
}
}
if(kao==200)
kao=20;
}
/*************************** 18b20+串口结束 ********************************************/
uchar xx=0;
uchar yy=0;
/****************** 键y盘部分 ********************/
void jianpan()
{
// begin:
if((!P0_0) | (!P0_1) | (!P0_2) | (!P0_3) | (!P0_4))
{
delay_1ms(20); //防止键盘抖动
if((!P0_0) | (!P0_1) | (!P0_2) | (!P0_3) | (!P0_4))
{
if(!P0_0)
{
xx=xx+1;
if(xx==1)
signx=1;
P1_0=0;
if(xx==2)
{ signx=0;
xx=0;
P1_0=1;
}
}
if(signx)
{
if(!P0_1)
{
up++;
P1_1=0;
if(up>125)
up=125;
DisplayOneChar(3, 1, (up/10)+'0');
DisplayOneChar(4, 1, (up%10)+'0');
}
P1_1=1;
if(!P0_2)
{
up--;
P1_2=0;
if(up<-55)
up=-55;
DisplayOneChar(3, 1, (up/10)+'0');
DisplayOneChar(4, 1, (up%10)+'0');
}
P1_2=1;
if(!P0_3)
{
down++;
P1_3=0;
if(down>125)
down=125;
DisplayOneChar(12, 1, (down/10)+'0');
DisplayOneChar(13, 1, (down%10)+'0');
}
P1_3=1;
if(!P0_4)
{
down--;
P1_4=0;
if(down<-55)
down=-55;
DisplayOneChar(12, 1, (down/10)+'0');
DisplayOneChar(13, 1, (down%10)+'0');
} P1_4=1;
}
//
if(!P0_4)
{//if(!P0_3)
yy=yy+1 ;
if(yy==1)
signy=1;
P1_4=0;
if(yy==2)
{signy=0;
yy=0;
P1_4=1;
}
}
if(signy)
{
if(!P0_3)
{dqz++;
P1_3=0;
DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
}P1_3=1;
if(!P0_2)
{dqz--;
P1_2=0;
DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
}P1_2=1;
if(!P0_1)
{
if(dqz>15)
{ for(q=0;q<12;q++)
{dqz--;
DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
liushuideng();
Delay5Ms();
}
P1=0X0FF;
}
if(dqz<5)
{ for(w=0;w<13;w++)
{ dqz++;
DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
liushuideng();
Delay5Ms();
}
} P1=0x0FF;
if(5<dqz<15)
{ DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
} P1_0=1;
} //goto begin;
}
}
}
}
/****************** 键盘部分END ********************/
/***************************************************************************************/
unsigned char code bysj_net[] = {"BIYESHEJI"};
unsigned char code chushihua_net[] = {"louyukongzhiqisj"};
unsigned char code wd_net[] = {"wd:"}; //从第三个开始显示温度值
unsigned char code sd_net[] = {"sd:"};
unsigned char code up_level[] = {"up:"};
unsigned char code down_level[] = {"down:"};
void main(void)
{
Delay400Ms(); //启动等待,等LCM讲入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻(可不要)
DisplayListChar(3,0,bysj_net);
DisplayListChar(0,1,chushihua_net);
Delay();
//WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
//LCMInit();
DisplayListChar(0, 0, wd_net);
DisplayListChar(9, 0, sd_net);
DisplayListChar(0, 1, up_level);
DisplayListChar(7, 1, down_level);
DisplayOneChar(3, 1, (up/10)+'0');
DisplayOneChar(4, 1, (up%10)+'0');
DisplayOneChar(12, 1, (down/10)+'0');
DisplayOneChar(13, 1, (down%10)+'0');
DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
DisplayOneChar(14, 0,'%' );
seriel_init();
while(1)
{
//串口显示
chuankou_disp();
jianpan();
delay_1ms(80);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -