❶ 基於單片機的電子溫度計設計
看看這個吧,是個通過溫度感測器實現對電風扇的智能控制的程序
溫度感測器是ds18b20
不懂的地方m我 qq 296264785
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P3^4;
sbit ka=P3^0;
sbit guan=P3^1;
uchar wen[]={0x00,0x00};
uchar code tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar code anma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar ,shi,ge,xiao,wen;
//延時子程序
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay1(uint a)
{
while(--a);
}
uchar init_18b20() //18b20初始化
{
uchar b;
DQ=1;
delay1(8);
DQ=0;
delay1(90);
DQ=1;
delay1(8);
b=DQ;
delay1(100);
DQ=1;
return b;
}
uchar ()//讀位元組
{
uchar i,dat=0;
DQ=1;_nop_();
for(i=0;i<8;i++)
{
DQ=0;
dat >>=1;
DQ=1;
_nop_(); _nop_();
if(DQ)dat|=0x80;
delay1(30);
DQ=1;
}
return dat;
}
void xie(uchar da)//寫位元組
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=da & 0x01;
delay1(5);
DQ=1;
da>>=1;
}
}
void wen()
{
while(init_18b20()); //DQ=1;等待
xie(0xcc);
xie(0x44);
init_18b20();
xie(0xcc);
xie(0xbe);
wen[0]=();
wen[1]=();
}
void xshi()
{
uchar i;
xiao=tab[wen[0] & 0x0f];
wen=((wen[0] & 0xf0)>>4) | ((wen[1] & 0x07)<<4);
=wen/100;
shi=wen%100/10;
ge=wen%10;
for(i=0;i<15;i++)
{
P1=0xfe;
P2=anma[xiao];
delay(5);
P1=0xfd;
P2=anma[ge];
delay(5);
P1=0xfb;
P2=anma[shi];
delay(5);
P1=0xf7;
P2=anma[];
delay(5);
}
}
void main()
{
ka=0;
guan=0;
wen();
delay(10);
while(1)
{
wen();
xshi();
if(wen>=25) //溫度高於25度 開風扇
{
ka=1;
guan=0;
}
else
{
ka=0;
guan=1;
}
}
}
❷ 基於單片機的數字溫度計設計要做成實物所需要的硬體有什麼
你搜一下單片機最小系統,按上面所列出的東西焊接起來,然後就是溫度感測器,可以選擇樓上的ds18b20,這個挺好用,直接接io口加個上拉電阻就行了,當然也可以用熱敏電阻,這個需要ad轉換.adc0804就夠了.然後就是顯示 ,除了樓上的數碼管之外還需要數碼管驅動,用三極體8050就行了,數碼管有共陽和共陰極,選的時候要注意.除了單片機最小系統外其他電路都相當簡單,用一般地萬用板就可以完成,就是外觀不太好看而以,單片機最小系統網路一搜一大把圖,直接按圖上的焊接就行了,也許你還需要一個復位按鈕,當然直接上電復位也可以,有段時間沒有接觸過單片機了,能想到的就這些了,希望對你有幫助
❸ 求求基於51單片機的數字溫度計設計 單片機AT89C51 測溫感測器使DS18B20 圖在下面!只要c語言程序
#include <reg51.H>
#define uint unsigned int
#define uchar unsigned char
#define Alarm_Value 30 //溫度報警值
sbit rs = P2^0;
sbit lcdcs = P2^2;
sbit buzzer = P3^4; //蜂鳴器報警
sbit OUT = P3^5; //光的檢測
sbit DQ = P3^7; //溫度傳送數據IO口
uchar TempBuffer[8];
uint temp_value; //溫度值
light_flag=1; //標志位
uchar value1[]={"TempShow:"};
uchar value2[]={"LightY/N:"};
uchar value3[]={"YES"};
uchar value4[]={"NO "};
/*******************************ds18b20子程序*******/
/***********ds18b20延遲子函數(晶振12MHz )*******/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函數***********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1;
delay_18B20(8);
DQ = 0;
delay_18B20(80);
DQ = 1;
delay_18B20(14);
x=DQ;
delay_18B20(20);
}
/***********ds18b20讀一個位元組**********************/
unsigned char 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);
}
/*************ds18b20寫一個位元組********************/
void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************讀取ds18b20當前溫度****************/
void ReadTemp(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;
float tt;
Init_DS18B20();
WriteOneChar(0xCC); //Skip ROM command
WriteOneChar(0x44); //啟動DS18B20進行溫度轉換
delay_18B20(100);
Init_DS18B20();
WriteOneChar(0xCC); //Skip ROM command
WriteOneChar(0xBE); // 讀暫存器9個位元組內容
delay_18B20(100);
a=ReadOneChar(); //讀溫度值低位
b=ReadOneChar(); //讀溫度值高位
temp_value=b;
temp_value<<=8;
temp_value=temp_value|a;
tt=temp_value*0.0625;
temp_value=tt*100+0.5; /*經典:處理保留幾位小數(此列為2位);*/
}
/*******************溫度值轉換為字元串**************/
void temp_to_str()
{
TempBuffer[0]=temp_value/1000+'0'; //十位
TempBuffer[1]=temp_value%1000/100+'0'; //個位
TempBuffer[2]='.'; //小數點
TempBuffer[3]=temp_value%1000%100/10+'0'; //小數點後一位
TempBuffer[4]=temp_value%1000%100%10+'0'; //小數點後二位
TempBuffer[5]=0xdf; //溫度符號
TempBuffer[6]='C';
TempBuffer[7]='\0';
}
void delay(uint ms)
{
uint i,j;
for (j=0;j<ms;j++)
for (i=0;i<120;i++);
}
Check_light()
{
if(out==0)
{
light_flag=1;
}
else
{
light_flag=0;
}
}
/**********1602顯示開始 ***************************/
void write_command(uchar command)
{
rs=0;
P0=command;
lcdcs=1;
lcdcs=0;
}
void write_data(uchar data0)
{
rs=1;
P0=data0;
lcdcs=1;
lcdcs=0;
}
void init_1602()
{
delay(15);
write_command(0x38);
delay(5);
write_command(0x0c);
delay(5);
write_command(0x06);
delay(5);
}
/*****************1602顯示結束 *********************
void show()
{
uchar i;
init_1602(); //初始化lcd
write_command(0x80); //液晶顯示位置第一行第一個
Init_DS18B20();
ReadTemp();
temp_to_str();
for (i=0;i<sizeof(value1)-1;i++)
{
write_data(value1[i]);
delay(5);
}
for (i=0;i<sizeof(TempBuffer)-1;i++)
{
write_data(TempBuffer[i]);
delay(5);
}
write_command(0x80+0x40); //液晶顯示位置 第二行第一個
delay(100);
for (i=0;i<sizeof(value2)-1;i++)
{
write_data(value2[i]);
delay(5);
}
if(light_flag== 1 )
{
for(i=0;i<sizeof(value3)-1;i++)
{
write_data(value3[i]);
delay(5);
}
}
else
{
for(i=0;i<sizeof(value4)-1;i++)
{
write_data(value4[i]);
delay(5);
}
}
}
void Temperature_Alarm() //溫度報警
{
if(temp_value/100>=Alarm_Value) //取temp_value前兩位
{
buzzer = 0; //不要用埠賦值
}
else
{
buzzer = 1;
}
}
/*****************主函數******************/
void main()
{
while(1)
{
show();
Temperature_Alarm();
Check_light();
}
}
我做的液晶是1602的
❹ 單片機數字溫度計設計用C語言寫程序
#include <reg51.h>
#define uchar unsigned char
sbit BEEP=P3^7;
//接控制繼電器
sbit DQ = P3^6;
//接溫度感測器18B20
uchar t[2],number=0,*pt;
//溫度值
uchar TempBuffer1[4]={0,0,0,0};
uchar Tmax=50,Tmin=10;
uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7};
uchar currtemp;
void t0isr() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
P2=1<<number;
if(number==2)P0=distab[TempBuffer1[0]]&0x7f;
else P0=distab[TempBuffer1[0]];
number++;
if(number>3)number=0;
}
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函數**********************/
void Init_DS18B20(void)
{
bit x=0;
do{
DQ=1;
delay_18B20(8);
DQ = 0; //單片機將DQ拉低
delay_18B20(90); //精確延時 大於 480us
DQ = 1; //拉高匯流排
delay_18B20(14);
x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗,繼續初始化
}while(x);
delay_18B20(20);
}
/***********ds18b20讀一個位元組**************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20寫一個位元組****************/
void 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;
}
}
/**************讀取ds18b20當前溫度************/
unsigned char *ReadTemperature(unsigned char rs)
{
unsigned char tt[2];
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0x44);
//啟動溫度轉換
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC);
//跳過讀序號列號的操作
WriteOneChar(0xBE);
//讀取溫度寄存器等(共可讀9個寄存器)前兩個就是溫度
tt[0]=ReadOneChar(); //讀取溫度值低位
tt[1]=ReadOneChar(); //讀取溫度值高位
return(tt);
}
void covert1(void)
//將溫度轉換為LED顯示的數據
{
uchar x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]&0x080) //判斷正負溫度
{
TempBuffer1[0]=0x0c;
//c代表負
t[1]=~t[1];
/*下面幾句把負數的補碼*/
t[0]=~t[0];
/*換算成絕對值*********/
x=t[0]+1;
t[0]=x;
if(x==0x00)t[1]++;
}
else TempBuffer1[0]=0x0a;
//A代表正
t[1]<<=4;
//將高位元組左移4位
t[1]=t[1]&0xf0;
x=t[0];
//將t[0]暫存到X,因為取小數部分還要用到它
x>>=4;
//右移4位
x=x&0x0f;
//和前面兩句就是取出t[0]的高四位
y=t[1]|x;
//將高低位元組的有效值的整數部分拼成一個位元組
TempBuffer1[1]=(y%100)/10;
TempBuffer1[2]=(y%100)%10;
t[0]=t[0]&0x0f;
//小數部分
TempBuffer1[3]=t[0]*10/16;
if(currtemp<Tmin || currtemp>Tmax)BEEP=1;
else BEEP=0;
}
void convert(char tmp)
{
uchar a;
if(tmp<0)
{
TempBuffer1[0]=0x0c;
a=~tmp+1;
}
else
{
TempBuffer1[0]=0x0a;
a=tmp;
}
TempBuffer1[1]=(a%100)/10;
TempBuffer1[2]=(a%100)%10;
}
main()
{
TMOD=0x01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
out=1;
flag=0;
ReadTemperature(0x3f);
delay_18B20(50000);
//延時等待18B20數據穩定
while(1)
{
pt=ReadTemperature(0x7f); //讀取溫度,溫度值存放在一個兩個位元組的數組中
if(dismod==0)covert1();
delay_18B20(30000);
}
}
❺ 基於單片機的數字溫度計設計用C語言寫程序
//------------------------------------------------------------------
//DS18B20溫度感測器輸出顯示,運行本例時,外界溫度將顯示在1602LCD上
//------------------------------------------------------------------
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
sbit DQ=P2^2;
sbit la=P2^6; //定義鎖存器鎖存端
sbit wela=P2^7;
sbit rs=P3^5; //定義1602液晶RS端
sbit lcden=P3^4;//定義1602液晶LCDEN端
sbit s1=P3^0; //定義按鍵--功能鍵
sbit s2=P3^1; //定義按鍵--增加鍵
sbit s3=P3^2; //定義按鍵--減小鍵
sbit s4=P3^6;//鬧鍾查看鍵
sbit rd=P3^7;
sbit beep=P2^3; //定義蜂鳴器端
uchar code Temp_Disp_Title[]={" Current Temp : "};
uchar Current_Temp_Display_Buffer[]={" TEMP: "};
uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};
uchar Alarm_HI_LO_STR[]={"Hi: Lo: "};
uchar temp_data[2]={0x00,0x00};
uchar temp_alarm[2]={0x00,0x00};
uchar display[5]={0x00,0x00,0x00,0x00,0x00};
uchar display1[3]={0x00,0x00,0x00};
uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar CurrentT=0; //當前讀取的溫度整數部分
uchar Temp_Value[]={0x00,0x00}; //從DS18B20讀取的溫度值
uchar Display_Digit[]={0,0,0,0}; //待顯示的各溫度數位
bit DS18B20_IS_OK=1;//感測器正常標志
//-------------------------------------
//延時1
//-------------------------------------
void delay1(uint x)
{
uchar i;
while(x--) for(i=0;i<200;i++);
}
//-------------------------------------
//延時2
//-------------------------------------
void Delay(uint x)
{
while(x--);
}
//------------------------------------
//忙檢查
//------------------------------------
void write_com(uchar com)//液晶寫命令函數
{
rs=0;
lcden=0;
P0=com;
delay1(5);
lcden=1;
delay1(5);
lcden=0;
}
void Write_LCD_Data(uchar date)//液晶寫數據函數
{
rs=1;
lcden=0;
P0=date;
delay1(5);
lcden=1;
delay1(5);
lcden=0;
}
//-----------------------------
//設置LCD顯示位置
//---------------------------------
void Set_Disp_Pos(uchar Pos)
{
write_com(Pos|0x80);
}
//-----------------------------
//LCD初始化
//---------------------------------
void Initialize_LCD()
{
uchar num;
rd=0; //軟體將矩陣按鍵第4列一端置低用以分解出獨立按鍵
la=0;//關閉兩鎖存器鎖存端,防止操作液晶時數碼管會出亂碼
wela=0;
lcden=0;
write_com(0x38);//初始化1602液晶
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);//設置顯示初始坐標
for(num=0;num<14;num++)//顯示年月日星期
{
Write_LCD_Data(Temp_Disp_Title[num]);
delay1(5);
}
}
//-------------------------------------
//函數功能:初始化DS18B20
//出口參數:status---DS18B20是否復位成功的標志
//-------------------------------------
uchar Init_DS18B20()
{
uchar status; //儲存DS18B20是否存在的標志,status=0,表示存在;status=1,表示不存在
DQ=1;Delay(8); //先將數據線拉高 //略微延時約6微秒
DQ=0;Delay(90); //再將數據線從高拉低,要求保持480~960us
//略微延時約600微秒 以向DS18B20發出一持續480~960us的低電平復位脈沖
DQ=1;Delay(8); //釋放數據線(將數據線拉高) //延時約30us(釋放匯流排後需等待15~60us讓DS18B20輸出存在脈沖)
status=DQ;Delay(100); //讓單片機檢測是否輸出了存在脈沖(DQ=0表示存在) //延時足夠長時間,等待存在脈沖輸出完畢
DQ=1; // 將數據線拉高
return status; //返回檢測成功標志
}
//-------------------------------------
//函數功能:讀一位元組
//出口參數:dat---讀出的數據
//-------------------------------------
uchar ReadOneByte()
{
uchar i,dat=0;
DQ=1;_nop_(); // 先將數據線拉高 //等待一個機器周期
for (i=0;i<8;i++)
{
DQ=0; //單片機從DS18B20讀書據時,將數據線從高拉低即啟動讀時序
dat>>=1;
_nop_(); //等待一個機器周期
DQ=1; //將數據線"人為"拉高,為單片機檢測DS18B20的輸出電平作準備
_nop_();_nop_(); //延時約6us,使主機在15us內采樣
if (DQ) dat|=0x80; //如果讀到的數據是1,則將1存入dat,如果是0則保持原值不變
Delay(30); //延時3us,兩個讀時序之間必須有大於1us的恢復期
DQ=1; // 將數據線拉高,為讀下一位數據做准備
}
return dat;
}
//-------------------------------------
//函數功能:寫一位元組
//入口參數:dat---待寫入的數據
//-------------------------------------
void WriteOneByte(uchar dat)
{
uchar i;
for (i=0;i<8;i++)
{
DQ=0; //將數據線從高拉低時即啟動寫時序
DQ=dat & 0x01; //利用與運算取出要寫的某位二進制數據,
//並將其送到數據線上等待DS18B20采樣
Delay(5); //延時約30us,DS18B20在拉低後的約15~60us期間從數據線上采樣
DQ=1; //釋放數據線
dat>>=1; //將dat中的各二進制位數據右移1位
}
}
//-------------------------------------
//函數功能:讀取溫度值
//出入口參數:無
//-------------------------------------
void Read_Temperature()
{
if(Init_DS18B20() == 1) //DS18B20故障
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xCC); // 跳過讀序號列號的操作
WriteOneByte(0x44); // 啟動溫度轉換
Init_DS18B20(); //將DS18B20初始化
WriteOneByte(0xCC); //跳過讀序號列號的操作
WriteOneByte(0xBE); //讀取溫度寄存器,前兩個分別是溫度的低位和高位
Temp_Value[0]=ReadOneByte(); //溫度低8位
Temp_Value[1]=ReadOneByte(); //溫度高8位
DS18B20_IS_OK=1;
}
}
//-------------------------------------
//函數功能:在LCD上顯示當前溫度
//入口參數:
//-------------------------------------
void Display_Temperature()
{
uchar i;
//延時值與負數標識
uchar t=150,ng=0;
//高5位全為1(0xF8)則為負數,為負數時取反加1,並設置負數標示
if ((Temp_Value[1] & 0xF8)==0xF8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00) Temp_Value[1]++; //加1後如果低位元組為00表示有進位,進位位再加到高位元組上
ng=1; //負數標示置1
}
Display_Digit[0]=df_Table[Temp_Value[0] & 0x0F]; //查表得到溫度小數部分
//獲取溫度整數部分(高位元組的低3位與低位元組中的高4位,無符號)
CurrentT=((Temp_Value[0] & 0xF0)>>4)|((Temp_Value[1] & 0x07)<<4);
//將整數部分分解為3位待顯示數字
Display_Digit[3]=CurrentT/100; //百位 digit[CurrentT/100];
Display_Digit[2]=CurrentT%100/10; //十位
Display_Digit[1]=CurrentT%10; //個位
//刷新LCD顯示緩沖
Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';//先將'0'轉換成整數48,然後與前面數字相加,得到相應數字的ASCII字元
Current_Temp_Display_Buffer[10]='.';
Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0'; //個位
Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0'; //十位
Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0'; //百位
//高位為0時不顯示
if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' ';
//高位為0且次高位為0時,次高位不顯示
if(Display_Digit[2]==0 && Display_Digit[3]==0)
Current_Temp_Display_Buffer[8]=' ';
//負數符號顯示在恰當位置
if(ng)
{
if (Current_Temp_Display_Buffer[8]==' ')
Current_Temp_Display_Buffer[8]='-';
else if(Current_Temp_Display_Buffer[7]==' ')
Current_Temp_Display_Buffer[7]='-';
else
Current_Temp_Display_Buffer[6]='-';
}
//在第一行顯示標題
Set_Disp_Pos(0x00);
for(i=0;i<16;i++)
{
Write_LCD_Data(Temp_Disp_Title[i]);
}
Set_Disp_Pos(0x40); //在第二行顯示當前溫度
for(i=0;i<16;i++)
{
Write_LCD_Data(Current_Temp_Display_Buffer[i]);
}
//顯示溫度符號
// Set_Disp_Pos(0x4D);Write_LCD_Data(0x00);
Set_Disp_Pos(0x4D);Write_LCD_Data(0xdf);
Set_Disp_Pos(0x4E); Write_LCD_Data('C');
}
//-------------------------------------
//函數功能:主函數
//入口參數:
//-------------------------------------
void main()
{
Initialize_LCD();
Read_Temperature();
Delay(50000);
Delay(50000);
while (1)
{
Read_Temperature();
if (DS18B20_IS_OK) Display_Temperature();
delay1(100);
}
}
❻ 8051單片機數字溫度計單片機的設計
-55~125度,你自己修改:
;***************WAVE-E6000/T**********************
;*MCU: AT892051 *
;*MCU-crystal: 12M *
;*Version: 01 *
;*Last Updata: 2007-5-27 *
;*Author: zhaojun *
;*Description: *
;DS18B20的讀寫程序,數據腳P3.4 *
;溫度感測器18B20匯編程序,採用器件默認的12位轉化 *
;最大轉化時間750微秒,顯示溫度-55到+125度,顯示精度*
;為0.1度,顯示採用4位LED共陽顯示測溫值 *
;*************************************************
;單片機內存分配申明!
;*************************************************
TEMPER_L EQU 40H ;用於保存讀出溫度的低8位
TEMPER_H EQU 41H ;用於保存讀出溫度的高8位
FLAG1 EQU 38H ;是否檢測到DS18B20標志位
SEC EQU 20H ;數碼管個位數存放內存位置
MIN EQU 21H ;數碼管十位數存放內存位置
TEMPL EQU 30H ;用於保存讀出溫度的低8位
TEMPH EQU 31H ;用於保存讀出溫度的高8位
TEMPHC EQU 32H ;溫度轉換寄存器低8位
TEMPLC EQU 33H ;溫度轉換寄存器高8位
BUF1 EQU 34H ;顯示緩沖寄存器小數位
BUF2 EQU 35H ;顯示緩沖寄存器個數位
BUF3 EQU 36H ;顯示緩沖寄存器十數位
BUF4 EQU 37H ;顯示緩沖寄存器百數位
TEMPDIN BIT P3.4 ;數據腳定義
DIN BIT P1.7 ;小數點控制
;**********************************************
ORG 0000H ;主程序入口地址
AJMP MAIN ;轉主程序
ORG 0003H ;外中斷0中斷入口
DB 00H,00H,00H,00H,00H,00H,00H;
RETI ;跳至INTEX0執行中斷服務程序
ORG 000BH ;定時器T0中斷入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至定時器T0執行中斷服務程序
ORG 0013H ;外中斷1中斷入口
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至INTEX1執行中斷服務程序
ORG 001BH ;定時器T1中斷入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中斷返回(不開中斷)
ORG 0023H ;串列口中斷入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中斷返回(不開中斷)
;**********************************************
;兩位數碼管來顯示溫度,顯示範圍00到99度,顯示精度為1度
;因為12位轉化時每一位的精度為0.0625度,我們不要求顯示小數所以可以拋棄29H的低4位
;將28H中的低4位移入29H中的高4位,這樣獲得一個新位元組,這個位元組就是實際測量獲得的溫度
;無需乘於0.0625系數
;**********************************************
MAIN:
MOV SP, #50H ;
MOV P1, #0FFH ;
LPTEMP:
LCALL GET_TEMPER ;調用讀溫度子程序
LCALL CONVTEMP ;溫度BCD碼計算處理子程序
LCALL DISPBCD ;顯示區BCD碼溫度值刷新子程序
;*************************************
LCALL DISPLAY ;調用數碼管顯示子程序
;*************************************
;CPL P3.0 ;
AJMP LPTEMP ;
;*************************************
; 這是DS18B20復位初始化子程序
;*************************************
INIT_1820:
SETB TEMPDIN
NOP
CLR TEMPDIN ;主機發出延時537微秒的復位低脈沖
MOV R1,#3
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB TEMPDIN ;然後拉高數據線
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB TEMPDIN,TSR3 ;等待DS18B20回應
DJNZ R0,TSR2
LJMP TSR4 ;延時
TSR3:
SETB FLAG1 ;置標志位,表示DS1820存在
;CLR P3.7 ;檢查到DS18B20就點亮P3.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ;清標志位,表示DS1820不存在
;CLR P3.1
LJMP TSR7
TSR5: MOV R0,#117
TSR6: DJNZ R0,TSR6 ;時序要求延時一段時間
TSR7: SETB TEMPDIN ;
RET
;****************************************
; 讀出轉換後的溫度值
;****************************************
GET_TEMPER:
SETB TEMPDIN ;
LCALL INIT_1820 ;先復位DS18B20
JB FLAG1,TSS2
RET ;判斷DS1820是否存在?若DS18B20不存在則返回
TSS2:
;CLR P3.3 ;DS18B20已經被檢測到!!
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE_1820
MOV A,#44H ;發出溫度轉換命令
LCALL WRITE_1820
;*****************************************
;這里通過調用顯示子程序實現延時一段時間,等待AD轉換結束,12位的話750微秒
;*****************************************
LCALL DISPLAY
;*****************************************
LCALL INIT_1820 ;准備讀溫度前先復位
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;發出讀溫度命令
LCALL WRITE_1820
LCALL READ_18200 ;將讀出的溫度數據保存到35H/36H
RET
;*******************************************
;寫DS18B20的子程序(有具體的時序要求)
;*******************************************
WRITE_1820:
MOV R2,#8 ;一共8位數據
CLR C ;
WR1:
CLR TEMPDIN ;
MOV R3,#6
DJNZ R3,$
RRC A
MOV TEMPDIN,C ;
MOV R3,#23
DJNZ R3,$
SETB TEMPDIN ;
NOP
DJNZ R2,WR1 ;
SETB TEMPDIN ;
RET
;*************************************
;處理溫度BCD碼子程序
;*************************************
CONVTEMP: MOV A,TEMPH ;
ANL A,#80H ;
JZ TEMPC1 ; 判斷溫度是否在零下?
CLR C ; 溫度值補碼 變成原碼
MOV A,TEMPL ;
CPL A
ADD A,#01H ;
MOV TEMPL,A ;
MOV A, TEMPH ; -
CPL A ;
ADDC A,#00H ;
MOV TEMPH,A ; TEMPHC HI=符號位
MOV TEMPHC,#0BH ; 置"-"標志
SJMP TEMPC11 ;
TEMPC1: MOV TEMPHC,#0AH ; 置"+"標志
;**************************************
TEMPC11: MOV A,TEMPHC ; 計算小數位溫度BCD值
SWAP A
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ; 乘0.0625
MOV DPTR,#TEMPDOTTAB ;
MOVC A,@A+DPTR ;
MOV TEMPLC,A ; TEMPLC LOW= 小數部分 BCD
;**************************************
MOV A,TEMPL ; 計算整數位溫度BCD值
ANL A,#0F0H ;
SWAP A ;
MOV TEMPL,A ;
MOV A,TEMPH ;
ANL A,#0FH ;
SWAP A ;
ORL A,TEMPL ;
MOV TEMPER_L ,A ;
LCALL HEX2BCD1 ; 調用單位元組十六進制轉BCD子程序
;************************************
MOV TEMPL,A ;
ANL A,#0F0H ;
SWAP A ;
ORL A,TEMPHC ; TEMPHC LOW = 十位數 BCD
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ;
SWAP A ; TEMPLC HI = 個位數 BCD
ORL A,TEMPLC ;
MOV TEMPLC,A ;
MOV A,R7 ;
JZ TEMPOUT ;
ANL A,#0FH ;
SWAP A ;
MOV R7,A ;
MOV A,TEMPHC ; TEMPHC HI = 百位數 BCD
ANL A,#0FH ;
ORL A,R7 ;
MOV TEMPHC,A ;
TEMPOUT: RET ;
;**************************************
;小數部分分碼表
;**************************************
TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H ;
;**************************************
;顯示區 BCD 碼溫度值刷新子程序
;**************************************
DISPBCD: MOV A,TEMPLC ; 溫度數據移入顯示寄存器
ANL A,#0FH ;
MOV BUF1,A ; 顯示小數
MOV A,TEMPLC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF2,A ; 顯示個位
MOV A,TEMPHC ;
ANL A,#0FH ;
MOV BUF3,A ; 顯示十位
MOV A,TEMPHC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF4,A ; 顯示百位
MOV A,TEMPHC ;
ANL A,#0F0H ;
CJNE A,#10H,DISPBCD0 ; 百位數=0?
SJMP DISPOUT ;
DISPBCD0:
MOV A, TEMPHC ;
ANL A, #0FH ;
JNZ DISPOUT ; 十位數是0?
MOV A,TEMPHC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF4,0AH ; 符號位不顯示
MOV BUF3,A ; 十位數顯示符號
DISPOUT: RET ;
;*************************************
;單位元組十六進制轉BCD
;*************************************
HEX2BCD1:MOV B,#64H ; 十六進制 ->BCD
DIV AB ; B=A%100
MOV R7,A ; R7=百位數
MOV A,#0AH ;
XCH A,B ;
DIV AB ; B=A%B
SWAP A ;
ORL A,B ;
RET ;
;*************************************
; Calculate CRC-8 Values, Uses The
;CCITT-8 Polynomial,Expressed As
; X^8+X^5+X^4+1
;*************************************
CRC8CAL: PUSH ACC ;
MOV R7,#08H ; Number Bits Byte
CRC8LOOP1:
XRL A,B ; Calculate CRC
RRC A ; Move T0 Carry
MOV A,B ; Get The Last CRC Value
JNC CRC8LOOP2 ; Skip If Data==0
XRL A,#18H ; Update The CRC Value
CRC8LOOP2:
RRC A ; Position The New CRC
MOV B,A ; Store The New CRC
POP ACC ; Get The Remaining Bits
RR A ; Possition The Next Bit
PUSH ACC ; Save The Remaining Bits
DJNZ R7,CRC8LOOP1 ; Repeat For 9 Bits
POP ACC ;
RET ;
;******************************************
;讀DS18B20的程序,從DS18B20中讀出9個位元組數據
;開始的兩個位元組為溫度數據
;******************************************
READ_18200:
MOV R4,#9 ; 將溫度高位和低位從DS18B20中讀出
MOV R1,#TEMPER_L ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
MOV B, #00H ;
;************************************
RE00:
MOV R2,#8 ; 數據一共有8位
RE01:
CLR C
SETB TEMPDIN ;
NOP
NOP
CLR TEMPDIN ;
NOP
NOP
NOP
SETB TEMPDIN ;
MOV R3,#9
RE10:
DJNZ R3,RE10 ;
MOV C,TEMPDIN ;
MOV R3,#23
RE20:
DJNZ R3,RE20 ;
RRC A
DJNZ R2,RE01 ;
;************************************
MOV @R1,A ;
INC R1 ;
LCALL CRC8CAL ;
DJNZ R4,RE00 ;
MOV A,B ;
JNZ READ_OUT ;
MOV TEMPL,TEMPER_L ;
MOV TEMPH,TEMPER_H ;
READ_OUT: RET
;*****************************************
;顯示子程序
;*****************************************
DISPLAY:
MOV DPTR,#NUMTAB ; 指定查表啟始地址
MOV R0,#4
DP11: MOV R1,#250 ; 顯示1000次
DPLP: SETB P1.7
MOV A,BUF1 ; 取小位數
MOVC A,@A+DPTR ; 查小位數的7段代碼
MOV P1,A ; 送出小位的7段代碼
CLR P3.0 ; 開小位顯示
ACALL DL1ms ; 顯示1ms
SETB P3.0 ;
MOV A,BUF2 ; 取個位數
MOVC A,@A+DPTR ; 查個位數的7段代碼
MOV P1,A ; 送出個位的7段代碼
CLR P1.7
CLR P3.1 ; 開個位顯示
ACALL DL1ms ; 顯示1ms
SETB P3.1 ;
SETB P1.7
MOV A,BUF3 ; 取十位數
MOVC A,@A+DPTR ; 查十位數的7段代碼
MOV P1,A ; 送出十位的7段代碼
CLR P3.2 ; 開十位顯示
ACALL DL1ms ; 顯示1ms
SETB P3.2 ;
SETB P1.7
MOV A,BUF4 ; 取百位數
MOVC A,@A+DPTR ; 查百位數的7段代碼
MOV P1,A ; 送出百位的7段代碼
CLR P3.3 ; 開百位顯示
ACALL DL1ms ; 顯示1ms
SETB P3.3 ;
DJNZ R1,DPLP ; 250次沒完循環
DJNZ R0,DP11 ; 4個100次沒完循環
RET
;****************************************
;0.2MS延時(按12MHZ算)
;****************************************
DL1MS: MOV R7,#100
DJNZ R7,$
RET
;****************************************
;7段數碼管0~9數字的共陽顯示代碼
;****************************************
NUMTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH ;
; "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
;****************************************
END
❼ 基於單片機的數字溫度計設計好做么
這種設計相對來說比較好做。
首先選擇用什麼洞此慶系列的單片機。目前常用的有51單片機,AVR單片機,MSP430單片機等等。
接下來選擇用什麼感測器。
採用有溫敏電阻,通過對直流電壓分壓,測量其直流電壓的變化,也就是AD檢測,再納握把電壓值轉換成溫度值;(這種方式要求單片機具有AD檢測功能,否則需要外接AD轉換晶元。)
採用溫度模塊,例如常用的DS18B20,不需要AD檢測,只需要進行I2C讀寫取扒仔得溫度值;
最後確定如何顯示檢測到的數值。
常用的有:
1.數碼管,可以顯示段碼數字或簡單字元。
2.LCD1602液晶屏,可以顯示兩行16*2個英文字母和數字;
3.LCD12864液晶屏,可以顯示四行8*4個漢字。也可以顯示字母及數字,當然也可以顯示自定義圖形。
以上選擇需要合理搭配。
接著就是繪制原理圖和PCB圖、採集元件、焊接,編寫程序,調試。