|
大佬們,要怎么改代碼才能讓我的溫度顯示值。單獨(dú)的溫度顯示成功了但與時(shí)間和在一起又不行
IMG_20241017_231650.jpg (650.89 KB, 下載次數(shù): 5)
下載附件
2024-10-17 23:18 上傳
單片機(jī)源程序如下:
- #include<reg51.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define yh 0x80 //LCD第一行的初始位置地址
- #define er 0xC0 //LCD第二行的初始位置地址
- //液晶屏的與C51之間的引腳連接定義(顯示數(shù)據(jù)線(xiàn)接C51的P0口)
- sbit rs = P2^0;
- sbit rw = P2^1; //如果硬件上rw接地,就不用寫(xiě)這句和后面的rw=0了
- sbit en = P2^2;
- //DS18B20單總線(xiàn)接口與C51之間的引腳連接定義
- sbit DQ = P2^3;
- //DS1302時(shí)鐘芯片與C51之間的引腳連接定義
- sbit RST =P2^4;
- sbit SCLK=P2^5;
- sbit IO =P2^6;
- //校時(shí)按鍵與C51的引腳連接定義
- sbit key1=P3^5; //設(shè)置鍵
- sbit key2=P3^6; //加鍵
- sbit key3=P3^7; //減鍵
- //ACC累加器
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- //年、月、日 漢字代碼數(shù)組
- unsigned char character0[24] = {
- 0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, //"年"地址代碼 0x00
- 0x0F,0x09,0x0F,0x09,0x0F,0x09,0x13,0x00, //"月"地址代碼 0x01
- 0x0F,0x09,0x09,0x0F,0x09,0x09,0x0F,0x00}; //"日"地址代碼 0x02
- //年、月、日顯示的固定字符
- uchar code tab1[]={'2','0','-','-',0x00,'-','-',0x01,'-','-',0x02};
- //時(shí)間、溫度顯示的固定字符
- uchar code tab2[]={':','-','-',':','-','-',' ',' ','-','-',0xdf,0x43};
- //星期字符:仿真DS1302的周寄存器正常運(yùn)行計(jì)數(shù)1~7,表示周日~六
- uchar code tab3[8][3]={"***","SUN","MON","TUE","WED","THU","FRI","SAT"};
- //緩存 存儲(chǔ)順序是秒分時(shí)日月周年
- char data TIME[7]={0,0,12,12,1,05,23};
- //DS1302讀出地址,存儲(chǔ)順序是秒分時(shí)日月周年
- uchar code READ_RTC_ADDR[7]= {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
- //DS1302寫(xiě)入地址,存儲(chǔ)順序是秒分時(shí)日月周年
- uchar code WRITE_RTC_ADDR[7]= {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
- uchar Key_value;
- bit flag=0;//5毫秒中斷標(biāo)志
- bit mark=1;
- //延時(shí)函數(shù)
- void delay(uint xms)//延時(shí)函數(shù),有參函數(shù)
- {
- uint x,y;
- for(x=xms;x>0;x--)
- for(y=110;y>0;y--);
- }
- /***********LCD1602判忙函數(shù)**********/
- void Read_Busy() //忙檢測(cè)函數(shù),判斷bit7是 0執(zhí)行 1禁止
- {
- uchar sta; //
- rs = 0;
- rw = 1;
- P0 = 0xff;
- do
- {
- en = 1;
- sta = P0;
- en = 0; //使能
- }while(sta & 0x80);
- }
- //****液晶寫(xiě)入指令函數(shù)****
- void write_1602com(uchar com)
- {
- Read_Busy();
- rs=0;//數(shù)據(jù)/指令選擇置為指令
- rw=0; //讀寫(xiě)選擇置為寫(xiě)
- en=1;//拉高使能端,為制造有效的下降沿做準(zhǔn)備
- P0=com;//送入數(shù)據(jù)
- // delay(1);
- en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
- //***液晶寫(xiě)入數(shù)據(jù)函數(shù)****
- void write_1602dat(uchar dat)
- {
- Read_Busy();
- rs=1;//數(shù)據(jù)/指令選擇置為數(shù)據(jù)
- rw=0; //讀寫(xiě)選擇置為寫(xiě)
- en=1; //en置高電平,為制造下降沿做準(zhǔn)備
- P0=dat;//送入數(shù)據(jù)
- // delay(1);
- en=0; //en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
- //***液晶初始化函數(shù)****
- void LCD_Init()
- {
- uchar i;
- write_1602com(0x38);//設(shè)置液晶工作模式
- write_1602com(0x0c);//開(kāi)顯示不顯示光標(biāo)
- write_1602com(0x06);//整屏不移動(dòng),光標(biāo)自動(dòng)右移
- write_1602com(0x01);//清顯示
- write_1602com(yh);//日歷顯示固定符號(hào)從第一行第0個(gè)位置之后開(kāi)始顯示
- for(i=0;i<11;i++)
- {
- write_1602dat(tab1[i]);//向液晶屏寫(xiě)日歷顯示的固定符號(hào)部分
- }
- write_1602com(er+4);//時(shí)間顯示固定符號(hào)寫(xiě)入位置,從第2個(gè)位置后開(kāi)始顯示
- for(i=0;i<14;i++)
- {
- write_1602dat(tab2[i]);//寫(xiě)顯示時(shí)間固定符號(hào),兩個(gè)冒號(hào)和C
- }
- }
- /***************DS1302有關(guān)子函數(shù)********************/
- void write_byte(uchar dat)//寫(xiě)一個(gè)字節(jié)
- {
- uchar i;
- ACC=dat;
- RST=1;
- for(i=8;i>0;i--)
- {
- IO=ACC0;
- SCLK=0;
- SCLK=1;
- ACC>>=1;
- }
- }
- uchar read_byte()//讀一個(gè)字節(jié)
- {
- uchar i;
- RST=1;
- for(i=8;i>0;i--)
- {
- ACC7=IO;
- SCLK=1;
- SCLK=0;
- ACC>>=1;
- }
- return ACC;
- }
- //----------------------------------------
- void write_1302(uchar add,uchar dat)//向1302芯片寫(xiě)函數(shù),指定寫(xiě)入地址,數(shù)據(jù)
- {
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- write_byte(dat);
- SCLK=1;
- RST=0;
- }
- uchar read_1302(uchar add)//從1302讀數(shù)據(jù)函數(shù),指定讀取數(shù)據(jù)來(lái)源地址
- {
- uchar temp;
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- temp=read_byte();
- SCLK=1;
- RST=0;
- return(temp);
- }
- //BCD碼轉(zhuǎn)十進(jìn)制函數(shù),輸入BCD碼返回十進(jìn)制
- uchar BCD_D(uchar bcd)//BCD碼轉(zhuǎn)十進(jìn)制函數(shù),
- {
- return ((bcd>>4)*10)+(bcd & 0x0f);
- }
- //十進(jìn)制轉(zhuǎn)BCD碼函數(shù),輸入十進(jìn)制返回BCD碼
- uchar D_BCD(uchar Dec)
- {
- return (Dec/10*16+Dec%10);
- }
- //--------------------------------------
- /*
- //1302芯片初始化函數(shù)
- void ds1302_init()
- {
- uchar i,
- RST=0;
- SCLK=0;
- write_1302(0x8e,0x00); //允許寫(xiě),禁止寫(xiě)保護(hù)
- for(i=0;i<7;i++)
- write_1302(WRITE_RTC_ADDR[i],D_BCD(TIME[i])); //向DS1302內(nèi)寫(xiě)入初始數(shù)據(jù)
- write_1302(0x8e,0x80); //打開(kāi)寫(xiě)保護(hù)
- }*/
- //刷新LCD函數(shù)
- write_LCD(uchar add,uchar dat)
- {
- write_1602com(add);
- write_1602dat(dat/10+'0');
- write_1602dat(dat%10+'0');
- }
- //刷新星期函數(shù)
- void write_WEE(uchar add, uchar dat)
- {
- uchar i;
- write_1602com(add);//星期字符的顯示位置
- for(i=0;i<3;i++)
- write_1602dat(tab3[dat][i]);
- }
- //按鍵掃描函數(shù)
- void keyscan()
- {
- static bit key_sign=0;//按鍵狀態(tài)標(biāo)志
- static uchar count=0;
- uchar i;
- if(!key1||!key2||!key3)
- {
- if(++count>=3 && key_sign==0)
- {
- key_sign=1;
- if(!key1)
- {
- Key_value=++Key_value%8;
- switch(Key_value)
- {
- case 0: write_1602com(0x0c);//按動(dòng)到第8次,設(shè)置光標(biāo)不閃爍
- write_1302(0x8e,0x00);//允許寫(xiě),禁止寫(xiě)保護(hù)
- for(i=0;i<7;i++)
- write_1302(WRITE_RTC_ADDR[i],D_BCD(TIME[i])); //向DS1302內(nèi)寫(xiě)入數(shù)據(jù)
- write_1302(0x8e,0x80);//禁止寫(xiě),打開(kāi)寫(xiě)保護(hù)
- mark=1;break;//允許讀1302
- case 1: mark=0;//禁止讀DS1302
- write_1602com(0x0f); //設(shè)置光標(biāo)為閃爍
- write_1602com(yh+3); break;//按動(dòng)第1次,年位置顯示光標(biāo)
- case 2: write_1602com(yh+6); break;//按動(dòng)第2次,月位置顯示光標(biāo)
- case 3: write_1602com(yh+9); break;//按動(dòng)第3次,日位置顯示光標(biāo)
- case 4: write_1602com(yh+14);break;//按動(dòng)第4次,周位置顯示光標(biāo)
- case 5: write_1602com(er+3); break;//按動(dòng)第5次,時(shí)位置顯示光標(biāo)
- case 6: write_1602com(er+6); break;//按動(dòng)第6次,分位置顯示光標(biāo)
- case 7: write_1602com(er+9); break;//按動(dòng)第7次,秒位置顯示光標(biāo)
- }
- }
- if(!key2 && Key_value!=0)
- {
- switch(Key_value)
- {
- case 1:if(++TIME[6]>99)TIME[6]=0; write_LCD(yh+2, TIME[6]);write_1602com(yh+3); break;//調(diào)年
- case 2:if(++TIME[4]>12)TIME[4]=1; write_LCD(yh+5, TIME[4]);write_1602com(yh+6); break;//調(diào)月
- case 3:if(++TIME[3]>31)TIME[3]=1; write_LCD(yh+8, TIME[3]);write_1602com(yh+9); break;//調(diào)日
- case 4:if(++TIME[5]>7) TIME[5]=1; write_WEE(yh+13,TIME[5]);write_1602com(yh+14);break;//調(diào)周
- case 5:if(++TIME[2]>23)TIME[2]=0; write_LCD(er+2, TIME[2]);write_1602com(er+3); break;//調(diào)時(shí)
- case 6:if(++TIME[1]>59)TIME[1]=0; write_LCD(er+5, TIME[1]);write_1602com(er+6); break;//調(diào)分
- case 7:if(++TIME[0]>59)TIME[0]=0; write_LCD(er+8, TIME[0]);write_1602com(er+9); break;//調(diào)秒
- }
- }
- if(!key3 && Key_value!=0)
- {
- switch(Key_value)
- {
- case 1:if(--TIME[6]<0)TIME[6]=99; write_LCD(yh+2, TIME[6]);write_1602com(yh+3); break;//調(diào)年
- case 2:if(--TIME[4]<1)TIME[4]=12; write_LCD(yh+5, TIME[4]);write_1602com(yh+6); break;//調(diào)月
- case 3:if(--TIME[3]<1)TIME[3]=31; write_LCD(yh+8, TIME[3]);write_1602com(yh+9); break;//調(diào)日
- case 4:if(--TIME[5]<1)TIME[5]=7; write_WEE(yh+13,TIME[5]);write_1602com(yh+14);break;//調(diào)周
- case 5:if(--TIME[2]<0)TIME[2]=23; write_LCD(er+2, TIME[2]);write_1602com(er+3); break;//調(diào)時(shí)
- case 6:if(--TIME[1]<0)TIME[1]=59; write_LCD(er+5, TIME[1]);write_1602com(er+6); break;//調(diào)分
- case 7:if(--TIME[0]<0)TIME[0]=59; write_LCD(er+8, TIME[0]);write_1602com(er+9); break;//調(diào)秒
- }
- }
- }
- }
- else
- {
- key_sign=0;
- count=0;
- }
- }
- /******************************* 延時(shí)函數(shù) ********************************
- * 功能:在11.059MHz的晶振條件下調(diào)用本函數(shù)需要24μs ,然后每次計(jì)數(shù)需16μs
- **************************************************************************/
- void DS18_delay(int us)
- {
- int s;
- for (s=0;s<us;s++);
- }
- /******************************* 復(fù)位函數(shù) *******************************
- * 功能:完成單總線(xiàn)的復(fù)位操作。
- * 復(fù)位時(shí)間為480μs,因此延時(shí)時(shí)間為(480-24)/16 = 28.5,取29μs。
- * 經(jīng)過(guò)70μs之后檢測(cè)存在脈沖,因此延時(shí)時(shí)間為(70-24)/16 = 2.875,取3μs
- **************************************************************************/
- unsigned char ow_reset(void)
- {
- unsigned char presence;
- DQ = 0; // 將 DQ 線(xiàn)拉低
- DS18_delay(29); // 保持 480μs
- DQ = 1; // DQ返回高電平
- DS18_delay(3); // 等待存在脈沖
- presence = DQ; // 獲得存在信號(hào)
- DS18_delay(25); // 等待時(shí)間隙結(jié)束
- return(presence); // 返回存在信號(hào),0 = 器件存在, 1 = 無(wú)器件
- }
- /****************************** 位寫(xiě)入函數(shù) *******************************
- * 功能:向單總線(xiàn)寫(xiě)入1位值:bitval
- *************************************************************************/
- void write_bit(char bitval)
- {
- DQ = 0; // 將DQ 拉低開(kāi)始寫(xiě)時(shí)間隙
- if(bitval==1)
- DQ =1; // 如果寫(xiě)1,DQ 返回高電平
- DS18_delay(5); // 在時(shí)間隙內(nèi)保持電平值,
- DQ = 1; // DS18_delay函數(shù)每次循環(huán)延時(shí)16μs,因此DS18_delay(5) = 104μs
- }
- /**************************** 字節(jié)寫(xiě)入函數(shù) *******************************
- * 功能:向單總線(xiàn)寫(xiě)入一個(gè)字節(jié)值:val
- *************************************************************************/
- void ds18write_byte(char val)
- {
- uchar i;
- uchar temp;
- for (i=0; i<8; i++)
- { // 寫(xiě)入字節(jié), 每次寫(xiě)入一位
- temp = val>>i;
- temp &= 0x01;
- write_bit(temp);
- }
- DS18_delay(5);
- }
- /**************************** 位讀取函數(shù) ********************************
- * 功能:從單總線(xiàn)上讀取一位信號(hào),所需延時(shí)時(shí)間為15μs,因此無(wú)法調(diào)用前面定義
- * 的DS18_delay()函數(shù),而采用一個(gè)for()循環(huán)來(lái)實(shí)現(xiàn)延時(shí)。
- * ***********************************************************************/
- uchar read_bit(void)
- {
- uchar i;
- DQ = 0; //將DQ 拉低開(kāi)始讀時(shí)間隙
- DQ = 1; // then return high
- for (i=0; i<3; i++); // 延時(shí)15μs
- return(DQ); // 返回 DQ 線(xiàn)上的電平值
- }
- /**************************** 字節(jié)讀取函數(shù) *******************************
- * 功能:從單總線(xiàn)讀取一個(gè)字節(jié)的值
- *************************************************************************/
- uchar DSread_byte(void)
- {
- unsigned char i;
- unsigned char value = 0;
- for (i=0;i<8;i++)
- { // 讀取字節(jié),每次讀取一個(gè)字節(jié)
- if(read_bit())
- value|=0x01<<i; // 然后將其左移
- DS18_delay(6);
- }
- return(value);
- }
- /******************************* 讀取溫度函數(shù) *****************************
- * 功能:如果單總線(xiàn)節(jié)點(diǎn)上只有一個(gè)器件則可以直接調(diào)用本函數(shù)。如果節(jié)點(diǎn)上有多個(gè)器
- * 件,為了避免數(shù)據(jù)沖突,應(yīng)使用Match ROM函數(shù)來(lái)選中特定器件。
- * 注: 本函數(shù)是根據(jù)DS1820的溫度數(shù)據(jù)格式編寫(xiě)的,若用于DS18B20,必須根據(jù)
- * DS18B20的溫度數(shù)據(jù)格式作適當(dāng)修改。
- **************************************************************************/
- uint ReadTemperature(void)
- {
- unsigned char temp_H,temp_L,temp_T;
- ow_reset();
- ds18write_byte(0xCC); // 跳過(guò) ROM
- ds18write_byte(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
- delay(2);
- ow_reset();
- ds18write_byte(0xCC); // 跳過(guò) ROM
- ds18write_byte(0xBE); // 讀暫存器
- temp_L=DSread_byte();
- temp_H=DSread_byte();
- temp_T=temp_H<<4|temp_L>>4;//取整數(shù)
- return temp_T;
- //temp_f = (((int)temp_c)* 9)/5 + 32;
- //return temp_f; 輸出華氏溫度值
- }
- //-------------------------------
- void Timer0Init() //5毫秒@11.0592MHz
- {
- TMOD |= 0x01; //設(shè)置定時(shí)器模式
- TL0 = 0x00; //設(shè)置定時(shí)初始值
- TH0 = 0xEE; //設(shè)置定時(shí)初始值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- EA = 1; //開(kāi)總中斷
- ET0 = 1; //開(kāi)T0中斷
- }
- //*******************主函數(shù)**************************
- void main()
- {
- uchar h;
- LCD_Init(); //LCD初始化函數(shù)
- // ds1302_init(); //DS1302初始化函數(shù)
- write_1602com(0x40);//寫(xiě)1602寄存器命令
- for (h=0;h<24;h++)
- {//向LCD自定義存儲(chǔ)器寫(xiě)入"年"、"月"、"日"
- write_1602dat(character0[h]);
- }
- Timer0Init(); //定時(shí)器初始化函數(shù)
- while(1)
- {
- if(flag)//5毫秒
- {
- flag=0;
- keyscan(); //按鍵掃描函數(shù)
- }
- }
- }
- void Timer0Interrupt() interrupt 1
- {
- static uchar i;
- uchar temp;
- TL0 = 0x00; //設(shè)置定時(shí)初始值
- TH0 = 0xEE; //設(shè)置定時(shí)初始值
- if(mark)
- {
- switch(i)
- {
- case 0: temp=ReadTemperature(); break;//讀溫度
- case 1: TIME[0] = BCD_D(read_1302(0x81)); break;//讀秒
- case 2: TIME[1] = BCD_D(read_1302(0x83)); break;//讀分
- case 3: TIME[2] = BCD_D(read_1302(0x85)); break;//讀時(shí)
- case 4: TIME[3] = BCD_D(read_1302(0x87)); break;//讀日
- case 5: TIME[4] = BCD_D(read_1302(0x89)); break;//讀月
- case 6: TIME[5] = BCD_D(read_1302(0x8b)); break;//讀周
- case 7: TIME[6] = BCD_D(read_1302(0x8d)); break;//讀年
- case 8: write_LCD(er+12,temp); break;//刷新溫度
- case 9: write_LCD(er+8, TIME[0]); break;//刷新秒
- case 10: write_LCD(er+5, TIME[1]); break;//刷新分
- case 11: write_LCD(er+2, TIME[2]); break;//刷新時(shí)
- case 12: write_LCD(yh+8, TIME[3]); break;//刷新日
- case 13: write_LCD(yh+5, TIME[4]); break;//刷新月
- case 14: write_WEE(yh+13,TIME[5]); break;//刷新周
- case 15: write_LCD(yh+2, TIME[6]); break;//刷新年
- default: break;
- }
- i=++i%16;
- }
- flag=1;
- }
復(fù)制代碼
|
|