標題: 求幫忙看看這DS18B20測溫程序有什么問題 [打印本頁]
作者: wang12345678 時間: 2017-6-1 12:03
標題: 求幫忙看看這DS18B20測溫程序有什么問題
4.2.1 DS18B20測溫程序
#include<reg52.h>
#include"lcd1602.h"
#include"adc_stc60s2.h"
#define ucharunsigned char
#defineuint unsigned int
#define jump_ROM0xCC
#define start0x44
#defineread_EEROM 0xBE
sbit DQ =P2^3; //DS18B20數據口
unsigned charTMPH,TMPL;
/********************************************************************
* 名稱 : delay()
* 功能 : 延時,延時時間大概為140US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay_1()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++)
;
}
/********************************************************************
* 名稱 : delay()
* 功能 : 延時函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay(uintN)
{
int i;
for(i=0; i<N; i++)
;
}
/********************************************************************
* 名稱 : Delay_1ms()
* 功能 : 延時子程序,延時時間為 1ms * x
* 輸入 : x (延時一毫秒的個數)
* 輸出 : 無
***********************************************************************/
voidDelay_1ms(uint i)//1ms延時
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/********************************************************************
* 名稱 : Reset()
* 功能 : 復位DS18B20
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
ucharReset(void)
{
uchar deceive_ready;
DQ = 0;
delay(29);
DQ = 1;
delay(3);
deceive_ready = DQ;
delay(25);
return(deceive_ready);
}
/********************************************************************
* 名稱 : read_bit()
* 功能 : 從DS18B20讀一個位值
* 輸入 : 無
* 輸出 : 從DS18B20讀出的一個位值
***********************************************************************/
ucharread_bit(void)
{
uchar i;
DQ = 0;
DQ = 1;
for(i=0; i<3; i++);
return(DQ);
}
/********************************************************************
* 名稱 : write_bit()
* 功能 : 向DS18B20寫一位
* 輸入 : bitval(要對DS18B20寫入的位值)
* 輸出 : 無
***********************************************************************/
voidwrite_bit(uchar bitval)
{
DQ=0;if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}
/********************************************************************
* 名稱 : read_byte()
* 功能 : 從DS18B20讀一個字節
* 輸入 : 無
* 輸出 : 從DS18B20讀到的值
***********************************************************************/
ucharread_byte(void)
{
uchar i,m,receive_data;
m = 1;
receive_data = 0;
for(i=0; i<8; i++)
{
if(read_bit())
{
receive_data = receive_data + (m<< i);
}
delay(6);
}
return(receive_data);
}
/********************************************************************
* 名稱 : write_byte()
* 功能 : 向DS18B20寫一個字節
* 輸入 : val(要對DS18B20寫入的命令值)
* 輸出 : 無
***********************************************************************/
voidwrite_byte(uchar val)
{
uchar i,temp;
for(i=0; i<8; i++)
{
temp = val >> i;
temp = temp & 0x01;
write_bit(temp);
delay(5);
}
}
/********************************************************************
* 名稱 : Main()
* 功能 : 主函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void main()
{
uchar lcd_string[2][33]={0};
uint temp,tmep1;
long delay_time = 5;
init_adc();
L1602_init();
while(1)
{
Reset();
write_byte(jump_ROM);
write_byte(start);
Reset();
write_byte(jump_ROM);
write_byte(read_EEROM);
TMPL = read_byte();
TMPH = read_byte();
temp = TMPL / 16 + TMPH * 16;
lcd_string[0][0] = temp/10%10 + 0x30;
//if (lcd_string[0][0]>=1)
//L1602_string(1,1,"123");
lcd_string[0][1] = temp%10 + 0x30;
if (temp > 30) P3 &= ~(0x01<< 2);
else P3 |= (0x01 << 2);
if (temp < 27) P3 &= ~(0x01<< 3);
else P3 |= (0x01 << 3);
temp1= adc_out();
lcd_string[1][0] = temp1/10%10 + 0x30;
lcd_string[1][1] = temp1%10 + 0x30;
//添加濕度上下限 result為濕度值
if(temp > 55) P3 &= ~(0x01 << 4);
else P3 |= (0x01 << 4);
if (temp < 40) P3 &= ~(0x01<< 5);
else P3 |= (0x01 << 5);
if(delay_time== 0) {
L1602_string(1,1,lcd_string[0]);
L1602_string(2,1,lcd_string[1]);
delay_time = 5;
}
delay_time--;
}
}
4.2.2 A/D轉換程序
#include<STC12c5a60s2/STC_12c5a.H>
#include<intrins.h> //包含_nop_()函數定義的頭文件
#include"adc_stc60s2.h"
voidinit_adc()
{
unsigned long i;
ADC_CONTR|=0x80; //開A/D轉換電源,第一次使用時要打開內部模擬電源
for (i=0;i<10000;i++); //適當延時
P1ASF=0x04; //選擇P1.2作為A/D轉換通道
ADC_CONTR=0xE2;
for (i=0;i<10000;i++); //適當延時
}
ucharadc_out()
{
uchar result;
uchar status;
ADC_CONTR|=0x08; //啟動 A/D 轉換
status=0;
while(status==0) //等待A/D轉換結束
{
status=ADC_CONTR&0x10;
}
ADC_CONTR&=0xE7; //將ADC_FLAG清0
result=ADC_RES; //保存A/D轉換結果
return result;
}
4.2.3 1602顯示程序
#include<reg52.h>
#include"lcd1602.h"
/********************************************************************
* 名稱 : delay()
* 功能 : 延時,延時時間大概為140US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
voiddelay()
{
int i,j;
for(i=0; i<=100; i++)
for(j=0; j<=20; j++)
;
}
/********************************************************************
* 名稱 : enable(uchar del)
* 功能 : 1602命令函數
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
voidenable(uchar del)
{
DATA = del;
RS = 0;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/********************************************************************
* 名稱 : write(uchar del)
* 功能 : 1602寫數據函數
* 輸入 : 需要寫入1602的數據
* 輸出 : 無
***********************************************************************/
voidwrite(uchar del)
{
DATA = del;
RS = 1;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/********************************************************************
* 名稱 : L1602_init()
* 功能 : 1602初始化,請參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
voidL1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}
/********************************************************************
* 名稱 : L1602_char(ucharhang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
voidL1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
/********************************************************************
* 名稱 : L1602_string(ucharhang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
voidL1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
-
-
Sheet1.pdf
2017-6-1 12:08 上傳
點擊文件名下載附件
24.84 KB, 下載次數: 5
電路圖
作者: 小超人 時間: 2017-6-1 18:07
ds18b20不需額外的ad轉換 輸出的就是數字量
作者: 小超人 時間: 2017-6-1 18:15
這是我自己寫的一個12864顯示ds18b20 的程序 可以參考一下
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds = P2^2;
sbit beep = P2^3;
sbit RS=P3^5;
sbit LCDE=P3^4;
sbit RW=P3^6;
sbit PSB=P3^7;
char code t4[]={"0123456789"};
char code t2[]={"當前溫度:"};
bit flag;
uint temp;//溫度
void TempDelay(uchar us)
{
while(us--); //6.51us
}
void delay(int z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=115;y>0;y--);
}
void xieml(unsigned char ml)
{
RS=0;
RW=0;
LCDE=0;
P0=ml;
delay(5);
LCDE=1;
delay(5);
LCDE=0;
}
void xieshu(unsigned char shu)
{
RS=1;
RW=0;
LCDE=0;
P0=shu;
delay(5);
LCDE=1;
delay(5);
LCDE=0;
}
void init()
{
PSB=1;
xieml(0x30);
delay(5);
xieml(0x0C);
delay(5);
}
void display(uint temp)
{
uchar bai,sh,ge,i;
bai=temp/100;
sh=temp%100/10;
ge=temp%100%10;
init();
xieml(0x90);
xieshu(t4[bai]);
xieshu(t4[sh]);
xieshu('.');
xieshu(t4[ge]);
i=0;
xieml(0x80);
while(t2[i]!='\0')
{
xieshu(t2[i]);
i++;
}
}
void ds_reset()
{
ds=1;
_nop_();
ds=0;
TempDelay(80);//520us
ds=1;
TempDelay(5);
if(ds==0)
flag=1;
else
flag=0;
TempDelay(20);
ds=1;
}
bit ds_read_bit()
{
bit dat;
ds=0;
_nop_();
_nop_();
ds=1;
_nop_();
dat=ds;
TempDelay(12);
return dat;
}
uchar ds_read_byte()
{
uchar i,j,value;
for(i=0;i<8;i++)
{
j=ds_read_bit();
value=(j<<7)|(value>>1);
}
return value;
}
void ds_write_byte(uchar dat)
{
uchar i,onebit;
for(i=0;i<8;i++)
{
onebit=dat&0x01;
if(onebit) //寫1
{
ds=0;
TempDelay(1);
ds=1;
_nop_();
}
else //寫0
{
ds=0;
TempDelay(11);
ds=1;
_nop_();
}
dat>>=1;
}
}
void ds_change()
{
ds_reset();
ds_write_byte(0xcc);
ds_write_byte(0x44);
}
uint get_temperature()
{
uchar a,b;
float temperature;
ds_reset();
ds_write_byte(0xcc);
ds_write_byte(0xbe);
a=ds_read_byte();
b=ds_read_byte();
temp=b;
temp<<=8;
temp|=a;
temperature=temp*0.0625;
temp=temperature*10+0.5;
return temp;
}
void main()
{
ds_change();
delay(1000);
while(1)
{
display(get_temperature());
ds_change();
if(get_temperature()>350)//35度蜂鳴器發聲
beep=0;
else
beep=1;
}
}
作者: 我拿真情去喂狗 時間: 2017-6-1 19:10
看不出來啊
作者: shuisheng60 時間: 2019-2-3 20:54
估計是樓主直接就將代碼復制在一起沒分開多文件產生的結果
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |