func
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到湛河網(wǎng)站設(shè)計(jì)與湛河網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋湛河地區(qū)。
功能
雙語(yǔ)對(duì)照
詞典結(jié)果:
func
[英]['f??k][美]['f??k]
abbr.function 官能; 功能; 作用; 職責(zé);
以上結(jié)果來(lái)自金山詞霸
FUNC
[計(jì)] 函數(shù),功能,操作;
網(wǎng)絡(luò)釋義
1. 作用
2. 功能
3. 函數(shù)
出錯(cuò)信息很清楚,你打開(kāi)的文件格式不正確。
原因:xlrd升級(jí)到2.0.1版本以后,只支持.xls文件格式,不支持xlsx格式。
/****lcd1602顯示溫度(使用溫度傳感器18b20)*****/
#includereg52.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
/*********液晶屏相關(guān)參數(shù)**************/
#define data_port P1 //液晶屏指令、數(shù)據(jù)通信接口
sbit rs=P2^0; //液晶屏寄存器選擇接口(rs=0時(shí)選擇指令寄存器,rs=1時(shí)選擇數(shù)據(jù)寄存器)
sbit rw=P2^1; //液晶屏讀寫(xiě)選擇接口(rw=0時(shí)選擇寫(xiě)入,rw=1時(shí)選擇讀出)
sbit en=P2^2; //液晶屏使能接口(en=0時(shí)通信接口中斷,en=1時(shí)通信接口接通)
uchar code line1_str[]={" Temperature "};//液晶屏第一行要顯示的字符串
uchar code num_tab[]={"0123456789"};
/*********溫度傳感器18b20相關(guān)參數(shù)**********/
sbit DQ=P3^5; //溫度傳感器18b20的數(shù)據(jù)接口
/**********子函數(shù)聲明部分************/
void T1_int(); //定時(shí)器T1初始化子函數(shù)聲明
void in_command(uchar com); //向液晶屏輸入命令子函數(shù)聲明
void in_data(uchar dat); //向液晶屏輸入數(shù)據(jù)子函數(shù)聲明
void lcd_disp_string(uchar str[]); //液晶屏顯示一串字符子函數(shù)聲明
void lcd_int(); //液晶屏初始化子函數(shù)聲明
void disp_temperature(uint temp);//lcd1602顯示溫度子函數(shù)聲明
bit ds18b20_ret(); //溫度傳感器18b20復(fù)位子函數(shù)聲明
void ds18b20_wr_com(uchar com); //向溫度傳感器18b20寫(xiě)入命令子函數(shù)聲明
void rd_ram_command(); //發(fā)送命令子函數(shù)(讀取18b20的RAM)
uint ds18b20_rd_data(); //讀出溫度傳感器18b20寄存器的相關(guān)數(shù)據(jù)(主要是溫度值)子函數(shù)聲明
void temperature_convert(); //18b20溫度轉(zhuǎn)換子函數(shù)聲明
void delayms(uint ms); //毫秒延時(shí)子函數(shù)聲明
void delay_n10_us(uchar n); //微秒延時(shí)子函數(shù)聲明
/************************************/
void main()
{
T1_int(); //定時(shí)器T1初始化
DQ=1; //釋放溫度傳感器18b20的數(shù)據(jù)接口
temperature_convert(); //第一次調(diào)用18b20溫度轉(zhuǎn)換子函數(shù)消除85°C問(wèn)題
lcd_int(); //液晶屏初始化(放在18b20溫度轉(zhuǎn)換子函數(shù)后邊用來(lái)延時(shí),跳過(guò)85°C)
while(1)
{
temperature_convert(); //調(diào)用18b20溫度轉(zhuǎn)換子函數(shù)
rd_ram_command(); //發(fā)送命令子函數(shù)(讀取18b20的RAM)
disp_temperature(ds18b20_rd_data());//調(diào)用lcd1602顯示溫度子函數(shù)
}
}
/**********定時(shí)器T1初始化*************/
void T1_int()
{
TMOD=0x10; //0001 0000 T1工作在定時(shí)方式1
TH1=0; //T1設(shè)定初值
TL1=0;
TR1=0; //暫時(shí)關(guān)閉T1
}
/**********18b20溫度轉(zhuǎn)換子函數(shù)*************/
void temperature_convert()
{
while(ds18b20_ret()==0);//溫度傳感器18b20復(fù)位
ds18b20_wr_com(0xcc); //向溫度傳感器18b20寫(xiě)入"跳躍ROM命令"
ds18b20_wr_com(0x44); //向溫度傳感器18b20寫(xiě)入"溫度轉(zhuǎn)換命令"
delay_n10_us(50); //500us延時(shí),等待轉(zhuǎn)換完成
}
/**********發(fā)送命令子函數(shù)(讀取18b20的RAM)***********/
void rd_ram_command()
{
while(ds18b20_ret()==0);
ds18b20_wr_com(0xcc); //向溫度傳感器18b20寫(xiě)入"跳躍ROM命令"
ds18b20_wr_com(0xbe); //向溫度傳感器18b20寫(xiě)入"讀RAM命令"
}
/******讀出18b20寄存器的相關(guān)數(shù)據(jù)(主要是溫度值)子函數(shù)******/
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延時(shí),確保讀出
}
return(temp_val);
}
/******向溫度傳感器18b20寫(xiě)入命令子函數(shù)聲明****/
void ds18b20_wr_com(uchar com)
{
uchar i;
for(i=0;i8;i++)
{
if((com0x01)==0)
{
DQ=0;
delay_n10_us(7); //70us延時(shí),確保寫(xiě)入0
DQ=1;
_nop_();
}
else
{
DQ=0;
_nop_();
DQ=1;
delay_n10_us(7); //70us延時(shí),確保寫(xiě)入1
}
com=1;
}
}
/**********溫度傳感器18b20復(fù)位子函數(shù)**********/
bit ds18b20_ret()
{
uint temp; //暫存脈沖時(shí)間
DQ=0; //啟動(dòng)復(fù)位脈沖
delay_n10_us(50); //500us延時(shí)(大于480us)
DQ=1; //停止復(fù)位脈沖
TR1=1; //啟動(dòng)T1
while(DQ==1 TH1*256+TL1=60);//等待18b20回應(yīng),等待時(shí)間不超過(guò)60us
if(DQ==0) //18b20回應(yīng)
{
temp=TH1*256+TL1;
while(TH1*256+TL1-temp40); //等待60us再次檢測(cè)回應(yīng)脈沖是否存在
if(DQ==0) //18b20正常回應(yīng)
{
while(TH1*256+TL1=480);//等待正常復(fù)位完成
TR1=0; //關(guān)閉T1
TH1=0; //計(jì)時(shí)歸零
TL1=0;
return(1); //18b20有正?;貞?yīng)返回1
}
else
{
TR1=0; //關(guān)閉T1
TH1=0; //計(jì)時(shí)歸零
TL1=0;
return(0); //18b20有正常回應(yīng)返回0
}
}
else
{
TR1=0; //關(guān)閉T1
TH1=0; //計(jì)時(shí)歸零
TL1=0;
return(0); //18b20沒(méi)有回應(yīng)返回0
}
}
/*********lcd1602顯示溫度子函數(shù)聲明********/
void disp_temperature(uint temp)
{
uchar temp_h,temp_l,flag=0; //溫度整數(shù)部分,小數(shù)部分(二進(jìn)制)和最高位是否為'0'標(biāo)志
uint temp_decimal=0; //存儲(chǔ)溫度值的小數(shù)部分(十進(jìn)制)
in_command(0xc2); //設(shè)定第二行字符串起始顯示位置
if(temp=0x8000)
{
in_data('-'); //顯示'-'號(hào)
temp=~temp;
temp+=1;
}
else
{
in_data(' '); //'+'號(hào)不顯示
}
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]); //顯示溫度值的個(gè)位
in_data('.'); //顯示小數(shù)點(diǎn)
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); //顯示溫度單位標(biāo)志'攝氏度'
in_data('C');
}
/**********液晶屏初始化子函數(shù)**********/
void lcd_int()
{
/***************LCD初始設(shè)置*****************/
delayms(15); //延時(shí)15MS,等待LCD初始化
in_command(0x01); //清顯示屏
in_command(0x38); //8位通信,2行顯示,5*7點(diǎn)陣
in_command(0x0c); //開(kāi)顯示,關(guān)光標(biāo),關(guān)閃爍
in_command(0x06); //字符不動(dòng),光標(biāo)右移動(dòng),地址加一
/************1602顯示上電后電機(jī)默認(rèn)的狀態(tài)信息**************/
in_command(0x80); //設(shè)定第一行字符串起始顯示位置
lcd_disp_string(line1_str); //顯示數(shù)據(jù)(字符)
}
/**********液晶屏顯示一串字符**********/
void lcd_disp_string(uchar str[])
{
uchar i=0;
while(str[i]!='\0')
{
in_data(str[i]); //顯示數(shù)據(jù)(字符)
i++;
delayms(50); //延時(shí)
}
}
/********向液晶屏輸入命令子函數(shù)************/
void in_command(uchar com)
{
delayms(2);
en=0;//關(guān)閉通信,為設(shè)置參數(shù)做準(zhǔn)備
rs=0;//選擇指令寄存器
rw=0;//寫(xiě)入液晶
_nop_();
data_port=com;
en=1;//開(kāi)始通信
_nop_();
en=0;//關(guān)閉通信,為設(shè)置參數(shù)做準(zhǔn)備
}
/********向液晶屏輸入數(shù)據(jù)子函數(shù)************/
void in_data(uchar dat)
{
delayms(2);
en=0;//關(guān)閉通信,為設(shè)置參數(shù)做準(zhǔn)備
rs=1;//選擇數(shù)據(jù)寄存器
rw=0;//寫(xiě)入液晶
_nop_();
data_port=dat;
_nop_();
en=1;//開(kāi)始通信
_nop_();
en=0;//關(guān)閉通信,為設(shè)置參數(shù)做準(zhǔn)備
}
/********微秒延時(shí)子函數(shù)************/
void delay_n10_us(uchar n)
{
while(n--)
{
_nop_();
_nop_();
}
}
/********毫秒延時(shí)子函數(shù)************/
void delayms(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i124;i++);
}
}
//#include?at89x51.h//用AT89C51時(shí)就用這個(gè)頭文件
#include?reg52.h//用華邦W78E58B時(shí)必須用這個(gè)頭文件
sbit?DQ?=?P3^7; //定義DQ引腳為P3.7
/***********ds18b20延遲子函數(shù)(晶振12MHz?)*******/
/************DS18B20對(duì)時(shí)間要求很嚴(yán),但只能長(zhǎng)不能短
*************在11.0592M下也行,因?yàn)闀r(shí)間長(zhǎng)些********/
void?delay_18B20(unsigned?int?i)
{
while(i--);
}
/**********ds18b20初始化函數(shù)**********************/
void?Init_DS18B20(void)
{
?unsigned?char?x=0;
?DQ?=?0;??????????//單片機(jī)將DQ拉低
?delay_18B20(80);?//精確延時(shí)?大于?480us
?DQ?=?1;??????????//拉高總線
?delay_18B20(14);
?x=DQ;????????????//稍做延時(shí)后?如果x=0則初始化成功?x=1則初始化失敗
?delay_18B20(20);
}
/***********ds18b20讀一個(gè)字節(jié)**************/
unsigned?char?ReadOneChar(void)
{
unsigned?char?i=0;
unsigned?char?dat?=?0;
for?(i=8;i0;i--)
?{
??DQ?=?0;?//?給脈沖信號(hào)
??dat=1;
??DQ?=?1;?//?給脈沖信號(hào)
??if(DQ)
??dat|=0x80;
??delay_18B20(4);
?}
return(dat);
}
/*************ds18b20寫(xiě)一個(gè)字節(jié)****************/
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;
}
}
/****************設(shè)置DS18B20工作狀態(tài)*******************
TH和TL分別是上限報(bào)警和下限報(bào)警溫度,RS是顯示分辨率的設(shè)置
*******************************************************/
void?setds18b20(unsigned?char?TH,unsigned?char?TL,unsigned?char?RS)
{
Init_DS18B20();
WriteOneChar(0xCC);???? //?跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0x4E);? //?//寫(xiě)入"寫(xiě)暫存器"命令,修改TH和TL和分辯率配置寄存器
//先寫(xiě)TH,再寫(xiě)TL,最后寫(xiě)配置寄存器
WriteOneChar(TH); //寫(xiě)入想設(shè)定的溫度報(bào)警上限
WriteOneChar(TL); //寫(xiě)入想設(shè)定的溫度報(bào)警下限
WriteOneChar(RS); //寫(xiě)配置寄存器,格式為0?R1?R0?1,1?1?1?1
//R1R0=00分辨率婁9位,R1R0=11分辨率為12位
}
/**************讀取ds18b20當(dāng)前溫度************/
unsigned?char?*ReadTemperature(void)
{ unsigned?char?tt[2];
Init_DS18B20();
WriteOneChar(0xCC);???? //?跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0x44);? //?啟動(dòng)溫度轉(zhuǎn)換
delay_18B20(70);???????//?溫度轉(zhuǎn)化要一段時(shí)間
Init_DS18B20();
WriteOneChar(0xCC);? //跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0xBE);? //讀取溫度寄存器等(共可讀9個(gè)寄存器)?前兩個(gè)就是溫度
//delay_18B20(70);
tt[0]=ReadOneChar();???? //讀取溫度值低位
tt[1]=ReadOneChar();??? //讀取溫度值高位
return(tt);
}
//#include?at89x51.h//用AT89C51時(shí)就用這個(gè)頭文件
#include?reg52.h//用華邦W78E58B時(shí)必須用這個(gè)頭文件
#include?intrins.h//此函數(shù)為庫(kù)函數(shù),里面有_nop_函數(shù),相當(dāng)于匯編中的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.數(shù)據(jù)端口
//內(nèi)部等待函數(shù)**************************************************************************
void?LCD_Wait(void)
{
LcdRs=0; //RS=0表示選擇指令寄存器
LcdRw=1; _nop_();//RW=1表示進(jìn)行讀操作
LcdEn=1; _nop_();//在EN為下降沿的時(shí)候鎖存數(shù)據(jù)
while(DBPort0x80)
{
LcdEn=0;
_nop_();
_nop_();
LcdEn=1;
_nop_();
_nop_();
}
LcdEn=0;
}
//向LCD寫(xiě)入命令或數(shù)據(jù)************************************************************
#define?LCD_COMMAND 0??????//?Command
#define?LCD_DATA 1??????//?Data
#define?LCD_CLEAR_SCREEN 0x01??????//?清屏
#define?LCD_HOMING?? 0x02??????//?光標(biāo)返回原點(diǎn)
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();
}
//設(shè)置顯示模式************************************************************
#define?LCD_SHOW 0x04????//顯示開(kāi)
#define?LCD_HIDE 0x00????//顯示關(guān)
#define?LCD_CURSOR 0x02? //顯示光標(biāo)
#define?LCD_NO_CURSOR 0x00????//無(wú)光標(biāo)
#define?LCD_FLASH 0x01????//光標(biāo)閃動(dòng)
#define?LCD_NO_FLASH 0x00????//光標(biāo)不閃動(dòng)
void?LCD_SetDisplay(unsigned?char?DisplayMode)
{
LCD_Write(LCD_COMMAND,?0x08|DisplayMode);
}
//設(shè)置輸入模式************************************************************
#define?LCD_AC_UP 0x02
#define?LCD_AC_DOWN 0x00??????//?default
#define?LCD_MOVE 0x01??????//?畫(huà)面可平移
#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位數(shù)據(jù)端口,2行顯示,5*7點(diǎn)陣
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);????//開(kāi)啟顯示,?無(wú)光標(biāo)
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);???//清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);???????//AC遞增,?畫(huà)面不動(dòng)
}
//************************************************************************
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轉(zhuǎn)換成相應(yīng)的BCD碼
//??????????????????????????0x66,0x6d,0x7d,0x07,
//??????????????????????????0x7f,0x6f,0x77,0x7c,
//??????????????????????????0x39,0x5e,0x79,0x71};
//unsigned?char?code?KEY[]={0x00,0x00,0x01,0x02,0x03,//此處是為使程序通用,當(dāng)鍵值不是按
// ?? ???0x04,0x05,0x06,0x07,//這個(gè)排列時(shí),把此表更改即可
// ???0x08,0x09,0x0a,0x0b,//最前面的那個(gè)0x00是為了查表方便,
// ???0x0c,0x0d,0x0e,0x0f};//因?yàn)殒I值是從1開(kāi)始的
sfr?key_port=0x90; ????//定義P1口為鍵盤(pán)掃描口
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.數(shù)據(jù)端口
bit?key_ok=0;??????? //有鍵按下的標(biāo)志
/*************延時(shí)子程序*************
****調(diào)用一次用時(shí)18微秒,t每加1,用時(shí)增加6微秒*/
void?delay(unsigned?char?t)
{
while(t--);
}
unsigned?char?r_left(unsigned?char?x)//循環(huán)左移一位
{
x=1;
x++;
return(x);
}
/*************粗判有無(wú)鍵按下**********
****有鍵按下則將key_ok置1************/
void?scan_full(void)
{
unsigned?char?temp;
key_port=0xf0;? //低半字節(jié)為行線,高半字節(jié)為列線
temp=P1;
if(temp!=0xf0)
key_ok=1;
else?key_ok=0;
}
/************鍵盤(pán)掃描程序*************************
****功能:返回鍵值,當(dāng)無(wú)鍵按下時(shí),返回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; //行數(shù)和列數(shù)
while(1)
{
scan_full(); ? //粗判是否有鍵按下
if(key_ok==1)
{
key_ok=0;
delay(200); //延時(shí)去抖動(dòng)
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)//等待按鍵松開(kāi)
{
scan_full();
}
??? key_value=count;
??? return(key_value);//找到鍵值,馬上返回
?? }
?? else
?? {
??? count++;
??? y_scan=r_left(y_scan);
?? }
? }
y_scan=0xef; //掃描完一列,重新對(duì)列掃描量賦初值
? x_scan=r_left(x_scan);//行掃描碼左移一位,掃描下一行??
}
}
}
return(key_value);//沒(méi)鍵按下,返回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時(shí)就用這個(gè)頭文件
#include?reg52.h//用華邦W78E58B時(shí)必須用這個(gè)頭文件
//#include?absacc.h
//#include?ctype.h
//#include?math.h
//#include?stdio.h
//#include?string.h
#include?DS18B20.h //測(cè)溫頭文件
#include?LCD1602.h //液晶顯示頭文件
#include?keyscan.h //鍵盤(pán)掃描頭文件
sbit?alarm=P2^6; //報(bào)警信號(hào)
//sbit?DQ?=?P3^7; //定義DQ引腳為P3.7
unsigned?char?key_value;????????????//存放鍵盤(pán)掃描值
bit?up_one,down_one;? //加1和減1標(biāo)志
bit?alarm_up_flag,alarm_down_flag; //上限報(bào)警和下限報(bào)警設(shè)置標(biāo)志
bit?set_temper_flag; //設(shè)置控制標(biāo)志溫度標(biāo)志
bit?alarm_switch; //報(bào)警開(kāi)關(guān)
unsigned?char?user_temper; ?//用戶標(biāo)定溫度
unsigned?char?TH=110,TL=-20,RS=0x3f;?//上限溫度110,下限-20,分辨率10位,也就是0.25C
unsigned?char?t[2],*pt; //用來(lái)存放溫度值,測(cè)溫程序就是通過(guò)這個(gè)數(shù)組與主函數(shù)通信的
unsigned?char??TempBuffer1[17]={0x2b,0x20,0x30,0x30,0x2e,0x30,0x30,0x20,
0x53,0x45,0x54,0x2b,0x20,0x30,0x30,0x43,'\0'};
//顯示實(shí)時(shí)溫度,上電時(shí)顯示+?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'};
//顯示溫度上下限,上電時(shí)顯示TH:+?00?TL:+?00C
unsigned?char?code?dotcode[4]={0,25,50,75};
/***因顯示分辨率為0.25,但小數(shù)運(yùn)算比較麻煩,故采用查表的方法*******
再將表值分離出十位和個(gè)位后送到十分位和百分位********************/
/***********用戶設(shè)定溫度轉(zhuǎn)換為L(zhǎng)CD顯示數(shù)據(jù)**************
*功能:將用戶設(shè)定溫度user_temper,分離出符號(hào)位,百、十、個(gè)位
??并將它們轉(zhuǎn)化為ACSII碼,送到液晶顯示緩沖區(qū)
******************************************************/
void?user_temper_LCD(unsigned?char?temper)
{
if(temper0x7f) //判斷正負(fù),如果為負(fù)溫,將其轉(zhuǎn)化為其絕對(duì)值
{
TempBuffer1[11]=0x2d; //0x2d為"-"的ASCII碼
temper=~temper; //將負(fù)數(shù)的補(bǔ)碼轉(zhuǎn)換成絕對(duì)值
temper++;
}
else?TempBuffer1[11]=0x2b; ////0x2B為"+"的ASCII碼
TempBuffer1[12]=temper/100+0x30; ?????????????//分離出temper的百十個(gè)位
if(?TempBuffer1[12]==0x30)?TempBuffer1[12]=0xfe;?????//百位數(shù)消隱
TempBuffer1[13]=(temper%100)/10+0x30; ?????//分離出十位
TempBuffer1[14]=(temper%100)%10+0x30; ? ?????//分離出個(gè)位
}
/***************溫度上下限轉(zhuǎn)換為L(zhǎng)CD顯示數(shù)據(jù)************
*功能:將上下限報(bào)警溫度,分離出符號(hào)位,百、十、個(gè)位
??并將它們轉(zhuǎn)化為ACSII碼,送到液晶顯示緩沖區(qū)
******************************************************/
void?alarm_LCD(?unsigned?char?TH,?unsigned?char?TL)
{
if(TH0x7F)????????????????????//判斷正負(fù),如果為負(fù)溫,將其轉(zhuǎn)化為其絕對(duì)值
{
TempBuffer0[3]=0x2d; ?????//0x2d為"-"的ASCII碼
TH=~TH; ?//將負(fù)數(shù)的補(bǔ)碼轉(zhuǎn)換成絕對(duì)值
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的百十個(gè)位
if(?TempBuffer0[4]==0x30)?TempBuffer0[4]=0xfe;?//百位數(shù)消隱
TempBuffer0[5]=(TH%100)/10+0x30; //分離出十位
TempBuffer0[6]=(TH%100)%10+0x30; ? //分離出個(gè)位
TempBuffer0[12]=TL/100+0x30; ?????????????//分離出TL的百十個(gè)位
if(?TempBuffer0[12]==0x30)?TempBuffer0[12]=0xfe;?//百位數(shù)消隱
TempBuffer0[13]=(TL%100)/10+0x30; //分離出十位
TempBuffer0[14]=(TL%100)%10+0x30; ? //分離出個(gè)位
}
/**********溫度轉(zhuǎn)換為L(zhǎng)CD顯示數(shù)據(jù)****************
*功能:將兩個(gè)字節(jié)的溫度值,分離出符號(hào)位,整數(shù)及小數(shù)
??并將它們轉(zhuǎn)化為ACSII碼,送到液晶顯示緩沖區(qū)
************************************************/
void?temper_LCD(void)
{
unsigned?char?x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]0x07)????????????????????//判斷正負(fù)溫度
{
TempBuffer1[0]=0x2d; ?????//0x2d為"-"的ASCII碼
t[1]=~t[1]; ?/*下面幾句把負(fù)數(shù)的補(bǔ)碼*/
t[0]=~t[0];? ?/*?換算成絕對(duì)值*********/
x=t[0]+1; ?/***********************/
t[0]=x; ?/***********************/
if(x255)????????????????/**********************/
t[1]++; ?/*********************/
}
else?TempBuffer1[0]=0x2b; //0xfe為變"+"的ASCII碼
t[1]=4; //將高字節(jié)左移4位
t[1]=t[1]0x70; //取出高字節(jié)的3個(gè)有效數(shù)字位
x=t[0]; //將t[0]暫存到X,因?yàn)槿⌒?shù)部分還要用到它
x=4; //右移4位
x=x0x0f; //和前面兩句就是取出t[0]的高四位
t[1]=t[1]|x; //將高低字節(jié)的有效值的整數(shù)部分拼成一個(gè)字節(jié)
TempBuffer1[1]=t[1]/100+0x30; ?????????????//+0x30?為變?0~9?ASCII碼
if(?TempBuffer1[1]==0x30)?TempBuffer1[1]=0xfe;?//百位數(shù)消隱
TempBuffer1[2]=(t[1]%100)/10+0x30; //分離出十位
TempBuffer1[3]=(t[1]%100)%10+0x30; ? //分離出個(gè)位
t[0]=t[0]0x0c; //取有效的兩位小數(shù)
t[0]=2; //左移兩位,以便查表
x=t[0];
y=dotcode[x]; //查表?yè)Q算成實(shí)際的小數(shù)
TempBuffer1[5]=y/10+0x30; //分離出十分位
TempBuffer1[6]=y%10+0x30; //分離出百分位
}
/*********鍵盤(pán)命令處理函數(shù)************
*功能:把鍵盤(pán)值轉(zhuǎn)化成相應(yīng)的功能標(biāo)志位
*備注:為了提高程序的健壯性,在功能標(biāo)志位無(wú)效時(shí),
**up_one和down_one都無(wú)效,并且各功能標(biāo)志之間
**采用互鎖處理,雖然這樣麻煩,特別是功能標(biāo)志較多時(shí)
**更是麻煩,但各功能標(biāo)志之間是同級(jí)別的;
**也可采用多重if?else方法,雖然簡(jiǎn)單,
**但各功能標(biāo)志之間有了明顯的優(yōu)先級(jí)差別
**************************************/
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; //在沒(méi)有相應(yīng)功能標(biāo)志有效時(shí)
down_one=0x00; //up_one和down_one都被鎖定
}
if(alarm_up_flag(!alarm_down_flag)(!set_temper_flag))//設(shè)置上限報(bào)警
{
if(up_one)//上限報(bào)警加1
{
TH++;up_one=0;
if(TH=100)//超過(guò)100度,回零到20度
TH=20;
}
if(down_one)//上限報(bào)警減1
{
TH--;down_one=0;
if(TH=20)//小于20度,回零到20度
TH=20;
}
}
if((!alarm_up_flag)(alarm_down_flag)(!set_temper_flag))//設(shè)置下限報(bào)警
{
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))//設(shè)置用戶標(biāo)定溫度
{
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);???? //設(shè)置上下限報(bào)警溫度和分辨率
delay(100);?
while(1)
{
pt=ReadTemperature(); ? ?//測(cè)溫函數(shù)返回這個(gè)數(shù)組的頭地址
?//讀取溫度,溫度值存放在一個(gè)兩個(gè)字節(jié)的數(shù)組中,
temper_LCD(); ?//實(shí)測(cè)溫度轉(zhuǎn)化為ACSII碼,并送液晶顯示緩沖區(qū)
user_temper_LCD(user_temper); ?//用戶設(shè)定溫度轉(zhuǎn)化為ACSII碼,并送液晶顯示緩沖區(qū)
alarm_LCD(TH,TL); ?//上下限報(bào)警溫度轉(zhuǎn)化為ASCII碼,并送液晶顯示緩沖區(qū)
LCD_Initial(); //第一個(gè)參數(shù)列號(hào),第二個(gè)為行號(hào),為0表示第一行
//為1表示第二行,第三個(gè)參數(shù)為顯示數(shù)據(jù)的首地址
LCD_Print(0,0,TempBuffer0);
LCD_Print(0,1,TempBuffer1);
scan_full();?????????????????????//看有無(wú)鍵按下
if(key_ok) //如有鍵按下則看到底哪個(gè)鍵按下
{
key_value=key_scan(); ?//調(diào)用鍵盤(pán)掃描程序
key_command(key_value); ?//鍵盤(pán)命令處理函數(shù)
}
}
}
覺(jué)得能運(yùn)行,我試過(guò)了,自己看圖
華氏度
華氏度(Fahrenheit scale)是指用來(lái)計(jì)量溫度的單位。符號(hào)℉。華氏度 = 32°F(華氏溫標(biāo)單位)+ 攝氏度× 1.8。
世界上僅有5個(gè)國(guó)家使用華氏度,包括巴哈馬、伯利茲、英屬開(kāi)曼群島、帕勞、美利堅(jiān)合眾國(guó)及其他附屬領(lǐng)土(波多黎各、關(guān)島、美屬維京群島)。
中文名
華氏度
外文名
Fahrenheit scale
別名
華氏溫標(biāo)
提出者
華倫海特
提出時(shí)間
1724年
快速
導(dǎo)航
換算
起源
華氏度(°F)是溫度的一種度量單位,以其發(fā)明者德國(guó)人華倫海特(Gabriel D. Fahrenheit,1686—1736)命名的。1724年他發(fā)現(xiàn)液體金屬水銀比酒精更適宜制造溫度計(jì),以水銀為測(cè)溫介質(zhì),發(fā)明了玻璃水銀溫度計(jì),選取氯化銨和冰水的混合物的冰點(diǎn)溫度為溫度計(jì)的零度,人體溫度為溫度計(jì)的100度。在標(biāo)準(zhǔn)大氣壓下,冰的熔點(diǎn)為32℉,水的沸點(diǎn)為212℉,中間有180等分,每等分為華氏1度,記作“1℉”。
“華氏溫標(biāo)”是經(jīng)驗(yàn)溫標(biāo)之一。在美國(guó)的日常生活中,多采用這種溫標(biāo),用字母“℉”表示。
換算
攝氏溫標(biāo)(°C)和華氏溫標(biāo)(°F)之間的換算關(guān)系為:
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āi)氏度K
1 華氏度°F = 460.67 蘭氏度°Ra
1 華氏度°F = -13.777777777778 列氏
二.系統(tǒng)軟件設(shè)計(jì)
圖4 系統(tǒng)程序流程圖
2.1 系統(tǒng)程序流程圖
系統(tǒng)程序流程圖如圖4所示。
2.2 溫度部分軟件設(shè)計(jì)
DS18B20的一線工作協(xié)議流程是:初始化→ROM操作指令→存儲(chǔ)器操作指令→數(shù)據(jù)傳輸。其工作時(shí)序包括初始化時(shí)序、寫(xiě)時(shí)序和讀時(shí)序。故主機(jī)控制DS18B20完成溫度轉(zhuǎn)換必須經(jīng)過(guò)三個(gè)步驟:每一次讀寫(xiě)之前都要對(duì)DS18B20進(jìn)行復(fù)位,復(fù)位成功后發(fā)送一條ROM指令,最后發(fā)送RAM指令,這樣才能對(duì)DS18B20進(jìn)行預(yù)定的操作。復(fù)位要求主CPU將數(shù)據(jù)線下拉500微秒,然后釋放,DS18B20收到信號(hào)后等待16~60微秒左右,后發(fā)出60~240微秒的存在低脈沖,主CPU收到此信號(hào)表示復(fù)位成功。程序主要函數(shù)部分如下:
(1)初始化函數(shù)
//讀一個(gè)字節(jié)函數(shù)
ReadOneChar(void)
{unsigned char i=0;
unsigned char dat = 0;
for (i=8;i0;i--)
{ DQ = 0; // 給脈沖信號(hào)
dat=1;
DQ = 1; // 給脈沖信號(hào)
if(DQ)
dat|=0x80;
delay(4);}
return(dat);}
//寫(xiě)一個(gè)字節(jié)函數(shù)
WriteOneChar(unsigned char dat)
{unsigned char i=0;
for (i=8; i0; i--)
{DQ = 0;
DQ = dat0x01;
delay(5);
DQ = 1;
dat=1;}}
(2)讀取溫度并計(jì)算函數(shù)
ReadTemperature(void)
{unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
Init_DS18B20();
WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍輸出并四舍五入---此行沒(méi)用
(3)主程序部分見(jiàn)前
return(t);}
三. 結(jié)束語(yǔ)
AT89C2051單片機(jī)體積小、重量輕、抗干擾能力強(qiáng)、對(duì)環(huán)境要求不高、價(jià)格低廉、可靠性高、靈活性好。即使是非電子計(jì)算機(jī)專業(yè)人員,通過(guò)學(xué)習(xí)一些專業(yè)基礎(chǔ)知識(shí)以后也能依靠自己的技術(shù)力量來(lái)開(kāi)發(fā)所希望的單片機(jī)應(yīng)用系統(tǒng)。本文的溫度控制系統(tǒng)只是單片機(jī)廣泛應(yīng)用于各行各業(yè)中的一例,相信讀者會(huì)依靠自己的聰明才智使單片機(jī)的應(yīng)用更加廣泛化。另外對(duì)本例子可以作一些擴(kuò)展,單片機(jī)的應(yīng)用越來(lái)越廣泛,由于單片機(jī)的運(yùn)算功能較差,往往需要借助計(jì)算機(jī)系統(tǒng),因此單片機(jī)和PC機(jī)進(jìn)行遠(yuǎn)程通信更具有實(shí)際意義。目前此設(shè)計(jì)已成功應(yīng)用于鉆井模擬器實(shí)驗(yàn)室室溫控制。
本文作者創(chuàng)新觀點(diǎn):采用的單片機(jī)AT89C2051性價(jià)比高,而且溫度傳感器DS18B20轉(zhuǎn)化溫度的方法非常簡(jiǎn)潔且精度高、測(cè)試范圍較廣。
參考文獻(xiàn)
[1]林伸茂.8051單片機(jī)徹底研究基礎(chǔ)篇 北京:人民郵電出版社 2004
[2]范風(fēng)強(qiáng)等.單片機(jī)語(yǔ)言C51應(yīng)用實(shí)戰(zhàn)集錦 北京:電子工業(yè)出版社 2005
[3]譚浩強(qiáng).C語(yǔ)言程序設(shè)計(jì)(第二版) 北京:清華大學(xué)出版社 1999
[4]夏路易等.電路原理圖與電路板設(shè)計(jì)教程 北京:北京希望電子出版社 2002
[5]趙晶.Protel99高級(jí)應(yīng)用 北京:人民郵電出版社 2000
[6]聶毅.單片機(jī)定時(shí)器中斷時(shí)間誤差的分析及補(bǔ)償[J] 微計(jì)算機(jī)信息 2002,18(4):37~38
網(wǎng)站欄目:測(cè)溫函數(shù)python 遙測(cè)溫度計(jì)的測(cè)量原理
網(wǎng)頁(yè)URL:http://muchs.cn/article40/hjdoeo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、網(wǎng)站建設(shè)、小程序開(kāi)發(fā)、Google、電子商務(wù)、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容