❶ 基于单片机的电子温度计设计
看看这个吧,是个通过温度传感器实现对电风扇的智能控制的程序
温度传感器是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图、采集元件、焊接,编写程序,调试。