1. 单片机温度的检测与显示的设计..的程序
;本程序用于循环显示0----99
;RXD作为数据输出端,TXD作为脉冲输出端
;本程序只适用于共阳极数码管
ORG 00H
START:
MOV A,#00H
MOV P0,A
MOV R1,#01H
MOV R3,#0AH
START1:
MOV A,#00H
MOV R0,A
MOV R2,#0AH
LOOP:
SETB P0.0
MOV A,R0
MOV R4,A
ACALL DSPLY
ACALL DELAY
MOV A,R0
INC A
MOV R0,A
DJNZ R2,LOOP
CLR P0.0
SETB P0.1
MOV A,R1
MOV R4,A
ACALL DSPLY
ACALL DELAY
MOV A,R1
INC A
MOV R1,A
CLR P0.1
DJNZ R3,START1
AJMP START
DSPLY:
MOV A,R4
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV SBUF, A
JNB TI, $
CLR TI
RET
DELAY:
MOV 30H,#8
D1:MOV 31H,#200
D2:MOV 32H,#200
D3:DJNZ 32H,D3
DJNZ 31H,D2
DJNZ 30H,D1
RET
TABLE:DB 02H,9EH,24H,0CH
DB 98H,48H,40H,1EH
DB 00H,08H
END 这是我参加全国电子设计大赛的一个子程序50分太少了吧!我自己做的电路板,绝对正确
2. 求一个51单片机控制的温度计显示程序
这个程序完全没问题的,我做过实验。希望对你有帮助,,,,
//DS18B20的读写程序,数据脚P3.3 //
//温度传感器18B20汇编程序,采用器件默认的12位转化 //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值 //
//P0口为段码输入,P24~P27为位选 //
/***************************************************/
#include "reg51.h"
#include "intrins.h" //_nop_();延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^3; //温度输入口
sbit DIN=P0^7; //LED小数点控制
uint h;
uchar flag;
//**************温度小数部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用
//
//
//
/***********11微秒延时函数**********/
//
void delay(uint t)
{
for(;t>0;t--);
}
//
/***********显示扫描函数**********/
scan()
{
char k;
for(k=0;k<4;k++) //四位LED扫描控制
{
Disdata=0xff;
Disdata=dis_7[display[k]];
if(k==1){DIN=0;}
discan=scan_con[k];delay(90);
discan=0xff;
}
}
//
//
/***********18B20复位函数**********/
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
presence=DQ; // presence=0继续下一步
}
delay(45); //延时500us
presence = ~DQ;
}
DQ=1;
}
//
//
/**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i>0; i--) //
{
DQ=1;_nop_();_nop_();
DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移一位
}
DQ = 1;
delay(1);
}
//
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ = 0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
//
/***********读出温度函数**********/
//
read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); // 发Skip ROM命令
write_byte(0xBE); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
}
//
/***********温度数据处理函数**********/
void work_temp()
{
uchar n=0;
uchar doth,dotl;
uchar flag3=1,flag2=1; //数字显示修正标记
if((temp_data[1]&0xf8)!=0x00)
{
temp_data[1]=~(temp_data[1]);
temp_data[0]=~(temp_data[0])+1;
n=1;
flag=1;
}//负温度求补码
if(temp_data[0]>255)
{
temp_data[1]++;
}
display[4]=temp_data[0]&0x0f;
display[0]=ditab[display[4]];
doth=display[0]/10;
dotl=display[0]%10;
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4);
display[3]=display[4]/100;
display[2]=display[4]/10%10;
display[1]=display[4]%10;
if(!display[3])
{
display[3]=0x0a;
flag3=0;
if(!display[2])
{
display[2]=0x0a;
flag2=0;
}
}//最高位为0时都不显示
if(n)
{
display[3]=0x0b;//负温度时最高位显示"-"
flag3=0;
}
}
//
//
/**************主函数****************/
main()
{
Disdata=0xff; //初始化端口
discan=0xff;
for(h=0;h<4;h++){display[h]=8;}//开机显示8888
ow_reset(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
for(h=0;h<500;h++)
{scan();} //开机显示"8888"2秒
while(1)
{
read_temp(); //读出18B20温度数据
work_temp(); //处理温度数据
scan(); //显示温度值2秒
}
}
//
//*********************结束**************************//
3. 跪求 单片机进行温度检测的C语言程序
//DS18B20的读写程序,数据脚P2.7 //
//温度传感器18B20汇编程序,采用器件默认的12位转化 //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值 //
//P0口为段码输入,P34~P37为位选 //
/***************************************************/
#include "reg51.h"
#include "intrins.h" //_nop_();延时函数用
#define Disdata P0 //段码输出口
#define discan P3 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^7; //温度输入口
sbit DIN=P0^7; //LED小数点控制
uint h;
uint temp;
//
//
//**************温度小数部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用
//
//
//
/*****************11us延时函数*************************/
//
void delay(uint t)
{
for (;t>0;t--);
}
//
/****************显示扫描函数***************************/
scan()
{
char k;
for(k=0;k<4;k++) //4位LED扫描控制
{
Disdata=dis_7[display[k]]; //数据显示
if (k==1){DIN=0;} //小数点显示
discan=scan_con[k]; //位选
delay(300);
}
}
//
//
/****************DS18B20复位函数************************/
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();//从高拉倒低
DQ=0;
delay(50); //550 us
DQ=1;
delay(6); //66 us
presence=DQ; //presence=0 复位成功,继续下一步
}
delay(45); //延时500 us
presence=~DQ;
}
DQ=1; //拉高电平
}
//
//
/****************DS18B20写命令函数************************/
//向1-WIRE 总线上写1个字节
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //从高拉倒低
DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
DQ=val&0x01; //最低位移出
delay(6); //66 us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
//
/****************DS18B20读1字节函数************************/
//从总线上取1个字节
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ)value|=0x80;
delay(6); //66 us
}
DQ=1;
return(value);
}
//
/****************读出温度函数************************/
//
read_temp()
{
ow_reset(); //总线复位
delay(200);
write_byte(0xcc); //发命令
write_byte(0x44); //发转换命令
ow_reset();
delay(1);
write_byte(0xcc); //发命令
write_byte(0xbe);
temp_data[0]=read_byte(); //读温度值的第字节
temp_data[1]=read_byte(); //读温度值的高字节
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 两字节合成一个整型变量。
return temp; //返回温度值
}
//
/****************温度数据处理函数************************/
//二进制高字节的低半字节和低字节的高半字节组成一字节,这个
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分
/********************************************************/
work_temp(uint tem)
{
uchar n=0;
if(tem>6348) // 温度值正负判断
{tem=65536-tem;n=1;} // 负温度求补码,标志位置1
display[4]=tem&0x0f; // 取小数部分的值
display[0]=ditab[display[4]]; // 存入小数部分显示值
display[4]=tem>>4; // 取中间八位,即整数部分的值
display[3]=display[4]/100; // 取百位数据暂存
display[1]=display[4]%100; // 取后两位数据暂存
display[2]=display[1]/10; // 取十位数据暂存
display[1]=display[1]%10;
/******************符号位显示判断**************************/
if(!display[3])
{
display[3]=0x0a; //最高位为0时不显示
if(!display[2])
{
display[2]=0x0a; //次高位为0时不显示
}
}
if(n){display[3]=0x0b;} //负温度时最高位显示"-"
}
//
//
/****************主函数************************/
main()
{
Disdata=0xff; //初始化端口
discan=0xff;
for(h=0;h<4;h++) //开机显示"0000"
{display[h]=0;}
ow_reset(); //开机先转换一次
write_byte(0xcc); //Skip ROM
write_byte(0x44); //发转换命令
for(h=0;h<100;h++) //开机显示"0000"
{scan();}
while(1)
{
work_temp(read_temp()); //处理温度数据
scan(); //显示温度值
}
}
//
//***********************结束**************************//
4. 单片机温度检测的程序
你用的是DS18B20?这个程序你参考下#include <reg52.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2; //温度传感器信号线
sbit la=P2^6; //数码管段选线
sbit wela=P2^7; //数码管位选线
sbit beep=P2^3; //蜂鸣器
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^6;
sbit key4=P3^7;
uint temp;
float f_temp;
uint warn_l1=23;
uint warn_h1=29;
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0xbf,0x86,
0xdb,0xcf,0xe6,0xed,
0xfd,0x87,0xff,0xef}; //不带小数点的编码
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void dsreset(void) //18B20复位,初始化函数
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bit tempreadbit(void) //读1位函数
{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return (dat);
}
uchar tempread(void) //读1个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tempwritebyte(uchar dat) //向18B20写一个字节数据
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写 1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写 0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
void tempchange(void) //DS18B20 开始获取温度并转换
{
dsreset();
delay(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}
uint get_temp() //读取寄存器中存储的温度数据
{
uchar a,b;
dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread(); //读低8位
b=tempread(); //读高8位
temp=b;
temp<<=8; //两个字节组合为1个字
temp=temp|a;
f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
return temp; //temp是整型
}
////////////////////显示程序//////////////////////////
void display(uchar num,uchar dat)
{
uchar i;
la=0;
P0=table[dat];
la=1;
la=0;
wela=0;
i=0XFF;
i=i&(~((0X01)<<(num)));
P0=i;
wela=1;
wela=0;
delay(1);
}
void dis_temp(uint t)
{
uchar i;
i=t/100;
display(0,i);
i=t%100/10;
display(1,i+10);
i=t%100%10;
display(2,i);
}
//////////////////////////////////////////////
void warn(uint s,uchar led) //蜂鸣器报警声音 ,s控制音调
{
uchar i;i=s;
la=0;
wela=0;
// beep=0;
P1=~(led);
while(i--)
{
dis_temp(get_temp());
}
// beep=1;
P1=0XFF;
i=s;
while(i--)
{
dis_temp(get_temp());
}
}
void deal(uint t)
{
uchar i,k;
k=t/10;
if(k<warn_l1)
{
warn(40,0x01);
}
if(k>warn_h1)
{
warn(40,0x04);
}
else
{
i=40;
while(i--)
{
dis_temp(get_temp());
}
}
}
void xianshi(num)
{
uint m;
for(m=50;m>0;m--)
{
uchar shi,ge;
shi=num/10;
ge=num%10;
la=1;
P0=table[shi];
la=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(10);
la=1;
P0=table[ge];
la=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(10);
}
}
void anjian()
{
if(key1==0)
{
delay(10);
if(key1==0)
{
warn_l1++;
if(warn_l1==warn_h1)
warn_l1=23;
xianshi(warn_l1+1);
while(!key1);
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
warn_l1--;
if(warn_l1==0)
warn_l1=23;
xianshi(warn_l1+1);
while(!key2);
}
}
if(key3==0)
{
delay(10);
if(key3==0)
{
warn_h1++;
if(warn_h1==125)
warn_h1=29;
xianshi(warn_h1+1);
while(!key3);
}
}
if(key4==0)
{
delay(10);
if(key4==0)
{
warn_h1--;
if(warn_h1==warn_l1)
warn_h1=29;
xianshi(warn_h1+1);
while(!key4);
}
}
}
void main()
{
uchar buff[4],i;
la=0;
wela=0;
while(1)
{
tempchange();
anjian();
for(i=10;i>0;i--)
{
dis_temp(get_temp());
}
deal(temp);
sprintf(buff,"%f",f_temp);
for(i=10;i>0;i--)
{
dis_temp(get_temp());
}
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
}
}
5. 51单片机学习板关于温度检测的程序求
一、DS18B20.c文件(用LCD1602显示的 I_N为DS18B20数据IO)
/*
模块名称:温度模块(DS18B20)
模块功能:DS18B20的功能子函数
*/
/********************************************预处理命令*******************************************/
#include"ds18b20.h"
/*
函数名:DS_WriBteAndRead(bit x,unit8 val)
函数功能:向DS18B20内部寄存器写入或读取数据
输入: x,val
输出:DS_WriteAndRead
*/
unit8 DS_WriteAndRead(bit x,unit8 val)
{
unit8 i=0,Red=0;
for(i=8;i>0;i--)
{
if(x) //读数据
{
I_N=0;
I_N=1;
Red>>=1;
if(I_N)Red|=0x80;
}
else //写数据
{
I_N=1;
I_N=0;
I_N=val&0x01;
val>>=1;
}
delay_us(4);
}
if(x)
return(Red);//返回数据
else
return 0;
}
/*
函数名:DS_Reset()
函数功能:DS18B20初始化设置
输入:无
输出:无
*/
void DS_Reset()
{
I_N=1;
I_N=0;
delay_us(50);
I_N=1;
delay_us(30);
DS_WriteAndRead(0,0xcc);//跳过搜索
}
/*
函数名: DS_Data_Handle()
函数功能:数据处理
输入:无
输出:无
*/
void DS_Data_Handle()
{
unit_16 Ra=0,Rb=0,Temp=0;
DS_Reset(); //复位
DS_WriteAndRead(0,0x44); //启动温度转换
DS_Reset(); //复位
delay_us(100);
DS_WriteAndRead(0,0xbe);//读暂存器中的数据
Ra=DS_WriteAndRead(1,0xbe);
Rb=DS_WriteAndRead(1,0xbe);
Temp=Rb;
Temp<<=8;
Temp|=Ra;
Temp=Temp*0.625+0.5;//数值转换
LCD_Write_Data(0,0xc5);
LCD_Write_Data(1,(Temp/100)+48);
LCD_Write_Data(1,(Temp/10%10)+48);
LCD_Write_Data(1,46);
LCD_Write_Data(1,(Temp%10)+48);
}
6. 单片机ts18b20测温程序 请大神注释程序 最好每一句都注释明白(小白一只 只有15财富 全送好人)
/****lcd1602显示温度(使用温度传感器18b20)*****/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*********液晶屏相关参数**************/
#define data_port P1 //液晶屏指令、数据通信接口
sbit rs=P2^0; //液晶屏寄存器选择接口(rs=0时选择指令寄存器,rs=1时选择数据寄存器)
sbit rw=P2^1; //液晶屏读写选择接口(rw=0时选择写入,rw=1时选择读出)
sbit en=P2^2; //液晶屏使能接口(en=0时通信接口中断,en=1时通信接口接通)
uchar code line1_str[]={" Temperature "};//液晶屏第一行要显示的字符串
uchar code num_tab[]={"0123456789"};
/*********温度传感器18b20相关参数**********/
sbit DQ=P3^5; //温度传感器18b20的数据接口
/**********子函数声明部分************/
void T1_int(); //定时器T1初始化子函数声明
void in_command(uchar com); //向液晶屏输入命令子函数声明
void in_data(uchar dat); //向液晶屏输入数据子函数声明
void lcd_disp_string(uchar str[]); //液晶屏显示一串字符子函数声明
void lcd_int(); //液晶屏初始化子函数声明
void disp_temperature(uint temp);//lcd1602显示温度子函数声明
bit ds18b20_ret(); //温度传感器18b20复位子函数声明
void ds18b20_wr_com(uchar com); //向温度传感器18b20写入命令子函数声明
void rd_ram_command(); //发送命令子函数(读取18b20的RAM)
uint ds18b20_rd_data(); //读出温度传感器18b20寄存器的相关数据(主要是温度值)子函数声明
void temperature_convert(); //18b20温度转换子函数声明
void delayms(uint ms); //毫秒延时子函数声明
void delay_n10_us(uchar n); //微秒延时子函数声明
/************************************/
void main()
{
T1_int(); //定时器T1初始化
DQ=1; //释放温度传感器18b20的数据接口
temperature_convert(); //第一次调用18b20温度转换子函数消除85°C问题
lcd_int(); //液晶屏初始化(放在18b20温度转换子函数后边用来延时,跳过85°C)
while(1)
{
temperature_convert(); //调用18b20温度转换子函数
rd_ram_command(); //发送命令子函数(读取18b20的RAM)
disp_temperature(ds18b20_rd_data());//调用lcd1602显示温度子函数
}
}
/**********定时器T1初始化*************/
void T1_int()
{
TMOD=0x10; //0001 0000 T1工作在定时方式1
TH1=0; //T1设定初值
TL1=0;
TR1=0; //暂时关闭T1
}
/**********18b20温度转换子函数*************/
void temperature_convert()
{
while(ds18b20_ret()==0);//温度传感器18b20复位
ds18b20_wr_com(0xcc); //向温度传感器18b20写入"跳跃ROM命令"
ds18b20_wr_com(0x44); //向温度传感器18b20写入"温度转换命令"
delay_n10_us(50); //500us延时,等待转换完成
}
/**********发送命令子函数(读取18b20的RAM)***********/
void rd_ram_command()
{
while(ds18b20_ret()==0);
ds18b20_wr_com(0xcc); //向温度传感器18b20写入"跳跃ROM命令"
ds18b20_wr_com(0xbe); //向温度传感器18b20写入"读RAM命令"
}
/******读出18b20寄存器的相关数据(主要是温度值)子函数******/
uint ds18b20_rd_data()
{
uchar i;
uint temp_val;
for(i=0;i<16;i++)
{
temp_val>>=1;
DQ=0;
_nop_();
DQ=1;
_nop_();
_nop_();
if(DQ==1)
{
temp_val|=0x8000;
}
delay_n10_us(7); //70us延时,确保读出
}
return(temp_val);
}
/******向温度传感器18b20写入命令子函数声明****/
void ds18b20_wr_com(uchar com)
{
uchar i;
for(i=0;i<8;i++)
{
if((com&0x01)==0)
{
DQ=0;
delay_n10_us(7); //70us延时,确保写入0
DQ=1;
_nop_();
}
else
{
DQ=0;
_nop_();
DQ=1;
delay_n10_us(7); //70us延时,确保写入1
}
com>>=1;
}
}
/**********温度传感器18b20复位子函数**********/
bit ds18b20_ret()
{
uint temp; //暂存脉冲时间
DQ=0; //启动复位脉冲
delay_n10_us(50); //500us延时(大于480us)
DQ=1; //停止复位脉冲
TR1=1; //启动T1
while(DQ==1 && TH1*256+TL1<=60);//等待18b20回应,等待时间不超过60us
if(DQ==0) //18b20回应
{
temp=TH1*256+TL1;
while(TH1*256+TL1-temp<40); //等待60us再次检测回应脉冲是否存在
if(DQ==0) //18b20正常回应
{
while(TH1*256+TL1<=480);//等待正常复位完成
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(1); //18b20有正常回应返回1
}
else
{
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(0); //18b20有正常回应返回0
}
}
else
{
TR1=0; //关闭T1
TH1=0; //计时归零
TL1=0;
return(0); //18b20没有回应返回0
}
}
/*********lcd1602显示温度子函数声明********/
void disp_temperature(uint temp)
{
uchar temp_h,temp_l,flag=0; //温度整数部分,小数部分(二进制)和最高位是否为'0'标志
uint temp_decimal=0; //存储温度值的小数部分(十进制)
in_command(0xc2); //设定第二行字符串起始显示位置
if(temp>=0x8000)
{
in_data('-'); //显示'-'号
temp=~temp;
temp+=1;
}
else
{
in_data(' '); //'+'号不显示
}
temp_h=temp/16;
temp_l=temp%16;
if(temp_h/100!=0)
{
flag=1;
in_data(num_tab[temp_h/100]); //显示温度值的百位
}
else
{
in_data(' '); //百位为'0'则百位不显示
}
temp_h%=100;
if(temp_h/10!=0 || flag==1)
{
flag=1;
in_data(num_tab[temp_h/10]); //显示温度值的十位
}
else
{
in_data(' '); //百位,十位都为'0'则十位不显示
}
temp_h%=10;
in_data(num_tab[temp_h]); //显示温度值的个位
in_data('.'); //显示小数点
if(temp_l/8==1)
{temp_decimal+=5000;}
temp_l=temp_l%8;
if(temp_l/4==1)
{temp_decimal+=2500;}
temp_l=temp_l%4;
if(temp_l/2==1)
{temp_decimal+=1250;}
temp_l=temp_l%2;
if(temp_l==1)
{temp_decimal+=625;}
in_data(num_tab[temp_decimal/1000]);//显示温度值的十分位
in_data(' ');
in_data(223); //显示温度单位标志'摄氏度'
in_data('C');
}
/**********液晶屏初始化子函数**********/
void lcd_int()
{
/***************LCD初始设置*****************/
delayms(15); //延时15MS,等待LCD初始化
in_command(0x01); //清显示屏
in_command(0x38); //8位通信,2行显示,5*7点阵
in_command(0x0c); //开显示,关光标,关闪烁
in_command(0x06); //字符不动,光标右移动,地址加一
/************1602显示上电后电机默认的状态信息**************/
in_command(0x80); //设定第一行字符串起始显示位置
lcd_disp_string(line1_str); //显示数据(字符)
}
/**********液晶屏显示一串字符**********/
void lcd_disp_string(uchar str[])
{
uchar i=0;
while(str[i]!='\0')
{
in_data(str[i]); //显示数据(字符)
i++;
delayms(50); //延时
}
}
/********向液晶屏输入命令子函数************/
void in_command(uchar com)
{
delayms(2);
en=0;//关闭通信,为设置参数做准备
rs=0;//选择指令寄存器
rw=0;//写入液晶
_nop_();
data_port=com;
en=1;//开始通信
_nop_();
en=0;//关闭通信,为设置参数做准备
}
/********向液晶屏输入数据子函数************/
void in_data(uchar dat)
{
delayms(2);
en=0;//关闭通信,为设置参数做准备
rs=1;//选择数据寄存器
rw=0;//写入液晶
_nop_();
data_port=dat;
_nop_();
en=1;//开始通信
_nop_();
en=0;//关闭通信,为设置参数做准备
}
/********微秒延时子函数************/
void delay_n10_us(uchar n)
{
while(n--)
{
_nop_();
_nop_();
}
}
/********毫秒延时子函数************/
void delayms(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<124;i++);
}
}
7. 单片机数字温度计的源程序
//DS18B20的读写程序,数据脚P2.7 // //温度传感器18B20汇编程序,采用器件默认的12位转化 // //最大转化时间750微秒,显示温度-55到+125度,显示精度 // //为0.1度,显示采用4位LED共阳显示测温值 // //P0口为段码输入,P34~P37为位选 // /***************************************************/ #include "reg51.h" #include "intrins.h" //_nop_();延时函数用 #define Disdata P0 //段码输出口 #define discan P2 //扫描口 #define uchar unsigned char #define uint unsigned int sbit DQ=P1^2; //温度输入口 sbit DIN=P0^7; //LED小数点控制 uint h; uint temp; // // //**************温度小数部分用查表法***********// uchar code ditab[16]= {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; // uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列扫描控制字 uchar data temp_data[2]={0x00,0x00}; //读出温度暂放 uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用 // // // /*****************11us延时函数*************************/ // void delay(uint t) { for (;t>0;t--); } // /****************显示扫描函数***************************/ scan() { char k; for(k=0;k<4;k++) //4位LED扫描控制 { Disdata=dis_7[display[k]]; //数据显示 if (k==1){DIN=0;} //小数点显示 discan=scan_con[k]; //位选 delay(300); P2=0xff; } }
8. 单片机温度检测程序怎么写采用一个带有I2C总线接口的温度传感器,包括显示,包括串口通讯给PC机
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //define interface
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit la=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///////功能:串口初始化,波特率9600,方式1///////
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
}
uint tmp() //get the temperature
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
void readrom() //read the serial
{
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3,ser;
ser=temp/10;
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
la=0;
P0=table[A1]; //显示百位
la=1;
la=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
la=0;
P0=table1[A2]; //显示十位
la=1;
la=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
la=1;
la=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main()
{
uchar a;
// Init_Com();
do
{
tmpchange();
// delay(200);
for(a=10;a>0;a--)
{ display(tmp());
}
} while(1);
}
参照一下。但注意你的开发板的接线情况,sbit la=P2^6;
sbit wela=P2^7;是控制数码管锁存。
9. 单片机ds18b20测温数码管显示程序,我参照原来程序改的,为何一个显示十进制一个显示16进制
我发现了三个不同之处。 不知道你有没有仔细比较 :
1、uchar readbyte()中i应该<=8;
2、显示十位时,原程序是 table1[];
3、结尾 display(tmp());后没有延时一个机器周期,1ms。
10. 51单片机制作温度计的简单程序
;这是关于DS18B20的读写程序,数据脚P2.2,晶振12MHZ
;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒
;可以将检测到的温度直接显示到AT89C51开发实验板的两个数码管上
;显示温度00到99度,很准确哦~~无需校正!
ORG 0000H ;单片机内存分配申明!
TEMPER_L EQU 29H;用于保存读出温度的低8位
TEMPER_H EQU 28H;用于保存读出温度的高8位
FLAG1 EQU 38H;是否检测到DS18B20标志位
a_bit equ 20h ;数码管个位数存放内存位置
b_bit equ 21h ;数码管十位数存放内存位置
TEMP_TH EQU
MAIN:
LCALL GET_TEMPER;调用读温度子程序 ,显示范围00到99度,显示精度为1度
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
MOV A,29H
MOV C,40H;将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
LCALL DISPLAY ;调用数码管显示子程序
CPL P1.0
AJMP MAIN
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB P3.5
NOP
CLR P3.5 ;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P3.5 ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P3.5,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
CLR P1.7 ;检查到DS18B20就点亮P1.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
CLR P1.1 ;点亮P1。1脚LED表示温度传感器通信失败
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:
SETB P3.5
RET
; 读出转换后的温度值
GET_TEMPER:
SETB P3.5
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
CLR P1.2
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
CLR P1.3 ;DS18B20已经被检测到!!!!!!!!!!!!!!!!!!
MOV A,#0CCH
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
CLR P1.4
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR P3.5
MOV R3,#6
DJNZ R3,$
RRC A
MOV P3.5,C
MOV R3,#23
DJNZ R3,$
SETB P3.5
NOP
DJNZ R2,WR1
SETB P3.5
RET
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB P3.5
NOP
NOP
CLR P3.5
NOP
NOP
NOP
SETB P3.5
MOV R3,#9
RE10:
DJNZ R3,RE10
MOV C,P3.5
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;显示子程序
display: mov a,29H;将29H中的十六进制数转换成10进制
mov b,#10 ;10进制/10=10进制
div ab
mov b_bit,a ;十位在a
mov a_bit,b ;个位在b
mov dptr,#numtab ;指定查表启始地址
mov r0,#4
dpl1: mov r1,#250 ;显示1000次
dplop: mov a,a_bit ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
mov p1,a ;送出个位的7段代码
setb p2.0 ;开个位显示
acall d1ms ;显示1ms
clr p2.0
mov a,b_bit ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
mov p1,a ;送出十位的7段代码
setb p2.1 ;开十位显示
acall d1ms ;显示1ms
clr p2.1
djnz r1,dplop ;100次没完循环
djnz r0,dpl1 ;4个100次没完循环
ret
;1MS延时(按12MHZ算)
D1MS: MOV R7,#80
DJNZ R7,$
RET
numtab: ;数码管共阳极0~9代码
DB 0C0H,0F9H,0A4H,0B0H,99H, 92H,82H,0F8H,80H,90H
end