你這樣問很難解答,給你一個成熟的程序和仿真圖參考
無標題.jpg (259.98 KB, 下載次數: 48)
下載附件
2019-3-6 15:27 上傳
- /*-----------------------------------------------
- 名稱:DS18b20測溫程序 數碼管顯示(-55~128度)
- ------------------------------------------------*/
- #include <reg51.H>
- #define uchar unsigned char
- #define uint unsigned int
- #define DataPort P0 //定義數據端口
- sbit LATCH1=P2^6;//定義鎖存使能端口 段鎖存
- sbit LATCH2=P2^7;// 位鎖存
- sbit DQ=P2^2; //DS18B20 端口
- /************定義全局變量*************/
- uchar code dofly_DuanMa[]={//共陰數碼管段碼"0~f-."
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
- 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};
- uchar code dofly_WeiMa[]={//共陰數碼管8位位碼
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
- uchar TempData[6]; //存儲顯示值的全局變量
- bit ReadTempFlag; //讀時間標志
- /*------------------------------------------------
- 函數聲明
- ------------------------------------------------*/
- void WriteOneChar(uchar dat);//寫入DS18B20一個字節
- uchar ReadOneChar();//讀取DS18B20一個字節
- uint ReadTemperature();//讀取DS18B20溫度值
- void Init_DS18B20();//初始化DS18B20
- void Display(); //數碼管顯示函數
- void Init_Timer0(); //定時器初始化
- void delay(uchar i);//1ms延時函數
- /*------------------------------------------------
- 主函數
- ------------------------------------------------*/
- void main()
- {
- uint temp;
- long tempM;
- bit negative;//負數標志
- uchar TempH,TempL,TempK;
- Init_Timer0();
- TempData[5]=0x39; //顯示C
- while(1) //主循環
- {
- if(ReadTempFlag==1)//定時標志
- {
- ReadTempFlag=0;
- temp=ReadTemperature();//讀取溫度
- if(temp&0x8000)
- {
- negative=1; //負號標志
- temp=~temp; //取反加1
- temp +=1;
- }
- else negative=0; //正數
- tempM=temp*0.0625*100; //換算為10進制溫度值再放大100倍
- TempH=tempM/100; //分解出整數值
- TempL=tempM%100; //分解出小數值
- TempL=(TempL+TempK)/2+0.5;//小數取兩次平均值加四舍五入
- TempK=TempL;
-
- if(negative==1)
- TempData[0]=0x40;//顯示負號
- else if(TempH/100==0)//小于100
- TempData[0]=0; //百位消隱
- else
- TempData[0]=dofly_DuanMa[TempH/100]; //顯示百位溫度
-
- if((TempH/100==0)&&((TempH%100)/10==0))
- TempData[1]=0; //十位消隱
- else
- TempData[1]=dofly_DuanMa[(TempH%100)/10]; //顯示十位溫度
- TempData[2]=dofly_DuanMa[(TempH%100)%10]|0x80;//顯示個位溫度,帶小數點
- TempData[3]=dofly_DuanMa[TempL/10]; //顯示溫度小數1位
- TempData[4]=dofly_DuanMa[TempL%10]; //顯示溫度小數2位
- }
- }
- }
- /**********1ms延時************/
- void delay(uchar i)
- {
- uchar j, k;
- for(j=i;j>0;j--)
- for(k=120;k>0;k--);
- }
- /*****初始化DS18B20*****/
- void Init_DS18B20()
- {
- uint i;
- DQ=0;
- i = 103;
- while(i>0)
- i--;
- DQ=1;
- i = 4;
- while(i>0)
- i--;
- }
- /*****讀一個字節*****/
- uchar ReadOneChar()
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- delay(1);
- }
- return(dat);
- }
- /*****寫一個字節*****/
- void WriteOneChar(uchar dat)
- {
- uchar i=0;
- for(i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay(1);
- DQ = 1;
- dat>>=1;
- }
- delay(1);
- }
- /*****讀取溫度*****/
- uint ReadTemperature()
- {
- uchar a,b;
- uint tt;
- Init_DS18B20(); //初始化DS18B20
- delay(1); //延時1ms
- WriteOneChar(0xcc); //寫入跳過序列號命令字
- WriteOneChar(0x44); //寫入溫度轉換命令字
- delay(1); //延時1ms //@12.000MHz //轉換需要一點時間,延時
- Init_DS18B20(); //初始化DS18B20
- delay(1); //延時1ms
- WriteOneChar(0xcc); //寫入跳過序列號命令字
- WriteOneChar(0xbe); //寫入讀取數據令字
- a=ReadOneChar(); //讀出溫度的低位LSB
- b=ReadOneChar(); //讀出溫度的高位MSB
- tt=(b<<8)|a;
- return tt;
- }
- /*------------------------------------------------
- 6位動態數碼管顯示函數
- ------------------------------------------------*/
- void Display()
- {
- static uchar i=0;
- DataPort=0; //清空數據,消隱
- LATCH1=1; //段鎖存
- LATCH1=0;
-
- DataPort=dofly_WeiMa[i]; //取位碼
- LATCH2=1; //位鎖存
- LATCH2=0;
-
- DataPort=TempData[i]; //取顯示數據,段碼
- LATCH1=1; //段鎖存
- LATCH1=0;
-
- i++;
- i%=6;
- }
- /*------------------------------------------------
- 定時器初始化子程序
- ------------------------------------------------*/
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定時器
- TH0=(65536-2000)/256; //給定初值
- TL0=(65536-2000)%256;
- EA=1; //總中斷打開
- ET0=1; //定時器中斷打開
- TR0=1; //定時器開關打開
- }
- /*------------------------------------------------
- 定時器中斷子程序
- ------------------------------------------------*/
- void Timer0_isr(void) interrupt 1
- {
- static uint num;
- TH0=(65536-2000)/256; //重新賦值 2ms
- TL0=(65536-2000)%256;
-
- Display(); // 調用數碼管掃描
- num++;
- if(num>=250) //500ms
- {
- num=0;
- ReadTempFlag=1; //讀標志位置1
- }
- }
復制代碼
|