|
- #include<reg51.h> //51單片機(jī)的頭文件
- #define uchar unsigned char //宏定義,用uchar來(lái)代替unsigned char(無(wú)符號(hào)字符型變量,也即是無(wú)符號(hào)的8位變量),
- //宏定義的原因就是書(shū)寫(xiě)方便,宏定義后,uchar可直接用來(lái)定義變量
- #define uint unsigned int //原因同上,不過(guò)要注意,unsigned int為無(wú)符號(hào)的整型變量
- uint present; // 實(shí)際溫度(擴(kuò)大了10倍)
- uint setting=30; //設(shè)定值
- sbit led=P3^5; //sbit是用來(lái)管腳的。此處定義LED燈由P3.5口控制
- sbit buzzer=P3^6; //蜂鳴器由P3.6口控制
- sbit DS=P3^7; //讀取溫度引腳
- sbit NixieTube0_DIG1=P1^2; // 實(shí)際溫度顯示十位數(shù)字的數(shù)碼管位選端
- sbit NixieTube0_DIG2=P1^3; //// 實(shí)際溫度顯示個(gè)位數(shù)字的數(shù)碼管位選端
- sbit NixieTube1_DIG1=P1^4; //// 設(shè)定溫度顯示十位數(shù)字的數(shù)碼管位選端
- sbit NixieTube1_DIG2=P1^5; //// 設(shè)定溫度顯示個(gè)位數(shù)字的數(shù)碼管位選端
-
- sbit add=P1^0; //按鍵加
- sbit sub=P1^1; //按鍵減
- unsigned char code table[]={0x82,0xF3,0x4A,0x62,0x33,0x26,0x06,0xE3,0x02,0x22}; //數(shù)碼管端碼表,相當(dāng)于顯示緩沖區(qū),依次是0——9.
- void delay(uint count) //延時(shí)函數(shù),用來(lái)進(jìn)行延時(shí),應(yīng)該是毫秒級(jí)延時(shí)
- {
- uint i;
- while(count) // count為函數(shù)的形參,當(dāng)count為0時(shí),跳出此處while循環(huán)
- {
- i=200;
- while(i>0) //
- i--; //此i--和while(i>0)可以看成是一個(gè)整體,當(dāng)i=0時(shí),就會(huì)跳出,執(zhí)行count--。
- count--; //count自減一次,i就會(huì)由200減到0
- }
- }
- /***********************************************************
- void initialize(void)//初始化函數(shù)
- 溫度傳感器采用的是DS18b20,此傳感器采用的
- 是“單總線”來(lái)傳輸數(shù)據(jù)。
- 在使用DS18b20時(shí),要對(duì)其進(jìn)行初始化操作,其初始化的要求是(根據(jù)DS18b20的時(shí)序圖得):
- (1)先將數(shù)據(jù)線置1,但是置1的時(shí)間要盡可能短(可以直接忽略此操作,因?yàn)?1單片機(jī)引腳上電默認(rèn)就是高電平。)。
- (2)將數(shù)據(jù)線(DS)拉低
- (3)延時(shí)750us左右
- (4)再將數(shù)據(jù)線(DS)拉高
- (5)進(jìn)行短暫延時(shí)
- *****************************************************************/
- void initialize(void) //初始化
- {
-
- uint i;
- DS=0; //將DS(P3.7)引腳拉低。請(qǐng)注意,這里的DS不是變量,而是單片機(jī)的引腳!!!
- i=103;
- while(i>0)i--; //延時(shí)
- DS=1; //將DS拉高
- i=4;
- while(i>0)i--; //短暫延時(shí)
- }
- /*************************************************************************************
- 說(shuō)明:DS18b20采用的是單總線,一次只能讀取溫度的1個(gè)Bit。
- 函數(shù)作用:bit tmpreadbit(void) //溫度讀取函數(shù),此處讀取的是溫度的1個(gè)bit,帶返回值
- 函數(shù)使用舉例:A=tmpreadbit(); // 變量A保存的只是溫度的一個(gè)bit
- DS18B20溫度讀取時(shí)序用單片機(jī)來(lái)實(shí)現(xiàn)的步驟如下:
- (1) 數(shù)據(jù)線DS拉低
- (2) 延時(shí)6us左右
- (3)將數(shù)據(jù)線DS拉高
- (4)延時(shí)4us左右
- (5) 此時(shí)DS便會(huì)得到一個(gè)狀態(tài)位,即1個(gè)Bit的數(shù)據(jù)
- (6)延時(shí)30us左右
- **************************************************************************************/
- bit tmpreadbit(void) //溫度讀取函數(shù),此處讀取的是溫度的1個(gè)bit.帶返回值
- {
- uint i;
- bit dat;
- DS=0;i++; //將數(shù)據(jù)線拉低并延時(shí)
- DS=1;i++;i++; //將數(shù)據(jù)線拉高并延時(shí)
- dat=DS; //讀取1個(gè)bit數(shù)據(jù),此處注意,DS變成了輸入引腳,DS18b20的數(shù)據(jù)會(huì)保存到局部變量dat中
- i=8;while(i>0)i--; //延時(shí)
- return (dat); //將讀取的數(shù)據(jù)返回
- }
- /***********************************************************************************************
- 說(shuō)明:DS18b20采用的是單總線,一次只能讀取溫度的1個(gè)Bit。溫度一共8個(gè)bit,此函數(shù)共讀了8次
- 函數(shù)作用:uchar tmpread(void) //溫度讀取函數(shù),此處讀取的是溫度數(shù)據(jù)的原始數(shù)據(jù),帶返回值
- 函數(shù)使用舉例:A=tmpread(); // 變量A保存的是溫度的原始數(shù)據(jù)
- *************************************************************************************************/
- uchar tmpread(void)
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++) //采用for 循環(huán),讀取原始溫度數(shù)據(jù)
- {
- j=tmpreadbit(); //讀取一個(gè)位
- dat=(j<<7)|(dat>>1);//讀取的溫度最低位在前,這樣剛好一個(gè)字節(jié)的溫度在dat中
- }
- return(dat); //將溫度數(shù)據(jù)返回
- }
-
- void tmpwritebyte(uchar dat) // 寫(xiě)指令函數(shù), dat為形參。
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++) //for循環(huán),8次,剛好寫(xiě)一個(gè)字節(jié)
- {
- testb=dat&0x01; //將形參的最低位與1相與,1&1=1,0&1=0;
- dat=dat>>1; //執(zhí)行完testb=dat&0x01;把傳入的形參右移一位,方便判斷下一位數(shù)據(jù)是0還是1,共移位8次,保證寫(xiě)入一個(gè)字節(jié)
- if(testb) //write 1
- {
- DS=0;
- i++;i++;
- DS=1; //DS=1的延時(shí)比較長(zhǎng),寫(xiě)入的就是1
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //write 0
- i=8;while(i>0)i--; //DS=0的延時(shí)比較長(zhǎng),寫(xiě)入的就是0
- DS=1;
- i++;i++;
- }
- }
- }
- void tmpchange(void) //溫度轉(zhuǎn)換函數(shù),
- {
- initialize(); //初始
- delay(1);
- tmpwritebyte(0xcc); //跳過(guò)讀ROM指令
- tmpwritebyte(0x44); //告訴DS18b20轉(zhuǎn)換溫度
- }
- uint tmp() //轉(zhuǎn)換函數(shù),將原始數(shù)據(jù)轉(zhuǎn)化成實(shí)際的溫度數(shù)據(jù)
- {
- float tt;
- uchar a,b;
- initialize(); //初始化
- delay(1); //延時(shí)
- tmpwritebyte(0xcc);//跳過(guò)讀ROM指令
- tmpwritebyte(0xbe); //讀溫度指令
- a=tmpread(); // 低8位數(shù)據(jù),即溫度的小數(shù)部分
- b=tmpread(); //高8位,即溫度的整數(shù)部分
- present=b;
- present<<=8; //將整數(shù)部分右移8位
- present=present|a; //將兩個(gè)字節(jié)組合成一個(gè)字
- tt=present*0.0625; //分辨率是0.0625,即原始數(shù)據(jù)*分辨率=實(shí)際溫度
- present=tt*10+0.5; //乘10表示小數(shù)點(diǎn)后面只取一位,+0.5是表示四舍五入
- return present; //返回實(shí)際溫度
- }
- //用的是共陽(yáng)極數(shù)碼管,顯示原理采用的是動(dòng)態(tài)顯示
- void display0(uint temp) //溫度顯示函數(shù) ,temp 為形參
- {
- uchar A1,A2,A2t;
- ////此處注意!因溫度讀取函數(shù)中 present=tt*10+0.5;即將溫度擴(kuò)大了10倍,所以原始溫度的十位變成了百位,
- //各位變成了十位,十分位變成了個(gè)位,因此我們只需取百位上的數(shù)字和十位上的數(shù)字即可。注意,是數(shù)字,不是數(shù)!
- A1=temp/100; //取模,將百位數(shù)字取下,存到變量A1中,
- A2t=temp%100; //取余,比如傳進(jìn)來(lái)的temp=325,則325%100=25;
- A2=A2t/10; //將余數(shù)對(duì)10取模,比如 25/10=2;
-
- NixieTube0_DIG1=1; //打開(kāi)數(shù)碼管位選端
- if(A1<=9|A1>=0) //判斷A1是否位一位數(shù)字,實(shí)際溫度的十位上的數(shù)字
- P2=table[A1]; //送入顯示
- delay(1); //延時(shí),待顯示穩(wěn)定
- NixieTube0_DIG1=0; // 關(guān)斷數(shù)碼管
- NixieTube0_DIG2=1; //打開(kāi)數(shù)碼管位選端
- if(A2<=9|A2>=0) //判斷A2是否位一位數(shù)字,實(shí)際溫度的個(gè)位上的數(shù)字
- P2=table[A2]; //送入顯示
- delay(1); //延時(shí),待顯示穩(wěn)定
- NixieTube0_DIG2=0; // 關(guān)斷數(shù)碼管
-
- }
- void display1(uint spare) //設(shè)定溫度顯示
- {
- uchar B1,B2;
- B1=spare/10; //將設(shè)定溫度對(duì)10取模,獲取十位上的數(shù)字
- B2=spare%10; //將設(shè)定溫度對(duì)10取余,獲取個(gè)位上的數(shù)字
- NixieTube1_DIG1=1; ////打開(kāi)數(shù)碼管位選端
- P2=table[B1]; //送入十位上的數(shù)字
- delay(1); ////延時(shí),待顯示穩(wěn)定
- NixieTube1_DIG1=0; //關(guān)斷顯示
-
- NixieTube1_DIG2=1; //打開(kāi)顯示
- P2=table[B2]; //送入個(gè)位上的數(shù)字
- delay(1); //延時(shí),待顯示穩(wěn)定
- NixieTube1_DIG2=0; //關(guān)斷顯示
- }
- void main() //主函數(shù)
- {
-
- uchar a;
- uchar b;
- uchar c;
- P2=0xf7; //對(duì)P2口初始化,開(kāi)機(jī)先不讓數(shù)碼管顯示
- NixieTube0_DIG1=1; //初始化,數(shù)碼管位選端拉高
- NixieTube0_DIG2=1; //同上
- NixieTube1_DIG1=1; //同上
- NixieTube1_DIG2=1; //同上
- buzzer=0; //蜂鳴器引腳拉低,上電,蜂鳴器響一秒
- delay(1000); //延時(shí)1S左右
- while(1)
- {
- tmpchange();//向溫度傳感器寫(xiě)入溫度轉(zhuǎn)換指令
- if(add==1) //如果 按鍵加 沒(méi)有按下
- b=1; //b=1;b的作用相當(dāng)于松手檢測(cè)
- if(add==0&b==1) //如果按鍵按下
- {
- if(setting==99)
- {}
- else
- {
- setting++;//設(shè)定值自加一次
- b=0; //只有按下松手后,再按 按鍵加 才能再次使設(shè)定值自加一次
- }
- };
- if(sub==1) //按鍵減未被按下
- c=1; //作用與b相同
- if(sub==0&c==1) //如果按鍵減 被按下
- {
- if(setting==0)
- {}
- else
- {
- setting--;//設(shè)定值自減一次
- c=0; //作用同上面的b
- }
- };
- if(present<=setting*10) //如果實(shí)際溫度小于設(shè)定溫度
- {
- buzzer=0; //蜂鳴器不響
- led=0; //燈亮
- }
- else
- {
- buzzer=0; //否則 蜂鳴器響
- led=1; //燈不亮
- }
- for(a=10;a>0;a--)
- {
- display0(tmp()); //顯示實(shí)際溫度
- display1(setting); //顯示設(shè)定溫度
- }
- }
- }
復(fù)制代碼
|
|