|
///////////////////////////////////////////////////////////////////////////
/////////DS12C887+8位數(shù)碼管定時器中斷動態(tài)掃描遙控時鐘單片機程序模塊////////
///////////////////////////////////////////////////////////////////////////
[功能] 0: 8位數(shù)碼管定時器中斷動態(tài)掃描顯示
1:通過單片機解碼紅外遙控編碼并按上圖方式顯示出來
2:可通過遙控器調(diào)整時間,日期以及鬧鐘
3:時鐘芯片采用DS12C887+,內(nèi)部集成電池與晶體,不怕掉電丟時間信息
4:在調(diào)整時間過程中會有動態(tài)效果(正在調(diào)試中!!!以經(jīng)搞好了)
5:在下一版本中會增計算器功能,也是用遙控器操作 值得大家期待!
6: ds18b20溫度顯示(正在弄這個ds18b20)
7:數(shù)碼管掃描數(shù)據(jù)在P0口通過鎖存器(74HC573)輸出,ds12c887的雙向數(shù)據(jù)則直接接P0口
//以下是C源文件==============================================================================
- #include <reg51.h>//80C51頭文件
- #define uint unsigned int//16bit無符整型0~465536
- #define ulint unsigned long int//32bit無符長整0~4294967295
- #define uchar unsigned char//8bit宏定義無符字符型0-256
- #define c(x) (x*120000/120000)// (x*216000/120000) //定義時鐘頻率便于紅外遙控解碼
-
- //單片機硬件設(shè)置
- sbit duan = P2^0;//數(shù)碼管段選定義
- sbit wei = P2^1;//數(shù)碼管位選定義
- sbit Ir_Pin=P3^3;//紅外接收端口
- sbit beep = P2^7;//蜂鳴器
-
- //時鐘芯片ds12c887控制引腳與單片機連接
- sbit dscs = P2^6;//時鐘片選
- sbit dsas = P2^5;//地址選取通
- sbit dsrw = P2^4;//讀寫輸入
- sbit dsds = P2^3;//數(shù)據(jù)選通或輸入
- sbit dsirq= P2^2;//中斷請求輸出
- sbit DQ =P2^2;//定義溫度傳感器(18b20)通信端口
- //字符碼表
- uchar code Led_Tab[]={//共陽數(shù)碼管字符碼
- 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//0---f,ff全滅,
- 0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xbf,0xf7,0xc6,0x9c};//上,中,下3短橫線
- uchar code Led_Sel[]={//位碼
- 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- //定義各個變量
- uchar shan_xia=0,zuo_you=8,Ir_Buf[4],ds_temp=0,i;//上下變量,左右變量,遙控數(shù)字,紅外結(jié)果
- bit ok=0,power=0,mute,ds=0,i_k=0;//ds為0時才準(zhǔn)讀時鐘芯片,減少頻繁讀時鐘, i_k為5秒延時開關(guān)
- uint ms;//屏閃時基變量,溫度傳感變量
-
- //以下是動態(tài)掃描變量
- uchar Led_Buf[8],Led_Buf_temp[8],Led_Index;//顯示緩沖區(qū),調(diào)時閃動緩沖區(qū),位碼索引
- //聲明子函數(shù)
- void init();//初始化
- void write_ds(uchar add,uchar date);//時鐘芯片寫函數(shù)
- uchar read_ds(uchar add);//時鐘芯片讀函數(shù)
- void delay(uint z);//延時
- void hyyk();//紅外遙控
- uint Ir_Get_Low();//低電平時間采集
- uint Ir_Get_High();//高電平時間采集
- //遙控調(diào)時,數(shù)值放入顯示緩沖區(qū)同步顯示,預(yù)寫時鐘
- //經(jīng)數(shù)據(jù)采集函數(shù)(time_set())根據(jù)各項格式顯示特征識別后
- //按mute鍵寫時鐘芯片相應(yīng)地址達(dá)到調(diào)整時鐘信息的目的
- void ykm_set();
- void time_set();//時間調(diào)整數(shù)據(jù)采集分析寫調(diào)時緩沖區(qū)函數(shù)
- void ykm_out();//遙控碼顯示
- void led_out(uchar add_1,uchar add_2,uchar add_3,uchar add_4);//送出地址,讀出信息,更新顯示緩沖區(qū)
- void led_flash(uchar k,uchar z);//調(diào)時閃爍 K為閃動開關(guān) Z為閃動內(nèi)容
- //溫度顯示子函數(shù)聲明
- void delay_18b20(uint i);//延時
- Init_DS18B20(void);//初始化函數(shù)
- WriteOneChar(uchar dat);//寫一個字節(jié)
- ReadOneChar(void);//讀一個字節(jié)
- ReadTemperature(void);//讀取溫度
- void out_18b20();//顯示
-
- //主程序==================================================================================
- void main()//程序入口
- {
- init();//初始化
-
- while(1)//循環(huán)等待中斷
- {
- hyyk();//遙控
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x14))//POWER鍵值翻轉(zhuǎn)并響鈴
- {
- ok=0;zuo_you=8;shan_xia=0;//有遙控power時復(fù)位ok與上下,左右值,取消閃屏顯示時間
- power=(!power);
- if(power==0)
- {
- delay(10);
- beep=0;
- delay(20);
- beep=1;
- }
- Ir_Buf[2]=0xff;
- }
- if (power==1){uchar i;mute=1; for(i=0;i<8;i++) Led_Buf_temp[i]=16;}//在power標(biāo)志為1時關(guān)屏關(guān)鈴
-
- if(power==0)//power標(biāo)志為0時根據(jù)shan_xia鍵值顯示內(nèi)容
- {
- ykm_set();//遙控調(diào)時,調(diào)整好后按mute鍵寫時鐘
- led_flash(ok,shan_xia);
- if(ok==0){ds=0;i_k=0;ds_temp=0;}
- if(ds==0)
- {
- if(shan_xia==0)led_out(4,2,0,19);//時間
-
- else if(shan_xia==1)led_out(9,8,7,17);//日期
-
- else if(shan_xia==2)led_out(5,3,1,18);//鬧鐘
-
- else if(shan_xia==3)led_out(6,6,6,18);//星期
- else if(shan_xia==4)out_18b20();//溫度
-
- else ykm_out();//遙控碼
- }
-
- ds=1;//關(guān)時鐘芯片讀與顯存刷新,在中斷掃描時會打開
- //只有在需要顯示具體內(nèi)容時才會訪問時鐘芯片對應(yīng)的具體地址并更新顯示緩沖區(qū)
-
- //ok鍵值翻轉(zhuǎn)
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x15))
- {
- if((ok==1)&&(zuo_you<8)){zuo_you=8;i_k=1;i=1;}//如果是位閃狀態(tài)按ok鍵就進(jìn)入全閃狀態(tài)
- else {ok=(!ok);zuo_you=8;}//否則閃<==>不閃 狀態(tài)翻轉(zhuǎn)一次
- //if(ok==0){i_k=0;ds_temp=0;}//不閃時可以刷新數(shù)據(jù)
- Ir_Buf[2]=0xff;
- }
-
- //MUTE鍵值翻轉(zhuǎn)并響鈴
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x0c))
- {
- if(((ok==1)&&(zuo_you>7))&&(ds_temp>0))time_set();//如果從位閃變?yōu)槿W并且8秒寫時鐘窗口打開則寫時鐘
- else mute=(!mute);//否則此鍵為靜音轉(zhuǎn)換功能
- if(mute==0)
- {
- delay(10);
- beep=0;
- delay(20);
- beep=1;
- }
- Ir_Buf[2]=0xff;
- }
- //按遙控器左鍵加一
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x11))
- {
- if(ok==0)mute=1;//如果沒有閃屏按此鍵關(guān)閉聲音
- if(ok==1)
- {
- if(++zuo_you>7) zuo_you=0;//左移,超出苑圍轉(zhuǎn)到最右邊
- while(Led_Buf[zuo_you]>9){if((++zuo_you)>7) zuo_you=0;}//正在如果要閃動的位不是十則一直數(shù)還
- Ir_Buf[2]=0xff;
- }
- }
- //按遙控器右鍵減一
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x10))
- {
- if(ok==0)mute=0;//如果沒有閃屏按此鍵打開聲音
- if(ok==1)
- {
- if((--zuo_you)==255) zuo_you=7;//右移,超出苑圍轉(zhuǎn)到最左邊
- while(Led_Buf[zuo_you]>9){if((--zuo_you)==255) zuo_you=7;}//正在閃動的位不是十進(jìn)制數(shù)則一直移動開遙控
- Ir_Buf[2]=0xff;
- }
- }
-
- //按遙控器上鍵加一
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x12))
- {
- if((ok==1)&&(zuo_you<8))
- {
- Led_Buf[zuo_you]++;//位閃狀態(tài)有上鍵按下對應(yīng)位加一
- if(Led_Buf[zuo_you]>9)Led_Buf[zuo_you]=0;//超出為0
- }
- else
- {
- zuo_you=8;//改變顯示內(nèi)容時位閃變?nèi)灵W
- if(++shan_xia>5) shan_xia=0;//超出為0
- }
- Ir_Buf[2]=0xff;
- }
- //按遙控器下鍵減一
- if ((Ir_Buf[0]==0x02)&&(Ir_Buf[2]==0x13))
- {
- if((ok==1)&&(zuo_you<8))
- {
- Led_Buf[zuo_you]--;//位閃狀態(tài)有上鍵按下對應(yīng)位減一
- if(Led_Buf[zuo_you]==255)Led_Buf[zuo_you]=9;//超出則為9
- }
- else
- {
- zuo_you=8;//改變顯示內(nèi)容時位閃變?nèi)灵W
- if((--shan_xia)==255) shan_xia=5;//自減,超出則為4
- }
- Ir_Buf[2]=0xff;
- }
- }
- }
- }
-
- //數(shù)碼管掃描===============================================================
- timer0() interrupt 1 using 1//定時中斷發(fā)生,運行中斷函數(shù)
- {
- ms++;//屏閃時基
- if(ms>=500) ms=0;
- if(i_k==1) //不閃屏?xí)r允許刷新讀寫信息
- {
- if(ms==0){if((++i)>8)i=0;}//延時8秒給mute鍵的寫時鐘芯片時間窗口,
- ds_temp=i;
- }
- if(ds_temp==0)i_k=0;
- if(((ok==1)&&(zuo_you<8))||(ds_temp>0))ds=1;//在全屏閃5秒內(nèi)和位閃調(diào)時時不允許刷新顯存
- else ds=0;//ds為何0時才允許刷新顯存
- TL0=0x25;//12M 2ms(測試這個晶振誤差后的初值)
- TH0=0xf8;
-
- //以下9行消隱
- dscs=1;//關(guān)掉時鐘片選讓數(shù)據(jù)接收口(74hc573數(shù)碼管的位碼和段碼鎖存器)得到純凈的數(shù)據(jù)信號
- duan=0; // 關(guān)閉段選
- wei=0; // 關(guān)閉位選
- P0=0x00; // 消陷碼
- wei=1; // 打開位選
- wei=0; // 關(guān)閉位選,鎖存消隱碼
- P0=0xff; // 消隱碼
- duan=1; // 打開段選
- duan=0; // 關(guān)閉段選,鎖存消隱碼
-
- //數(shù)字顯示 在鎖存器的鎖存端出現(xiàn)下降沿時鎖存數(shù)據(jù)
- P0=Led_Tab[Led_Buf_temp[Led_Index]];// 數(shù)模段碼送P0口
- duan=1;// 打開段選
- duan=0;// 關(guān)閉段選,鎖存段碼
- P0=Led_Sel[Led_Index];// 位碼數(shù)據(jù)送P0口
- wei=1;// 打開位選
- wei=0;// 關(guān)閉位選,鎖存位碼
- if(++Led_Index>7) Led_Index=0;
- }
- //初始化=============================================================================
- void init()
- {
- //以下9行消隱 在開機瞬間消除屏閃
- dscs=1;//關(guān)掉時鐘片選讓數(shù)據(jù)接收口(74hc573為數(shù)碼管的位碼和段碼鎖存器)得到純靜凈的數(shù)據(jù)信號
- duan=0;// 關(guān)閉段選
- wei=0;// 關(guān)閉位選
- P0=0xff;// 消隱碼
- duan=1;// 打開段選
- duan=0;// 關(guān)閉段選,鎖存消隱碼
- P0=0x00;// 消陷碼
- wei=1;// 打開位選
- wei=0;// 關(guān)閉位選,鎖存消隱碼
- //定時器設(shè)置
- TMOD=0x11;
- TL0=0xc5;//重裝初值
- TH0=0xf1;//數(shù)碼管的刷新頻率2ms
- EA=1;//開定時總中斷
- ET0=1;//開定時器0中斷 用于遙控高低電平時間采集
- ET1=1;//開定時器1中斷
- TR0=1;//啟動定時器1 用于數(shù)碼管定時中斷掃描
- //以下是初始化時鐘芯片的控制寄存器A和B
- write_ds(0x0A,47); //寫時鐘芯片DS12C887+A寄存器,打開振蕩器,啟動記時 輸出2HZ方波
- write_ds(0x0B,126); //寫時鐘芯片B
-
- }
- //寫時鐘芯片DS12C887+時序========(請參考DS12C887芯片手冊)
- void write_ds(uchar add,uchar date)
- {dscs=0;dsas=0;dsas=1;dsrw=1;dsds=1;P0=add;dsas=0;dsrw=0;P0=date;dsrw=1;dsas=1;dscs=1;}
-
- //讀時鐘芯片DS12C887+時序========(請參考DS12C887芯片手冊)
- uchar read_ds(uchar add)
- {uchar ds_date;dscs=0;dsas=0;dsas=1;dsrw=1;dsds=1;P0=add;dsas=0;
- dsds=0;P0=0xff;ds_date=P0;dsds=1;dsas=1;dscs=1;return ds_date;}
-
- //根據(jù)具體內(nèi)容格式化輸出函數(shù)
- void led_out(uchar add_1,uchar add_2,uchar add_3,uchar add_4)
- {
- uchar a,b,c,d=add_4,i;
- for(i=0;i<4;i++)
- {
- if(i==0) a=read_ds(add_1);
- if(i==1) b=read_ds(add_2);
- if(i==2) c=read_ds(add_3);
- if(i==3) d=read_ds(add_4);
- }
- if(add_1==4)d=18;//時鐘間隔位
- if(add_1==5)d=16;//鬧鐘間隔位
-
- if(add_1==4||add_1==5)//按不同的內(nèi)容用不同的格式輸出(參數(shù)特征決定輸出內(nèi)容)
- {
- Led_Buf[7]=a/10;//分離小時位數(shù)據(jù)
- Led_Buf[6]=a%10;
- Led_Buf[4]=b/10;//分離分鐘位數(shù)據(jù)
- Led_Buf[3]=b%10;
- Led_Buf[1]=c/10;//分離秒鐘位數(shù)據(jù)
- Led_Buf[0]=c%10;
- Led_Buf[5]=d; //間隔位
- Led_Buf[2]=d;
- }
-
- else if(add_1==9)
- {
- Led_Buf[7]=2; //分離小時位數(shù)據(jù)
- Led_Buf[6]=0;
- Led_Buf[5]=a/10;
- Led_Buf[4]=a%10;//分離分鐘位數(shù)據(jù)
- Led_Buf[3]=b/10;
- Led_Buf[2]=b%10;
- Led_Buf[1]=c/10;//分離秒鐘位數(shù)據(jù)
- Led_Buf[0]=c%10;
- }
- else for(i=0;i<8;i++) Led_Buf[i]=a;
- }
-
- //遙控碼顯示========================================================================
- void ykm_out()
- {
- uchar y;//由于使用過的鍵會對用戶碼全置1操作,所以在此根據(jù)用戶反碼取反操作還原用戶碼
- if(Ir_Buf[0]==0x02)y=(~Ir_Buf[3]);
- else y=Ir_Buf[2];
- Led_Buf[0]=Ir_Buf[3]&0xf;//結(jié)果裝入顯示緩沖區(qū)
- Led_Buf[1]=(Ir_Buf[3]/16)&0xf;//數(shù)據(jù)反碼
- Led_Buf[2]=y&0xf;
- Led_Buf[3]=(y/16)&0xf;//數(shù)據(jù)碼
- Led_Buf[4]=Ir_Buf[1]&0xf;
- Led_Buf[5]=(Ir_Buf[1]/16)&0xf;//用戶反碼
- Led_Buf[6]=Ir_Buf[0]&0xf;
- Led_Buf[7]=(Ir_Buf[0]/16)&0xf;//用戶碼
- }
- //遙控數(shù)字鍵直接預(yù)調(diào)時==================================================================================
- void ykm_set()//從最左第一位開始直接輸入一個0--9的數(shù)時顯示出來后自動右移一位,當(dāng)?shù)阶钣疫厱r轉(zhuǎn)到最左邊
- {
- if((ok==1)&&((Ir_Buf[0]==0x02)&&(Ir_Buf[2]<10)))
- {
- if(zuo_you>7){zuo_you=7;ds=1;}//ds=1;保證此函數(shù)結(jié)束后不從寫 Led_Buf[7]
- while(Led_Buf[zuo_you]>9){if((--zuo_you)==255) zuo_you=7;}//閃動的第7位不是十進(jìn)制數(shù)則一直移動
- if(Ir_Buf[2]<9)Led_Buf[zuo_you]=Ir_Buf[2]+1;//因為我的遙控器按1時數(shù)據(jù)碼是0x00,按2是0x01...,按0是0x09
- else Led_Buf[zuo_you]=0;
- if((--zuo_you)==255) {zuo_you=8;i_k=1;i=1;}//先右移,如果到最右邊一位則轉(zhuǎn)到最左邊一位
- while(Led_Buf[zuo_you]>9){if((--zuo_you)==255)zuo_you=8;}//正在閃動的位不是十進(jìn)制數(shù)則一直移動
- Ir_Buf[2]=0xff;
- }
- if((ok==0)&&((Ir_Buf[0]==0x02)&&(Ir_Buf[2]<10)))
- {
- if(Ir_Buf[2]<6)shan_xia=Ir_Buf[2];
- }
- }
-
- //調(diào)時閃動函數(shù)========================================================================
- void led_flash(uchar k,uchar z)//K為閃動開關(guān),Z為閃動內(nèi)容
- {
- uchar x,y,a=k;
- if(z==1)y=17;
- else if(z==2)y=18;
- else y=19;
-
- if(a==0)for(x=0;x<8;x++)Led_Buf_temp[x]=Led_Buf[x];//正常狀態(tài)不閃動
-
- else//當(dāng)K值不為0里閃動
- {
- if(ms>220)for(x=0;x<8;x++){Led_Buf_temp[x]=Led_Buf[x];}//MS為閃動時基
- else
- {
- if(zuo_you<=7)Led_Buf_temp[zuo_you]=y;
- else for(x=0;x<8;x++)Led_Buf_temp[x]=y;
- }
- }
- }
-
- //延時void delay(uint z)
- { uint x,y;for(x=z;x>0;x--)for(y=500;y>0;y--);}
- //紅外遙控=========================================================================
- void hyyk()
- {
- uint temp;
- uchar i,j;
- temp=Ir_Get_Low();//低電平時間采集
- if(temp<c(8500) || temp>c(9500)) goto restart;//引導(dǎo)脈沖低電平在9ms 附近
- temp=Ir_Get_High();//高電平時間采集
- if(temp<c(4000) || temp>c(5000)) goto restart;//引導(dǎo)脈沖高電平在4。5ms 附近
- for(i=0;i<4;i++)//4個字節(jié)
- for(j=0;j<8;j++)//每個字節(jié)8位 共32bit裝入Ir_Buf[4]
- {
- temp=Ir_Get_Low();
- if(temp<c(200) || temp>c(800)) goto restart;//低電平時間符合
- temp=Ir_Get_High();
- if(temp<c(200) || temp>c(2000)) goto restart;//高電平時間符合
- Ir_Buf[i]>>=1;//數(shù)據(jù)右移一位
- if(temp>c(1120)) Ir_Buf[i]|=0x80;//高電平時間分析,大于1120us為1否則為0
- }
- if(mute==0)//靜音功能,默認(rèn)打開
- {
- beep=0;
- delay(15);
- beep=1;
- }
- restart://無效信號勻跳轉(zhuǎn)至此 加速循環(huán)提高程式運行效率
- TR1=0;//關(guān)定時器1中斷
- }
- //紅外低電平時間采集=======================================================================
- uint Ir_Get_Low()
- { //定時器清0
- TL1=0;
- TH1=0;//開始記數(shù)
- TR1=1;//完成一次記數(shù)
- while(!Ir_Pin && (TH1&0x80)==0);
- TR1=0;//關(guān)定時器
- return TH1*256+TL1;//反回記數(shù)值
- }
- //紅外高電平時間采集uint Ir_Get_High()
- {
- TL1=0;
- TH1=0;
- TR1=1;
- while(Ir_Pin && (TH1&0x80)==0);
- TR1=0;
- return TH1*256+TL1;
- }
- //時間調(diào)整數(shù)據(jù)采集分析寫調(diào)時緩沖區(qū)函數(shù)
- void time_set()
- {
- uchar write[3]//write[3]為預(yù)寫緩沖區(qū)
- ok=0;//當(dāng)寫時鐘芯片后不閃,并可以馬上刷新屏幕
- if((Led_Buf[2]==16)||(Led_Buf[2]==18))//此時顯示的是鬧鐘或時間,那么預(yù)寫緩沖區(qū)的數(shù)到顯示緩沖區(qū)相應(yīng)的數(shù)
- {
- write[0]=Led_Buf[0]+Led_Buf[1]*10; //預(yù)寫秒位
- write[1]=Led_Buf[3]+Led_Buf[4]*10; //預(yù)寫分位
- write[2]=Led_Buf[6]+Led_Buf[7]*10; //預(yù)寫時位
- if(Led_Buf[2]==18) //是時間格式特征
- {
- write_ds(0x04,write[2]); //寫時 向時鐘芯片ds12c887+寫信息
- write_ds(0x02,write[1]); //寫分
- write_ds(0x00,write[0]); //寫秒
- }
- if(Led_Buf[2]==16) //是鬧鐘格式特征
- {
- write_ds(0x05,write[2]); //寫時(鬧鐘) 向時鐘芯片ds12c887+寫信息
- write_ds(0x03,write[1]); //寫分(鬧鐘)
- write_ds(0x01,write[0]); //寫秒(鬧鐘)
- }
- }
-
-
-
- if((Led_Buf[7]==2)&&(Led_Buf[6]==0)&&(Led_Buf[3]<2)&&(Led_Buf[1]<4))//是日期的格式特征
- {
- write[0]=Led_Buf[0]+Led_Buf[1]*10;//預(yù)寫日
- write[1]=Led_Buf[2]+Led_Buf[3]*10;//預(yù)寫月
- write[2]=Led_Buf[4]+Led_Buf[5]*10;//預(yù)寫年
- write_ds(0x09,write[2]); //寫年 向時鐘芯片ds12c887+寫信息
- write_ds(0x08,write[1]); //寫月
- write_ds(0x07,write[0]); //寫日
- }
-
- if((Led_Buf[1]==Led_Buf[2])&&(Led_Buf[6]==Led_Buf[7]))//是星期格式特征(先排除時間與鬧鐘格式再排除日期格式)
- {
- write[0]=Led_Buf[7];
- // if(write[0]>7)write[0]=0;
- write_ds(0x06,write[0]); //寫星期 向時鐘芯片ds12c887+寫信息
- }
- }
- //以下全為溫度傳感函數(shù)
- //延時
- void delay_18b20(uint i)
- {while(i--);}
- //初始化函數(shù)
- Init_DS18B20(void)
- {
- uchar x=0;
- DQ = 1; //DQ復(fù)位
- delay_18b20(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay_18b20(80); //精確延時 大于 480us
- DQ = 1; //拉高總線
- delay_18b20(14);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay_18b20(20);
- }
- //讀一個字節(jié)
- ReadOneChar(void)
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; //給脈沖信號
- dat>>=1;
- DQ = 1; //給脈沖信號
- if(DQ)
- dat|=0x80;
- delay_18b20(4);
- }
- return(dat);
- }
- //寫一個字節(jié)
- WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18b20(5);
- DQ = 1;
- dat>>=1;
- }
- delay_18b20(4);
- }
- //讀取溫度
- ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned char t=0;
- Init_DS18B20();
- WriteOneChar(0xCC);// 跳過讀序號列號的操作
- WriteOneChar(0x44);// 啟動溫度轉(zhuǎn)換
- Init_DS18B20();
- WriteOneChar(0xCC);//跳過讀序號列號的操作
- WriteOneChar(0xBE);//讀取溫度寄存器等(共可讀9個寄存器)前兩個就是溫度
- a=ReadOneChar();//讀取溫度值低位
- b=ReadOneChar();//讀取溫度值高位
- a=a>>4;//低位右移4位,舍棄小數(shù)部分
- t=b<<4;//高位左移4位,舍棄符號位
- t=t|a;
- return(t);
- }
- void out_18b20()//溫度顯示函數(shù)
- {
- int temp_18b20;
- temp_18b20=ReadTemperature();
- Led_Buf[7]=16;
- Led_Buf[6]=16;
- Led_Buf[5]=16;
- Led_Buf[4]=16;
- Led_Buf[3]=temp_18b20/10;
- Led_Buf[2]=temp_18b20%10;
- Led_Buf[1]=20;
- Led_Buf[0]=21;
- }
復(fù)制代碼
|
|