func
站在用户的角度思考问题,与客户深入沟通,找到湛河网站设计与湛河网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:做网站、成都网站制作、企业官网、英文网站、手机端网站、网站推广、域名注册、网站空间、企业邮箱。业务覆盖湛河地区。
功能
双语对照
词典结果:
func
[英]['fʊŋk][美]['fʊŋk]
abbr.function 官能; 功能; 作用; 职责;
以上结果来自金山词霸
FUNC
[计] 函数,功能,操作;
网络释义
1. 作用
2. 功能
3. 函数
出错信息很清楚,你打开的文件格式不正确。
原因:xlrd升级到2.0.1版本以后,只支持.xls文件格式,不支持xlsx格式。
/****lcd1602显示温度(使用温度传感器18b20)*****/
#includereg52.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
/*********液晶屏相关参数**************/
#define data_port P1 //液晶屏指令、数据通信接口
sbit rs=P2^0; //液晶屏寄存器选择接口(rs=0时选择指令寄存器,rs=1时选择数据寄存器)
sbit rw=P2^1; //液晶屏读写选择接口(rw=0时选择写入,rw=1时选择读出)
sbit en=P2^2; //液晶屏使能接口(en=0时通信接口中断,en=1时通信接口接通)
uchar code line1_str[]={" Temperature "};//液晶屏第一行要显示的字符串
uchar code num_tab[]={"0123456789"};
/*********温度传感器18b20相关参数**********/
sbit DQ=P3^5; //温度传感器18b20的数据接口
/**********子函数声明部分************/
void T1_int(); //定时器T1初始化子函数声明
void in_command(uchar com); //向液晶屏输入命令子函数声明
void in_data(uchar dat); //向液晶屏输入数据子函数声明
void lcd_disp_string(uchar str[]); //液晶屏显示一串字符子函数声明
void lcd_int(); //液晶屏初始化子函数声明
void disp_temperature(uint temp);//lcd1602显示温度子函数声明
bit ds18b20_ret(); //温度传感器18b20复位子函数声明
void ds18b20_wr_com(uchar com); //向温度传感器18b20写入命令子函数声明
void rd_ram_command(); //发送命令子函数(读取18b20的RAM)
uint ds18b20_rd_data(); //读出温度传感器18b20寄存器的相关数据(主要是温度值)子函数声明
void temperature_convert(); //18b20温度转换子函数声明
void delayms(uint ms); //毫秒延时子函数声明
void delay_n10_us(uchar n); //微秒延时子函数声明
/************************************/
void main()
{
T1_int(); //定时器T1初始化
DQ=1; //释放温度传感器18b20的数据接口
temperature_convert(); //第一次调用18b20温度转换子函数消除85°C问题
lcd_int(); //液晶屏初始化(放在18b20温度转换子函数后边用来延时,跳过85°C)
while(1)
{
temperature_convert(); //调用18b20温度转换子函数
rd_ram_command(); //发送命令子函数(读取18b20的RAM)
disp_temperature(ds18b20_rd_data());//调用lcd1602显示温度子函数
}
}
/**********定时器T1初始化*************/
void T1_int()
{
TMOD=0x10; //0001 0000 T1工作在定时方式1
TH1=0; //T1设定初值
TL1=0;
TR1=0; //暂时关闭T1
}
/**********18b20温度转换子函数*************/
void temperature_convert()
{
while(ds18b20_ret()==0);//温度传感器18b20复位
ds18b20_wr_com(0xcc); //向温度传感器18b20写入"跳跃ROM命令"
ds18b20_wr_com(0x44); //向温度传感器18b20写入"温度转换命令"
delay_n10_us(50); //500us延时,等待转换完成
}
/**********发送命令子函数(读取18b20的RAM)***********/
void rd_ram_command()
{
while(ds18b20_ret()==0);
ds18b20_wr_com(0xcc); //向温度传感器18b20写入"跳跃ROM命令"
ds18b20_wr_com(0xbe); //向温度传感器18b20写入"读RAM命令"
}
/******读出18b20寄存器的相关数据(主要是温度值)子函数******/
uint ds18b20_rd_data()
{
uchar i;
uint temp_val;
for(i=0;i16;i++)
{
temp_val=1;
DQ=0;
_nop_();
DQ=1;
_nop_();
_nop_();
if(DQ==1)
{
temp_val|=0x8000;
}
delay_n10_us(7); //70us延时,确保读出
}
return(temp_val);
}
/******向温度传感器18b20写入命令子函数声明****/
void ds18b20_wr_com(uchar com)
{
uchar i;
for(i=0;i8;i++)
{
if((com0x01)==0)
{
DQ=0;
delay_n10_us(7); //70us延时,确保写入0
DQ=1;
_nop_();
}
else
{
DQ=0;
_nop_();
DQ=1;
delay_n10_us(7); //70us延时,确保写入1
}
com=1;
}
}
/**********温度传感器18b20复位子函数**********/
bit ds18b20_ret()
{
uint temp; //暂存脉冲时间
DQ=0; //启动复位脉冲
delay_n10_us(50); //500us延时(大于480us)
DQ=1; //停止复位脉冲
TR1=1; //启动T1
while(DQ==1 TH1*256+TL1=60);//等待18b20回应,等待时间不超过60us
if(DQ==0) //18b20回应
{
temp=TH1*256+TL1;
while(TH1*256+TL1-temp40); //等待60us再次检测回应脉冲是否存在
if(DQ==0) //18b20正常回应
{
while(TH1*256+TL1=480);//等待正常复位完成
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(1); //18b20有正常回应返回1
}
else
{
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(0); //18b20有正常回应返回0
}
}
else
{
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(0); //18b20没有回应返回0
}
}
/*********lcd1602显示温度子函数声明********/
void disp_temperature(uint temp)
{
uchar temp_h,temp_l,flag=0; //温度整数部分,小数部分(二进制)和最高位是否为'0'标志
uint temp_decimal=0; //存储温度值的小数部分(十进制)
in_command(0xc2); //设定第二行字符串起始显示位置
if(temp=0x8000)
{
in_data('-'); //显示'-'号
temp=~temp;
temp+=1;
}
else
{
in_data(' '); //'+'号不显示
}
temp_h=temp/16;
temp_l=temp%16;
if(temp_h/100!=0)
{
flag=1;
in_data(num_tab[temp_h/100]); //显示温度值的百位
}
else
{
in_data(' '); //百位为'0'则百位不显示
}
temp_h%=100;
if(temp_h/10!=0 || flag==1)
{
flag=1;
in_data(num_tab[temp_h/10]); //显示温度值的十位
}
else
{
in_data(' '); //百位,十位都为'0'则十位不显示
}
temp_h%=10;
in_data(num_tab[temp_h]); //显示温度值的个位
in_data('.'); //显示小数点
if(temp_l/8==1)
{temp_decimal+=5000;}
temp_l=temp_l%8;
if(temp_l/4==1)
{temp_decimal+=2500;}
temp_l=temp_l%4;
if(temp_l/2==1)
{temp_decimal+=1250;}
temp_l=temp_l%2;
if(temp_l==1)
{temp_decimal+=625;}
in_data(num_tab[temp_decimal/1000]);//显示温度值的十分位
in_data(' ');
in_data(223); //显示温度单位标志'摄氏度'
in_data('C');
}
/**********液晶屏初始化子函数**********/
void lcd_int()
{
/***************LCD初始设置*****************/
delayms(15); //延时15MS,等待LCD初始化
in_command(0x01); //清显示屏
in_command(0x38); //8位通信,2行显示,5*7点阵
in_command(0x0c); //开显示,关光标,关闪烁
in_command(0x06); //字符不动,光标右移动,地址加一
/************1602显示上电后电机默认的状态信息**************/
in_command(0x80); //设定第一行字符串起始显示位置
lcd_disp_string(line1_str); //显示数据(字符)
}
/**********液晶屏显示一串字符**********/
void lcd_disp_string(uchar str[])
{
uchar i=0;
while(str[i]!='\0')
{
in_data(str[i]); //显示数据(字符)
i++;
delayms(50); //延时
}
}
/********向液晶屏输入命令子函数************/
void in_command(uchar com)
{
delayms(2);
en=0;//关闭通信,为设置参数做准备
rs=0;//选择指令寄存器
rw=0;//写入液晶
_nop_();
data_port=com;
en=1;//开始通信
_nop_();
en=0;//关闭通信,为设置参数做准备
}
/********向液晶屏输入数据子函数************/
void in_data(uchar dat)
{
delayms(2);
en=0;//关闭通信,为设置参数做准备
rs=1;//选择数据寄存器
rw=0;//写入液晶
_nop_();
data_port=dat;
_nop_();
en=1;//开始通信
_nop_();
en=0;//关闭通信,为设置参数做准备
}
/********微秒延时子函数************/
void delay_n10_us(uchar n)
{
while(n--)
{
_nop_();
_nop_();
}
}
/********毫秒延时子函数************/
void delayms(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i124;i++);
}
}
//#include at89x51.h//用AT89C51时就用这个头文件
#include reg52.h//用华邦W78E58B时必须用这个头文件
sbit DQ = P3^7; //定义DQ引脚为P3.7
/***********ds18b20延迟子函数(晶振12MHz )*******/
/************DS18B20对时间要求很严,但只能长不能短
*************在11.0592M下也行,因为时间长些********/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i0;i--)
{
DQ = 0; // 给脉冲信号
dat=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i0; i--)
{
DQ = 0;
DQ = dat0x01;
delay_18B20(5);
DQ = 1;
dat=1;
}
}
/****************设置DS18B20工作状态*******************
TH和TL分别是上限报警和下限报警温度,RS是显示分辨率的设置
*******************************************************/
void setds18b20(unsigned char TH,unsigned char TL,unsigned char RS)
{
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x4E); // //写入"写暂存器"命令,修改TH和TL和分辩率配置寄存器
//先写TH,再写TL,最后写配置寄存器
WriteOneChar(TH); //写入想设定的温度报警上限
WriteOneChar(TL); //写入想设定的温度报警下限
WriteOneChar(RS); //写配置寄存器,格式为0 R1 R0 1,1 1 1 1
//R1R0=00分辨率娄9位,R1R0=11分辨率为12位
}
/**************读取ds18b20当前温度************/
unsigned char *ReadTemperature(void)
{ unsigned char tt[2];
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(70); // 温度转化要一段时间
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
//delay_18B20(70);
tt[0]=ReadOneChar(); //读取温度值低位
tt[1]=ReadOneChar(); //读取温度值高位
return(tt);
}
//#include at89x51.h//用AT89C51时就用这个头文件
#include reg52.h//用华邦W78E58B时必须用这个头文件
#include intrins.h//此函数为库函数,里面有_nop_函数,相当于汇编中的NOP
//Port Definitions**********************************************************
sbit LcdRs = P2^0;
sbit LcdRw = P2^1;
sbit LcdEn = P2^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
void LCD_Wait(void)
{
LcdRs=0; //RS=0表示选择指令寄存器
LcdRw=1; _nop_();//RW=1表示进行读操作
LcdEn=1; _nop_();//在EN为下降沿的时候锁存数据
while(DBPort0x80)
{
LcdEn=0;
_nop_();
_nop_();
LcdEn=1;
_nop_();
_nop_();
}
LcdEn=0;
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();//注意顺序
LcdEn=1; _nop_();//注意顺序
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}
//************************************************************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
void LCD_Print(unsigned char x, unsigned char y, unsigned char *str)
{
GotoXY(x,y);
Print(str);
}
#include reg52.h
//#include at89x52.h
//unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成相应的BCD码
// 0x66,0x6d,0x7d,0x07,
// 0x7f,0x6f,0x77,0x7c,
// 0x39,0x5e,0x79,0x71};
//unsigned char code KEY[]={0x00,0x00,0x01,0x02,0x03,//此处是为使程序通用,当键值不是按
// 0x04,0x05,0x06,0x07,//这个排列时,把此表更改即可
// 0x08,0x09,0x0a,0x0b,//最前面的那个0x00是为了查表方便,
// 0x0c,0x0d,0x0e,0x0f};//因为键值是从1开始的
sfr key_port=0x90; //定义P1口为键盘扫描口
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
bit key_ok=0; //有键按下的标志
/*************延时子程序*************
****调用一次用时18微秒,t每加1,用时增加6微秒*/
void delay(unsigned char t)
{
while(t--);
}
unsigned char r_left(unsigned char x)//循环左移一位
{
x=1;
x++;
return(x);
}
/*************粗判有无键按下**********
****有键按下则将key_ok置1************/
void scan_full(void)
{
unsigned char temp;
key_port=0xf0; //低半字节为行线,高半字节为列线
temp=P1;
if(temp!=0xf0)
key_ok=1;
else key_ok=0;
}
/************键盘扫描程序*************************
****功能:返回键值,当无键按下时,返回0*************/
unsigned char key_scan(void)
{
unsigned char temp,count=0x01,key_value;//按键返回值
unsigned char x_scan=0xfe,y_scan=0xef;//行、列扫描码
unsigned char i,j,y; //行数和列数
while(1)
{
scan_full(); //粗判是否有键按下
if(key_ok==1)
{
key_ok=0;
delay(200); //延时去抖动
scan_full(); //再次粗判是否有键按下
if(key_ok==1)
{
for(i=0;i4;i++) //扫描4行
{
key_port=x_scan;
for(j=0;j4;j++) //每行4列
{
temp=key_port;
temp=temp0xf0;
y=y_scan0xf0;
if(temp==y)
{
while(key_ok!=0)//等待按键松开
{
scan_full();
}
key_value=count;
return(key_value);//找到键值,马上返回
}
else
{
count++;
y_scan=r_left(y_scan);
}
}
y_scan=0xef; //扫描完一列,重新对列扫描量赋初值
x_scan=r_left(x_scan);//行扫描码左移一位,扫描下一行
}
}
}
return(key_value);//没键按下,返回0
}
}
//unsigned char key(void)
//{
// unsigned char x;
// unsigned char y;
// x=key_scan();
// return(x);
//y=KEY[x];
//return y;
//}
//#include at89x51.h//用AT89C51时就用这个头文件
#include reg52.h//用华邦W78E58B时必须用这个头文件
//#include absacc.h
//#include ctype.h
//#include math.h
//#include stdio.h
//#include string.h
#include DS18B20.h //测温头文件
#include LCD1602.h //液晶显示头文件
#include keyscan.h //键盘扫描头文件
sbit alarm=P2^6; //报警信号
//sbit DQ = P3^7; //定义DQ引脚为P3.7
unsigned char key_value; //存放键盘扫描值
bit up_one,down_one; //加1和减1标志
bit alarm_up_flag,alarm_down_flag; //上限报警和下限报警设置标志
bit set_temper_flag; //设置控制标志温度标志
bit alarm_switch; //报警开关
unsigned char user_temper; //用户标定温度
unsigned char TH=110,TL=-20,RS=0x3f; //上限温度110,下限-20,分辨率10位,也就是0.25C
unsigned char t[2],*pt; //用来存放温度值,测温程序就是通过这个数组与主函数通信的
unsigned char TempBuffer1[17]={0x2b,0x20,0x30,0x30,0x2e,0x30,0x30,0x20,
0x53,0x45,0x54,0x2b,0x20,0x30,0x30,0x43,'\0'};
//显示实时温度,上电时显示+ 00.00 SET+ 00C
unsigned char TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x20,0x30,0x30,0x20,
0x54,0x4c,0x3a,0x2b,0x20,0x30,0x30,0x43,'\0'};
//显示温度上下限,上电时显示TH:+ 00 TL:+ 00C
unsigned char code dotcode[4]={0,25,50,75};
/***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法*******
再将表值分离出十位和个位后送到十分位和百分位********************/
/***********用户设定温度转换为LCD显示数据**************
*功能:将用户设定温度user_temper,分离出符号位,百、十、个位
并将它们转化为ACSII码,送到液晶显示缓冲区
******************************************************/
void user_temper_LCD(unsigned char temper)
{
if(temper0x7f) //判断正负,如果为负温,将其转化为其绝对值
{
TempBuffer1[11]=0x2d; //0x2d为"-"的ASCII码
temper=~temper; //将负数的补码转换成绝对值
temper++;
}
else TempBuffer1[11]=0x2b; ////0x2B为"+"的ASCII码
TempBuffer1[12]=temper/100+0x30; //分离出temper的百十个位
if( TempBuffer1[12]==0x30) TempBuffer1[12]=0xfe; //百位数消隐
TempBuffer1[13]=(temper%100)/10+0x30; //分离出十位
TempBuffer1[14]=(temper%100)%10+0x30; //分离出个位
}
/***************温度上下限转换为LCD显示数据************
*功能:将上下限报警温度,分离出符号位,百、十、个位
并将它们转化为ACSII码,送到液晶显示缓冲区
******************************************************/
void alarm_LCD( unsigned char TH, unsigned char TL)
{
if(TH0x7F) //判断正负,如果为负温,将其转化为其绝对值
{
TempBuffer0[3]=0x2d; //0x2d为"-"的ASCII码
TH=~TH; //将负数的补码转换成绝对值
TH++;
}
else TempBuffer0[3]=0x2b; //0x2B为"+"的ASCII码
if(TL0x7f)
{
TempBuffer0[11]=0x2d; //0x2d为"-"的ASCII码
TL=~TL+1;
}
else TempBuffer0[11]=0x2b; //0x2B为"+"的ASCII码
TempBuffer0[4]=TH/100+0x30; //分离出TH的百十个位
if( TempBuffer0[4]==0x30) TempBuffer0[4]=0xfe; //百位数消隐
TempBuffer0[5]=(TH%100)/10+0x30; //分离出十位
TempBuffer0[6]=(TH%100)%10+0x30; //分离出个位
TempBuffer0[12]=TL/100+0x30; //分离出TL的百十个位
if( TempBuffer0[12]==0x30) TempBuffer0[12]=0xfe; //百位数消隐
TempBuffer0[13]=(TL%100)/10+0x30; //分离出十位
TempBuffer0[14]=(TL%100)%10+0x30; //分离出个位
}
/**********温度转换为LCD显示数据****************
*功能:将两个字节的温度值,分离出符号位,整数及小数
并将它们转化为ACSII码,送到液晶显示缓冲区
************************************************/
void temper_LCD(void)
{
unsigned char x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]0x07) //判断正负温度
{
TempBuffer1[0]=0x2d; //0x2d为"-"的ASCII码
t[1]=~t[1]; /*下面几句把负数的补码*/
t[0]=~t[0]; /* 换算成绝对值*********/
x=t[0]+1; /***********************/
t[0]=x; /***********************/
if(x255) /**********************/
t[1]++; /*********************/
}
else TempBuffer1[0]=0x2b; //0xfe为变"+"的ASCII码
t[1]=4; //将高字节左移4位
t[1]=t[1]0x70; //取出高字节的3个有效数字位
x=t[0]; //将t[0]暂存到X,因为取小数部分还要用到它
x=4; //右移4位
x=x0x0f; //和前面两句就是取出t[0]的高四位
t[1]=t[1]|x; //将高低字节的有效值的整数部分拼成一个字节
TempBuffer1[1]=t[1]/100+0x30; //+0x30 为变 0~9 ASCII码
if( TempBuffer1[1]==0x30) TempBuffer1[1]=0xfe; //百位数消隐
TempBuffer1[2]=(t[1]%100)/10+0x30; //分离出十位
TempBuffer1[3]=(t[1]%100)%10+0x30; //分离出个位
t[0]=t[0]0x0c; //取有效的两位小数
t[0]=2; //左移两位,以便查表
x=t[0];
y=dotcode[x]; //查表换算成实际的小数
TempBuffer1[5]=y/10+0x30; //分离出十分位
TempBuffer1[6]=y%10+0x30; //分离出百分位
}
/*********键盘命令处理函数************
*功能:把键盘值转化成相应的功能标志位
*备注:为了提高程序的健壮性,在功能标志位无效时,
**up_one和down_one都无效,并且各功能标志之间
**采用互锁处理,虽然这样麻烦,特别是功能标志较多时
**更是麻烦,但各功能标志之间是同级别的;
**也可采用多重if else方法,虽然简单,
**但各功能标志之间有了明显的优先级差别
**************************************/
void key_command(unsigned char x)
{
switch(x)
{
case 1: up_one=1;break;
case 2: down_one=1;break;
case 5: alarm_up_flag=!alarm_up_flag;break;
case 6: alarm_down_flag=!alarm_down_flag;break;
case 7: set_temper_flag=!set_temper_flag;break;
case 8: alarm_switch=!alarm_switch;break;
default: break;
}
if(!(alarm_up_flag||alarm_down_flag||set_temper_flag))
{
up_one=0x00; //在没有相应功能标志有效时
down_one=0x00; //up_one和down_one都被锁定
}
if(alarm_up_flag(!alarm_down_flag)(!set_temper_flag))//设置上限报警
{
if(up_one)//上限报警加1
{
TH++;up_one=0;
if(TH=100)//超过100度,回零到20度
TH=20;
}
if(down_one)//上限报警减1
{
TH--;down_one=0;
if(TH=20)//小于20度,回零到20度
TH=20;
}
}
if((!alarm_up_flag)(alarm_down_flag)(!set_temper_flag))//设置下限报警
{
if(up_one)
{
TL++;up_one=0;
if(TL=20)//高于20度,回零到0度
TL=0;
}
if(down_one)
{
TL--;down_one=0;
if(TL=0)//低于0度,回零到0度
TL=0;
}
}
if((!alarm_up_flag)(!alarm_down_flag)(set_temper_flag))//设置用户标定温度
{
if(up_one)
{
user_temper++;up_one=0;
if(user_temper=60)//高于60度,回零到0度
user_temper=0;
}
if(down_one)
{
user_temper--;down_one=0;
if(user_temper=0)//低于0度,回零到0度
user_temper=0;
}
}
//if(alarm_switch)
}
main()
{
setds18b20(TH,TL,RS); //设置上下限报警温度和分辨率
delay(100);
while(1)
{
pt=ReadTemperature(); //测温函数返回这个数组的头地址
//读取温度,温度值存放在一个两个字节的数组中,
temper_LCD(); //实测温度转化为ACSII码,并送液晶显示缓冲区
user_temper_LCD(user_temper); //用户设定温度转化为ACSII码,并送液晶显示缓冲区
alarm_LCD(TH,TL); //上下限报警温度转化为ASCII码,并送液晶显示缓冲区
LCD_Initial(); //第一个参数列号,第二个为行号,为0表示第一行
//为1表示第二行,第三个参数为显示数据的首地址
LCD_Print(0,0,TempBuffer0);
LCD_Print(0,1,TempBuffer1);
scan_full(); //看有无键按下
if(key_ok) //如有键按下则看到底哪个键按下
{
key_value=key_scan(); //调用键盘扫描程序
key_command(key_value); //键盘命令处理函数
}
}
}
觉得能运行,我试过了,自己看图
华氏度
华氏度(Fahrenheit scale)是指用来计量温度的单位。符号℉。华氏度 = 32°F(华氏温标单位)+ 摄氏度× 1.8。
世界上仅有5个国家使用华氏度,包括巴哈马、伯利兹、英属开曼群岛、帕劳、美利坚合众国及其他附属领土(波多黎各、关岛、美属维京群岛)。
中文名
华氏度
外文名
Fahrenheit scale
别名
华氏温标
提出者
华伦海特
提出时间
1724年
快速
导航
换算
起源
华氏度(°F)是温度的一种度量单位,以其发明者德国人华伦海特(Gabriel D. Fahrenheit,1686—1736)命名的。1724年他发现液体金属水银比酒精更适宜制造温度计,以水银为测温介质,发明了玻璃水银温度计,选取氯化铵和冰水的混合物的冰点温度为温度计的零度,人体温度为温度计的100度。在标准大气压下,冰的熔点为32℉,水的沸点为212℉,中间有180等分,每等分为华氏1度,记作“1℉”。
“华氏温标”是经验温标之一。在美国的日常生活中,多采用这种温标,用字母“℉”表示。
换算
摄氏温标(°C)和华氏温标(°F)之间的换算关系为:
F=C×1.8+32
C=(F-32)÷1.8
例如:
0℃=(0×1.8+32)℉=32℉
1 华氏度°F = -17.222222222222 摄氏度°C
1 华氏度°F = 1 华氏度°F
1 华氏度°F = 255.92777777778 开氏度K
1 华氏度°F = 460.67 兰氏度°Ra
1 华氏度°F = -13.777777777778 列氏
二.系统软件设计
图4 系统程序流程图
2.1 系统程序流程图
系统程序流程图如图4所示。
2.2 温度部分软件设计
DS18B20的一线工作协议流程是:初始化→ROM操作指令→存储器操作指令→数据传输。其工作时序包括初始化时序、写时序和读时序。故主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。程序主要函数部分如下:
(1)初始化函数
//读一个字节函数
ReadOneChar(void)
{unsigned char i=0;
unsigned char dat = 0;
for (i=8;i0;i--)
{ DQ = 0; // 给脉冲信号
dat=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(4);}
return(dat);}
//写一个字节函数
WriteOneChar(unsigned char dat)
{unsigned char i=0;
for (i=8; i0; i--)
{DQ = 0;
DQ = dat0x01;
delay(5);
DQ = 1;
dat=1;}}
(2)读取温度并计算函数
ReadTemperature(void)
{unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍输出并四舍五入---此行没用
(3)主程序部分见前
return(t);}
三. 结束语
AT89C2051单片机体积小、重量轻、抗干扰能力强、对环境要求不高、价格低廉、可靠性高、灵活性好。即使是非电子计算机专业人员,通过学习一些专业基础知识以后也能依靠自己的技术力量来开发所希望的单片机应用系统。本文的温度控制系统只是单片机广泛应用于各行各业中的一例,相信读者会依靠自己的聪明才智使单片机的应用更加广泛化。另外对本例子可以作一些扩展,单片机的应用越来越广泛,由于单片机的运算功能较差,往往需要借助计算机系统,因此单片机和PC机进行远程通信更具有实际意义。目前此设计已成功应用于钻井模拟器实验室室温控制。
本文作者创新观点:采用的单片机AT89C2051性价比高,而且温度传感器DS18B20转化温度的方法非常简洁且精度高、测试范围较广。
参考文献
[1]林伸茂.8051单片机彻底研究基础篇 北京:人民邮电出版社 2004
[2]范风强等.单片机语言C51应用实战集锦 北京:电子工业出版社 2005
[3]谭浩强.C语言程序设计(第二版) 北京:清华大学出版社 1999
[4]夏路易等.电路原理图与电路板设计教程 北京:北京希望电子出版社 2002
[5]赵晶.Protel99高级应用 北京:人民邮电出版社 2000
[6]聂毅.单片机定时器中断时间误差的分析及补偿[J] 微计算机信息 2002,18(4):37~38