DS18B20温度采集程序代码
DS18B20温度传感器实现代码
DS18B20温度传感器实现代码平台: freescale CodeWarriorMCU:MC9S12G128(汽车级芯⽚)#include "Ds18b20.h"/************************************************************* DS18B20 status initialization************************************************************/#pragma MESSAGE DISABLE C12056 //屏蔽警告INT8U Ds18b20StsInit(void){INT8U ack = DB_OK;INT16U outTime = 500;//DisableInterrupts/* 初始化状态 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);/* 拉低BUS,延时500us */BUS = LOW;DelayUs(480);/* BUS上拉,延时15us-60us */BUS = HIGH;DelayUs(30);/* BUS设置为输⼊ */BUS_DIR = LOW;/* 等待DS18B20存在脉冲做出回应,0正常,60-240us */DelayUs(8);while(BUS){--outTime; //超时处理if(outTime == 0){ack = DB_ERR;break;}}/* 等待DS18B20恢复稳定 */DelayUs(128);/* BUS上拉 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(280);//EnableInterruptsreturn (ack);}/************************************************************* Write data to ds18b20************************************************************/PRIVATE void Ds18b20WriteData(INT8U cmd){INT8U i;DisableInterruptsfor(i = 0; i < 8; i++){//BUS = LOW; //HIGH->LOW 启动写时序//Tim_Delay8Us(2);if(cmd & 0x01) //从低位开始发送数据,15us完成 {BUS = 0; //写1时序DelayUs(5);BUS = 1;}else{BUS = 0; //写0时序DelayUs(5);}DelayUs(60); //等待从器件采集数据BUS = HIGH; //拉⾼总线,起始状态DelayUs(8);cmd >>= 0x01;}EnableInterrupts}#if 1/************************************************************* Read data from ds18b20************************************************************/ PRIVATE INT8U Ds18b20ReadData(void){INT8U i;INT8U data = 0x00;BUS = HIGH;DelayUs(8);DisableInterruptsfor(i = 0; i < 8; i++){data >>= 0x01;BUS = LOW; //拉低总线,进⾏读时序操作 DelayUs(8);BUS = HIGH; //拉低总线,进⾏读时序操作 DelayUs(8);BUS_DIR = LOW; //配置为输⼊asm("nop");//Tim_Delay8Us(1);if(BUS){data |= 0x80;}DelayUs(60); //等待数据读缓存BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);}EnableInterruptsreturn (data);#endifINT8U Dt = 0, Dt1 = 0;/************************************************************* Get data from ds18b20************************************************************/INT16U Ds18b20GetTemperature(void){INT16U data = CLEAR;INT8U temp[2] = {0};Dt = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0x44); //启动温度转换Dt1 = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0xbe); //读暂存寄存器temp[0] = Ds18b20ReadData();temp[1] = Ds18b20ReadData();data = (temp[1] << 8) | temp[0];return (data);}调试DS18B20遇到采集数据不稳定情况: 不稳定现象:每读到⼏个正常数据后会有⼏个不正常的数据 不稳定原因:因为中断在打断我数据的读写以及采集 解决办法:因为DS18B20单总线读写时对时序要求很严格,每次读写时关闭中断即可得到稳定数据。
(整理)数字温度传感器18b20编程
ds18b20汇编程序:本汇编程序仅适合单个DS18B20和51单片机的连接,晶振为12 MHZ左右DQ:DS18B20的数据总线接脚FLAG1:标志位,为"1"时表示检测到DS18B20TEMPER_NUM:保存读出的温度数据TEMPER_LEQU36HTEMPER_HEQU35HDQBITP1.7; DS18B20初始化汇编程序;//*****************************************//INIT_1820:SETBDQNOPCLRDQMOVR0,#06BHTSR1:DJNZR0,TSR1; 延时SETBDQMOVR0,#25HTSR2:JNBDQ,TSR3DJNZR0,TSR2LJMPTSR4; 延时TSR3:SETBFLAG1; 置标志位,表示DS1820存在LJMPTSR5TSR4:CLRFLAG1; 清标志位,表示DS1820不存在LJMPTSR7TSR5:MOVR0,#06BHTSR6:DJNZR0,TSR6; 延时TSR7:SETBDQRET;//*****************************************// ; 重新写DS18B20暂存存储器设定值;//*****************************************//RE_CONFIG:JBFLAG1,RE_CONFIG1; 若DS18B20存在,转RE_CONFIG1 RETRE_CONFIG1:MOVA,#0CCH; 发SKIP ROM命令LCALLWRITE_1820MOVA,#4EH; 发写暂存存储器命令LCALLWRITE_1820MOVA,#00H; TH(报警上限)中写入00HLCALLWRITE_1820MOVA,#00H; TL(报警下限)中写入00HLCALLWRITE_1820MOVA,#1FH; 选择9位温度分辨率LCALLWRITE_1820RET;//*****************************************//; 读出转换后的温度值;//*****************************************//GET_TEMPER:SETBDQ; 定时入口LCALLINIT_1820JBFLAG1,TSS2RET; 若DS18B20不存在则返回TSS2:MOVA,#0CCH; 跳过ROM匹配LCALLWRITE_1820MOVA,#44H; 发出温度转换命令LCALLWRITE_1820LCALLINIT_1820MOVA,#0CCH; 跳过ROM匹配LCALLWRITE_1820MOVA,#0BEH; 发出读温度命令LCALLWRITE_1820LCALLREAD_1820MOVTEMPER_NUM,A; 将读出的温度数据保存RET;//*****************************************//; 读DS18B20的程序,从DS18B20中读出一个字节的数据;//*****************************************// READ_1820:MOVR2,#8RE1:CLRCSETBDQNOPNOPCLRDQNOPNOPNOPSETBDQMOVR3,#7DJNZR3,$MOVC,DQMOVR3,#23DJNZR3,$RRCADJNZR2,RE1RET;//*****************************************//; 写DS18B20的程序;//*****************************************// WRITE_1820:MOVR2,#8CLRCWR1:CLRDQMOVR3,#6DJNZR3,$RRCAMOVDQ,CMOVR3,#23DJNZR3,$SETBDQNOPDJNZR2,WR1SETBDQ RET;//*****************************************//; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据;//*****************************************//READ_18200:MOVR4,#2; 将温度高位和低位从DS18B20中读出MOVR1,#36H; 低位存入36H(TEMPER_L),高位存入35H(TEMP ER_H)RE00:MOVR2,#8RE01:CLRCSETBDQNOPNOPCLRDQNOPNOPNOPSETBDQMOVR3,#7DJNZR3,$MOVC,DQMOVR3,#23DJNZR3,$RRCADJNZR2,RE01MOV@R1,ADECR1DJNZR4,RE00RET;//*****************************************//; 将从DS18B20中读出的温度数据进行转换;//*****************************************//TEMPER_COV:MOVA,#0F0HANLA,TEMPER_L; 舍去温度低位中小数点后的四位温度数值SWAPAMOVTEMPER_NUM,AMOVA,TEMPER_LJNBACC.3,TEMPER_COV1; 四舍五入去温度值INCTEMPER_NUMTEMPER_COV1:MOVA,TEMPER_HANLA,#07HSWAPAORLA,TEMPER_NUMMOVTEMPER_NUM,A; 保存变换后的温度数据LCALLBIN_BCDRET;//*****************************************//; 将16进制的温度数据转换成压缩BCD码;//*****************************************//BIN_BCD:MOVDPTR,#TEMP_TABMOVA,TEMPER_NUMMOVCA,@A+DPTRMOVTEMPER_NUM,ARETTEMP_TAB:DB00H,01H,02H,03H,04H,05H,06H,07HDB08H,09H,10H,11H,12H,13H,14H,15HDB16H,17H,18H,19H,20H,21H,22H,23HDB24H,25H,26H,27H,28H,29H,30H,31HDB32H,33H,34H,35H,36H,37H,38H,39HDB40H,41H,42H,43H,44H,45H,46H,47HDB48H,49H,50H,51H,52H,53H,54H,55HDB56H,57H,58H,59H,60H,61H,62H,63HDB64H,65H,66H,67H,68H,69H,70H;//*****************************************//下面还介绍一个ds18b20汇编程序;**********************************FLAG1 BIT F0 ;DS18B20存在标志位DQ BIT P1.7TEMPER_L EQU 29HTEMPER_H EQU 28HA_BIT EQU 35HB_BIT EQU 36H;************ds18b20汇编程序起始******************** ORG 0000HAJMP MAINORG 0100H;**************主程序开始************MAIN:LCALL INIT_18B20;LCALL RE_CONFIGLCALL GET_TEMPERAJMP CHANGE;**********DS18B20复位程序*****************INIT_18B20: SETB DQNOPCLR DQMOV R0,#0FBHTSR1: DJNZ R0,TSR1 ;延时SETB DQMOV R0,#25HTSR2: JNB DQ ,TSR3DJNZ R0,TSR2TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在CLR P2.0 ;二极管指示AJMP TSR5TSR4: CLR FLAG1LJMP TSR7TSR5: MOV R0,#06BHTSR6: DJNZ R0,TSR6TSR7:SETB DQ ;表明不存在RET;********************设定DS18B20暂存器设定值********** ****;RE_CONFIG:;JB FLAG1,RE_CONFIG1;RET;RE_CONFIG1: MOV A,#0CCH ;放跳过ROM命令;LCALL WRITE_18B20;MOV A,#4EH;LCALL WRITE_18B20 ;写暂存器命令;MOV A,#00H ;报警上限中写入00H;LCALL WRITE_18B20;MOV A,#00H ;报警下限中写入00H; LCALL WRITE_18B20;MOV A,#1FH ;选择九位温度分辨率; LCALL WRITE_18B20; RET;*****************读转换后的温度值****************GET_TEMPER:SETB DQLCALL INIT_18B20JB FLAG1,TSS2RET ;若不存在则返回TSS2: MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#44H ;发出温度转换命令LCALL WRITE_18B20LCALL DISPLAY ;延时LCALL INIT_18B20MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#0BEH ;发出读温度换命令LCALL WRITE_18B20LCALL READ2_18B20 ;读两个字节的温度RET;***************写ds18b20汇编程序************WRITE_18B20:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;***********读18B20程序,读出两个字节的温度********* READ2_18B20:MOV R4,#2 ;低位存在29 H,高位存在28HMOV R1,#29HRE00: MOV R2,#8RE01: CLR CSETB CNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;************读出的温度进行数据转换**************CHANGE: MOV A,29HMOV C,28H.0 ;将28H中的最低位移入CRRC AMOV C,28H.1RRC AMOV C,28H.2RRC AMOV C,28H.3RRC AMOV 29H,A;setb p2.0LCALL DISPLAY ;调用数码管显示子程序; setb P2.0LJMP MAIN;*******************DISPLAY******DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制mov b,#10 ;10进制/10=10进制div abmov b_bit,a ;十位在amov a_bit,b ;个位在bmov dptr,#TAB ;指定查表启始地址mov r0,#4dpl1: mov r1,#250 ;显示1000次dplop: mov a,a_bit ;取个位数MOVC A,@A+DPTR ;查个位数的7段代码mov p0,a ;送出个位的7段代码clr p2.5;开个位显示acall d1ms ;显示1mssetb p2.5mov a,b_bit ;取十位数MOVC A,@A+DPTR ;查十位数的7段代码mov p0,a ;送出十位的7段代码clr p2.4;开十位显示acall d1ms ;显示1mssetb p2.4djnz r1,dplop ;100次没完循环djnz r0,dpl1 ;4个100次没完循环ret;***********************************D1MS: MOV R7,#80 ;1MS延时(按12MHZ算)DJNZ R7,$RET;*************************TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H, 90H。
温度DS18B20数字测土壤湿度程序代码(AD和12864)
void main()
{ char8 i;
int16 shidu;
init();
init12864();//液晶初始化
a=1;b=1;c=0; //选通道in3
st=0;
while(1)
{
st=1;
st=0;
while(!eoc);
PCA_PWM0=0;//pwm寄存器
//timer0工作在时钟输出
WAKE_CLKO=0X01;//允许P3^4为时钟输出口
AUXR=0X80;//设置定时器0工作在1t模式
TMOD=0X02;//设置定时器0工作方式TL0=(256-11)%256;
for(i=0;i<4;i++)
write(0xfa,table[i]);
write(0xf8,0x80);
delayD(50000);
}
}
/**********z=1时**延时大约100us********/
void delayD(int16 z)
{
int16 i,j;
for(i=z;i>0;i--)
for(j=86;j>0;j--);
}
/**********z=0时**延时大约1.54us********/
void delayX(int16 z)
{
while(z--);/***大约为9个周期1.54us**/
}
/**********12864串行通信******************/
//串行接口时序参数:(测试条件:T=25℃ VDD=4.5V)*/
ds18b20多路温度采集程序
本程序为ds18b20的多路温度采集程序,是我自己参考其他程序后改写而成,可显示4路正负温度值,并有上下限温度报警(声音、灯光报警)。
亲测,更改端口即可使用。
(主要器件:51单片机,ds18b20,lcd显示器)附有proteus仿真图,及序列号采集程序/****上限62度下限-20度****/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit ds=P1^1;sbit rs=P1^4;sbit e=P1^6;sbit sp=P1^0;sbit d1=P1^2;sbit d2=P1^3;ucharlcdrom[4][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e} ,{0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9},{0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0},{0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}};unsigned char code table0[]={"TEMPERARTURE:U "}; unsigned char code table1[]={"0123456789ABCDEF"};int f[4];int tvalue;float ftvalue;uint warnl=320;uint warnh=992;/****lcd程序****/void delayms(uint ms)//延时{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}void wrcom(uchar com)//写指令{delayms(1);rs=0;P3=com;delayms(1);e=1;delayms(1);e=0;}void wrdat(uchar dat)//写数据{rs=1;e=0;P3=dat;delayms(5);e=1;delayms(5);e=0;}void lcdinit()//初始化lcd {delayms(15);wrcom(0x38);delayms(5);wrcom(0x0c);delayms(5);wrcom(0x06);delayms(5);wrcom(0x01);delayms(5); }void display(uchar *p)//显示{while(*p!='\0'){wrdat(*p);p++;delayms(1);}}displayinit()//初始化显示{lcdinit();wrcom(0x80);display(table0);}/****ds18b20程序****/ void dsrst()//ds18b20复位{uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit dsrd0()//读一位数据{uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar dsrd()//读1个字节数据{uchar i,j,dat;dat=0;for(i=8;i>0;i--){j=dsrd0();dat=(j<<7)|(dat>>1);}return(dat);}void dswr(uchar dat)//写数据{uint i;uchar j;bit testb;for(j=8;j>0;j--){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tmstart()//初始化ds18b20{sp=1;d1=1;d2=1;dsrst();delayms(1);dswr(0xcc);dswr(0x44);}void read_dealtemp()//读取并处理温度{uchar i,j,t;uchar a,b;for(j=0;j<4;j++){dsrst();delayms(1);dswr(0x55);for(i=0;i<8;i++){dswr(lcdrom[j][i]);//发送64位序列号}dswr(0xbe);a=dsrd();b=dsrd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0){d1=1;tvalue=~tvalue+1;wrcom(0xc0);wrdat(0x2d);if(tvalue>warnl){d2=0;sp=0;}else{d2=1;sp=1;}}else{d2=1;wrcom(0xc0);wrdat(' ');if(tvalue>warnh){d1=0;sp=0;}else{d1=1;sp=1;}}if(j==0){wrcom(0x8e); wrdat('2');}if(j==1){wrcom(0x8e);wrdat('3');}if(j==2){wrcom(0x8e);wrdat('4');}if(j==3){wrcom(0x8e);wrdat('5');}ftvalue=tvalue*0.0625;tvalue=ftvalue*10+0.5;ftvalue=ftvalue+0.05;f[j]=tvalue;//温度扩大十倍,精确到一位小数tvalue=f[j];t=tvalue/1000;wrcom(0x80+0x41);wrdat(table1[t]);//显示百位t=tvalue%1000/100;wrdat(table1[t]);//显示十位t=tvalue%100/10;wrdat(table1[t]);//显示个位wrdat(0x2e); //显示小数点儿t=tvalue%10/1;wrdat(table1[t]);//显示小数位delayms(5000);}}/****主函数****/void main(){d1=1;d2=1;sp=1;displayinit();//初始化显示while(1){tmstart();//初始化read_dealtemp();//读取温度}}/****序列号读取程序****/#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^1; //温度传感器信号线sbit rs = P1^4; //LCD数据/命令选择端(H/L)位声明sbit lcden = P1^6; //LCD使能信号端位声明void delay(uint z); //延时函数void DS18B20_Reset(void); //DQ18B20复位,初始化函数bit DS18B20_Readbit(void); //读1位数据函数uchar DS18B20_ReadByte(void); //读1个字节数据函数void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数void LCD_WriteCom(uchar com); //1602液晶命令写入函数void LCD_WriteData(uchar dat); //1602液晶数据写入函数void LCD_Init();//LCD初始化函数void Display18B20Rom(char Rom); //显示18B20序列号函数/**********************************************//* 主函数*//**********************************************/void main(){ uchar a,b,c,d,e,f,g,h;LCD_Init();DS18B20_Reset();delay(1);DS18B20_WriteByte(0x33);delay(1);a = DS18B20_ReadByte();b = DS18B20_ReadByte();c = DS18B20_ReadByte();d = DS18B20_ReadByte();e = DS18B20_ReadByte();f = DS18B20_ReadByte();g = DS18B20_ReadByte();h = DS18B20_ReadByte();LCD_WriteCom(0x80+0x40);Display18B20Rom(h);Display18B20Rom(g);Display18B20Rom(f);Display18B20Rom(e);Display18B20Rom(d);Display18B20Rom(c);Display18B20Rom(b);Display18B20Rom(a);while(1);}/***************************************************//* 延时函数:void delay() *//* 功能:延时函数*//***************************************************/void delay(uint z)//延时函数{uint x,y;for( x = z; x > 0; x-- )for( y = 110; y > 0; y-- );}/***************************************************//* DS18B20函数:void DS18B20_Reset() *//* 功能:复位18B20 *//***************************************************/void DS18B20_Reset(void)//DQ18B20复位,初始化函数{uint i;DQ = 0;i = 103;while( i > 0 ) i--;DQ = 1;i = 4;while( i > 0 ) i--;}/***************************************************//* DS18B20函数:void DS18B20_Readbit() *//* 功能:读1个字节数据函数*//***************************************************/bit DS18B20_Readbit(void) //读1位数据函数{uint i;bit dat;DQ = 0;i++; //i++起延时作用DQ = 1;i++;i++;dat = DQ;i = 8;while( i > 0 )i--;return( dat );}/***************************************************//* DS18B20函数:void DS18B20_ReadByte() *//* 功能:读1个字节数据函数*//***************************************************/uchar DS18B20_ReadByte(void) //读1个字节数据函数{uchar i,j,dat;dat = 0;for( i = 1; i <= 8; i++ ){j = DS18B20_Readbit();dat = ( j << 7 ) | ( dat >> 1 );}return(dat);}/***************************************************//* DS18B20函数:void DS18B20_WriteByte() *//* 功能:向DQ18B20写一个字节数据函数*//***************************************************/void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数{uint i;uchar j;bit testb;for( j=1; j<=8; j++){testb = dat&0x01;dat= dat>>1;if(testb) //写1{DQ = 0;i++;i++;DQ = 1;i = 8;while(i>0)i--; }else{DQ = 0; //写0 i = 8;while(i>0)i--; DQ = 1;i++;i++;}}}/* LCD函数:void LCD_WriteCom() *//* 功能:向LCD写入命令*//***********************************************/void LCD_WriteCom(uchar com){rs = 0;P3= com;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}/***********************************************//* LCD函数:void LCD_WriteData(uchar dat) *//* 功能:向LCD写入数据*/void LCD_WriteData(uchar dat){rs = 1; //选择LCD为写入数据状态lcden = 0;P3= dat; //将待写入数据放到总线上delay(5);lcden = 1; //给LCD使能端一个脉冲delay(5); //信号将之前放到总线上lcden = 0; //的数据写入LCDdelay(5);}/***********************************************//* LCD函数:void LCD_Init() *//* 功能:初始化LCD,设定LCD的初始状态*/void LCD_Init(){LCD_WriteCom(0x38); //LCD显示模式设定delay(15);LCD_WriteCom(0x08); //关闭LCD显示delay(3);LCD_WriteCom(0x01); //LCD显示清屏delay(3);LCD_WriteCom(0x06); //设定光标地址指针为自动加1delay(3);LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标}/**********************************************//* *//* 显示18B20序列号*//* *//**********************************************/void Display18B20Rom(char Rom){uchar h,l;l = Rom & 0x0f; //取低4位h = Rom & 0xf0; //取高4位h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30);//取ASCII码elseLCD_WriteData(h+0x37);//取ASCII码if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30);//取ASCII码elseLCD_WriteData(l+0x37);//取ASCII码}。
DS1820_源代码
源代码:;这是关于单个DS18B20的测温程序,数据脚为P3.3,晶振是11.059MHZ;(因为我要用到串口通信,只是下面没有给出具体的程序,所以下面的延时用12MHZ计算) ;温度传感器18B20采用器件默认的12位转化,最大转化时间要750毫秒;用1602液晶屏显示,显示温度从00到99度,精确到0.0625度;内存分配声明TEMPER_L EQU 29H;用于保存读出温度的低字节TEMPER_H EQU 28H;用于保存读出温度的高字节T_DF EQU 27H ;FORMA T后的小数部分(decimal fraction),半字节的温度小数(存在低四位) T_INTEGER EQU 26H ;FORMA T后的整数部分(integer),将两字节的温度整合成1字节FLAG1 BIT 50H;位地址50H是字节2AH的最低位,用作是否检测到DS18B20的标志位A_BIT EQU 20h ;液晶十位数存放内存位置B_BIT EQU 21h ;液晶个位数存放内存位置C_BIT EQU 22H ;个位小数D_BIT EQU 23H ;十位小数E_BIT EQU 24H ;百位小数F_BIT EQU 25H ;千位小数RS BIT P3.7 ;这3位是液晶屏的控制信号,连接方式由具体硬件而定RW BIT P3.6E BIT P3.5ORG 0000HLJMP MAINORG 0100HMAIN: LCALL T_CONVERSION;调用读温度子程序LCALL T_FORMA T;将读出的2字节温度格式化LCALL DISPLAY;调用液晶显示子程序LCALL D1S;延时1秒后再测LJMP MAIN;--------------DS18B20的温度转换子程序,具体时序请参考资料-------------------T_CONVERSION:LCALL INIT_1820;先复位DS18B20JB FLAG1,T_C0RET ; 判断DS1820是否存在?若DS18B20不存在则返回T_C0: MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL D1S ;这里等待AD转换结束,12位的话要延时750m秒LCALL INIT_1820;准备读温度前先复位MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_1820; 将读出的温度数据保存到28H(TEMPER_H)和29H(TEMPER_L)处RET;------DS18B20复位初始化程序-----------------------------------------INIT_1820: SETB P3.3NOPCLR P3.3MOV R0,#2 ;主机发出延时500微秒的复位低脉冲INIT0: MOV R1,#250DJNZ R1,$DJNZ R0,INIT0SETB P3.3;然后拉高数据线NOPMOV R0, #15INIT1: JNB P3.3, INIT3;延时60us等待DS18B20回应DJNZ R0, INIT1LJMP INIT4 ; 超时而没有响应INIT3: SETB FLAG1 ; 置标志位,表示DS1820存在LJMP INIT5INIT4: CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP INIT6INIT5: MOV R0, #120DJNZ R0, $ ; 延时240usINIT6: SETB P3.3RET;---------写DS18B20的子程序(有具体的时序要求)-------------------------------------WRITE_1820: MOV R2,#8;一共8位数据WR0: CLR P3.3MOV R3,#6DJNZ R3,$RRC AMOV P3.3,CMOV R3,#20DJNZ R3,$SETB P3.3NOPNOPDJNZ R2,WR0SETB P3.3RET;------读DS18B20的程序,从DS18B20中读出两个字节的温度数据-------------------------- READ_1820: MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#TEMPER_L ; 低位存入29H(TEMPER_L)RE0: MOV R2,#8RE1: SETB P3.3NOPNOPCLR P3.3NOPNOPSETB P3.3MOV R3,#5DJNZ R3, $MOV C,P3.3MOV R3,#20DJNZ R3, $RRC ADJNZ R2,RE1MOV @R1,ADEC R1 ; 高位存入28H(TEMPER_H)DJNZ R4,RE0RET;-----整合读出的两字节温度(关于DS18B20读出的2字节温度格式请参考资料)---------- T_FORMAT: MOV A, #0FHANL A, TEMPER_LMOV T_DF, A ;获得小数部分(4位)MOV A, TEMPER_LSWAP AMOV TEMPER_L, AMOV A, TEMPER_HSWAP AMOV R0, #TEMPER_LXCHD A, @R0MOV T_INTEGER, A ;获得整数部分(1字节)RET;-------液晶显示的子程序(显示前先格式转换)--------------------------------------- DISPLAY: mov a, T_INTEGERmov b,#10div abmov A_BIT,a ;十位存在A_BITmov B_BIT,b ;个位存在B_BITMOV A, T_DFMOV R0, #C_BITMOV R2, #4D0: MOV B, #10MUL ABMOV B, #16DIV ABMOV @R0, A ;从个位小数C_BIT,到十位D_BIT,百位E_BIT,千位F_BITINC R0MOV A, BDJNZ R2, D0;----二进制到ASCII码转换--------------MOV A, #30HORL A_BIT, AORL B_BIT, AORL C_BIT, AORL D_BIT, AORL E_BIT, AORL F_BIT, A;-------------------------------------LCALL INITIALMOV A, #10000000B ; LINE1: DB 'Now is:',00HLCALL WRITE_INSTRUCTIONMOV DPTR, #LINE1LCALL PR_STRINGMOV A, A_BITLCALL WRITE_LCDDATAMOV A, B_BITLCALL WRITE_LCDDATAMOV A, #2EH ;'.'字符LCALL WRITE_LCDDATAMOV A, C_BITLCALL WRITE_LCDDATAMOV A, D_BITLCALL WRITE_LCDDATAMOV A, E_BITLCALL WRITE_LCDDATAMOV A, F_BITLCALL WRITE_LCDDATAMOV A, #0DFH ;下面两个是摄氏度的数字符号LCALL WRITE_LCDDATAMOV A, #63HLCALL WRITE_LCDDATAmov a, #11000000B ; LINE2: DB 'Design by liang!',00HLcall write_instructionMOV DPTR, #LINE2LCALL PR_STRINGRET;---液晶屏初始化,具体请参考资料------------------------------------------------- initial: MOV A, #01HLCALL WRITE_INSTRUCTIONMOV A, #38HLCALL WRITE_instructionMOV A, #0FHLCALL WRITE_instructionMOV A, #06HLCALL WRITE_instructionRET;----写液晶指令的子程序------------------------------------------WRITE_instruction: MOV P1, ACLR RS ;写入控制命令CLR RWCLR ELCALL DELAYSETB ERET;----写液晶数据的子程序---------------------------------------------write_lcddata: MOV P1, ASETB RS ;写入数据CLR RWCLR ELCALL DELAY ;判断液晶模块是否忙?SETB ERET;-----写行字符的子程序---------------------------------------------------------------PR_STRING: CLR AMOVC A, @A+DPTRJZ END_PRLCALL WRITE_LCDDATAINC DPTRLJMP PR_STRINGEND_PR: RET;----查看液晶忙碌信号的子程序--------------------------------------------------------- DELAY: MOV P1,#0FFH ;判断液晶显示器是否忙的子程序CLR RSSETB RWCLR ENOPSETB EJB P1.7,DELAY ;如果P1.7为高电平表示忙就循环等待RET;---1mS延时(按12MHZ算)----------------------------------------------------------------- D1mS: MOV R7,#250LOOP0: NOPNOPDJNZ R7,LOOP0RET;----1S延时(按12MHZ算)----------------------------------------------------------------- D1S: Mov R6,#4LOOP2: mov R5,#250LOOP1: LCALL D1mSDJNZ R5,LOOP1DJNZ R6,LOOP2RET;--------------------------------------------------------------------------------------LINE1: DB 'Now is:',00HLINE2: DB 'Design by liang!',00HEND。
DS18B20温度采集和显示程序
这个是我自己制作的51单片机板上的DS18B20温度采集和显示程序,你如果有现成的51板稍微修改一下可以用,在我这里是可以用没问题的。
环境是KEIL。
我这个51板也完全符合你的要求。
#pragma db code#include<AT89X52.H>//#include "reg52.h"#include "INTRINS.H"// 此实验是使用18B20检测温度,然后在数码管上显示#define uchar unsigned char#define uint unsigned int#define BUSY1 (DQ1==0)sbit LED_0=P1^0;sbit LED_1=P1^1;sbit LED_2=P1^2;sbit LED_3=P1^3;sbit DQ1=P1^6;//void delay(uint x);void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);void ds_reset_1(void);void wr_ds18_1(char dat);void time_delay(unsigned char time);int get_temp_1(void);void delay(unsigned int x);void read_ROM(void);int get_temp_d(void);/*=====0-9=====A-G=====*/uchar a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82}; unsigned char ResultSignal;int ResultTemperatureLH,ResultT emperatureLL,ResultTemperatureH; unsigned char ROM[8];unsigned char idata TMP;unsigned char idata TMP_d;unsigned char f;unsigned char rd_ds18_1();unsigned int TemH,TemL;void main(){unsigned int TemH,TemL,k=0;ds_reset_1();ds_reset_1(); //resetwr_ds18_1(0xcc); //skip rom_nop_();wr_ds18_1(0x7f);ds_reset_1();wr_ds18_1(0xcc);_nop_();wr_ds18_1(0x44);for(k=0;k<11000;k++)time_delay(255);ds_reset_1();while(1){wr_ds18_1(0xcc);wr_ds18_1(0xbe);TemH=get_temp_1();TemL=get_temp_d();TemH&=0x00ff;TemL&=0x00ff;display((TemH/10),(T emH%10),(TemL/10),(TemL%10));}}/***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time){time=time-10;time=time/6;while(time!=0)time--;}/*****************************************************//* reset ds18b20 */ /*****************************************************/void ds_reset_1(void){unsigned char idata count=0;DQ1=0;time_delay(240);time_delay(240);DQ1=1;return;}void check_pre_1(void){while(DQ1);while(~DQ1);time_delay(30);}void read_ROM(void){int n;check_pre_1();wr_ds18_1(0x33);for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}}/*****************************************************//* Read a bit from 1820 位读取*/ /*****************************************************/bit tmrbit_1(void){idata char i=0;bit dat;DQ1=0;_nop_();DQ1=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();dat = DQ1;time_delay(50);return dat;}/*****************************************************//* read a bety from ds18b20 字节读取*/ /*****************************************************/unsigned char rd_ds18_1(){unsigned char idata i,j,dat=0;for(i=1;i<=8;i++){j=tmrbit_1();dat=(j<<(i-1))|dat;}return dat;}/*****************************************************//* write a bety from ds18b20 写字节*/ /****************************************************/void wr_ds18_1(char dat){signed char idata i=0;unsigned char idata j;bit testb;for(j=1;j<=8;j++){testb=dat & 0x01;dat = dat>>1;if(testb){DQ1=0;_nop_();_nop_();DQ1=1;time_delay(60);}else{DQ1=0;time_delay(50);DQ1=1;_nop_();_nop_();}}}int get_temp_1(void){unsigned char idata a=0,b=0; unsigned char idata i;EA=0;ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);if (a>8){TMP=(TMP+1);}}else{f=1;a=a>>4;b=b<<4;TMP=(a|b);TMP=~TMP;TMP=(TMP+1);}EA=1;return(TMP);}int get_temp_d(void){unsigned char idata a=0,b=0; unsigned char idata i,m;EA=0;ds_reset_1();//复位check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4)); a=(a&0x0f);TMP_d=a;}else{f=1;a=~a;a=(a+1);b=~b;b=(b+1);m=a;a=a>>4;b=b<<4;TMP=(a|b);m=(m&0x0f);TMP_d=m;}EA=1;return(TMP_d);}void delay(unsigned int x) {unsigned int i;for(i=0;i<x;i++);}void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4) {P2=a[d1];LED_0=0;delay(100);LED_0=1;P2=a[d2];LED_1=0;delay(100);LED_1=1;P2=a[d3];LED_2=0;delay(100);LED_2=1;P2=a[d4];LED_3=0;delay(100);LED_3=1;}。
ds18b20多路温度采集程序
本程序为ds18b20的多路温度采集程序,是我自己参考其他程序后改写而成,可显示4路正负温度值,并有上下限温度报警(声音、灯光报警)。
亲测,更改端口即可使用。
(主要器件:51单片机,ds18b20,lcd 显示器)附有proteus仿真图,及序列号采集程序/****上限62度下限-20度****/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit ds=P1^1;sbit rs=P1^4;sbit e=P1^6;sbit sp=P1^0;sbit d1=P1^2;sbit d2=P1^3;uchar lcdrom[4][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e}, {0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9},{0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0},{0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}};unsigned char code table0[]={"TEMPERARTURE:U "}; unsigned char code table1[]={"0123456789ABCDEF"};int f[4];int tvalue;float ftvalue;uint warnl=320;uint warnh=992;/****lcd程序****/void delayms(uint ms)//延时{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}void wrcom(uchar com)//写指令{delayms(1);rs=0;P3=com;delayms(1);e=1;delayms(1);e=0;}void wrdat(uchar dat)//写数据{rs=1;e=0;P3=dat;delayms(5);e=1;delayms(5);e=0;}void lcdinit()//初始化lcd {delayms(15);wrcom(0x38);delayms(5);wrcom(0x0c);delayms(5);wrcom(0x06);delayms(5);wrcom(0x01);delayms(5); }void display(uchar *p)//显示{while(*p!='\0'){wrdat(*p);p++;delayms(1);}}displayinit()//初始化显示{lcdinit();wrcom(0x80);display(table0);}/****ds18b20程序****/ void dsrst()//ds18b20复位{uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit dsrd0()//读一位数据{uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar dsrd()//读1个字节数据{uchar i,j,dat;dat=0;for(i=8;i>0;i--){j=dsrd0();dat=(j<<7)|(dat>>1);}return(dat);}void dswr(uchar dat)//写数据{uint i;uchar j;bit testb;for(j=8;j>0;j--){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tmstart()//初始化ds18b20 {sp=1;d1=1;d2=1;dsrst();delayms(1);dswr(0xcc);dswr(0x44);}void read_dealtemp()//读取并处理温度{uchar i,j,t;uchar a,b;for(j=0;j<4;j++){dsrst();delayms(1);dswr(0x55);for(i=0;i<8;i++){dswr(lcdrom[j][i]);//发送64位序列号}dswr(0xbe);a=dsrd();b=dsrd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0){d1=1;tvalue=~tvalue+1;wrcom(0xc0);wrdat(0x2d);if(tvalue>warnl){d2=0;sp=0;}else{d2=1;sp=1;}}else{d2=1;wrcom(0xc0);wrdat(' ');if(tvalue>warnh){d1=0;sp=0;}else{d1=1;sp=1;}}if(j==0){wrcom(0x8e);wrdat('2');}if(j==1){wrcom(0x8e);wrdat('3');}if(j==2){wrcom(0x8e);wrdat('4');}if(j==3){wrcom(0x8e);wrdat('5');}ftvalue=tvalue*0.0625; tvalue=ftvalue*10+0.5;ftvalue=ftvalue+0.05;f[j]=tvalue;//温度扩大十倍,精确到一位小数tvalue=f[j];t=tvalue/1000;wrcom(0x80+0x41);wrdat(table1[t]);//显示百位t=tvalue%1000/100;wrdat(table1[t]);//显示十位t=tvalue%100/10;wrdat(table1[t]);//显示个位wrdat(0x2e); //显示小数点儿t=tvalue%10/1;wrdat(table1[t]);//显示小数位delayms(5000);}}/****主函数****/void main(){d1=1;d2=1;sp=1;displayinit();//初始化显示while(1){tmstart();//初始化read_dealtemp();//读取温度}}/****序列号读取程序****/#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^1; //温度传感器信号线sbit rs = P1^4; //LCD数据/命令选择端(H/L)位声明sbit lcden = P1^6; //LCD使能信号端位声明void delay(uint z); //延时函数void DS18B20_Reset(void); //DQ18B20复位,初始化函数bit DS18B20_Readbit(void); //读1位数据函数uchar DS18B20_ReadByte(void); //读1个字节数据函数void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数void LCD_WriteCom(uchar com); //1602液晶命令写入函数void LCD_WriteData(uchar dat); //1602液晶数据写入函数void LCD_Init(); //LCD初始化函数void Display18B20Rom(char Rom); //显示18B20序列号函数/**********************************************//* 主函数*//**********************************************/void main(){ uchar a,b,c,d,e,f,g,h;LCD_Init();DS18B20_Reset();delay(1);DS18B20_WriteByte(0x33);delay(1);a = DS18B20_ReadByte();b = DS18B20_ReadByte();c = DS18B20_ReadByte();d = DS18B20_ReadByte();e = DS18B20_ReadByte();f = DS18B20_ReadByte();g = DS18B20_ReadByte();h = DS18B20_ReadByte();LCD_WriteCom(0x80+0x40);Display18B20Rom(h);Display18B20Rom(g);Display18B20Rom(f);Display18B20Rom(e);Display18B20Rom(d);Display18B20Rom(c);Display18B20Rom(b);Display18B20Rom(a);while(1);}/***************************************************//* 延时函数:void delay() *//* 功能:延时函数*//***************************************************/ void delay(uint z)//延时函数{uint x,y;for( x = z; x > 0; x-- )for( y = 110; y > 0; y-- );}/***************************************************//* DS18B20函数:void DS18B20_Reset() *//* 功能:复位18B20 *//***************************************************/ void DS18B20_Reset(void)//DQ18B20复位,初始化函数{uint i;DQ = 0;i = 103;while( i > 0 ) i--;DQ = 1;i = 4;while( i > 0 ) i--;}/***************************************************//* DS18B20函数:void DS18B20_Readbit() *//* 功能:读1个字节数据函数*//***************************************************/bit DS18B20_Readbit(void) //读1位数据函数{uint i;bit dat;DQ = 0;i++; //i++起延时作用DQ = 1;i++;i++;dat = DQ;i = 8;while( i > 0 )i--;return( dat );}/***************************************************//* DS18B20函数:void DS18B20_ReadByte() *//* 功能:读1个字节数据函数*//***************************************************/ uchar DS18B20_ReadByte(void) //读1个字节数据函数{uchar i,j,dat;dat = 0;for( i = 1; i <= 8; i++ ){j = DS18B20_Readbit();dat = ( j << 7 ) | ( dat >> 1 );}return(dat);}/***************************************************//* DS18B20函数:void DS18B20_WriteByte() *//* 功能:向DQ18B20写一个字节数据函数*//***************************************************/ void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数{uint i;uchar j;bit testb;for( j=1; j<=8; j++){testb = dat&0x01;dat= dat>>1;if(testb) //写1{DQ = 0;i++;i++;DQ = 1;i = 8;while(i>0)i--;}else{DQ = 0; //写0i = 8;while(i>0)i--;DQ = 1;i++;i++;}}}/***********************************************//* LCD函数:void LCD_WriteCom()/* 功能:向LCD写入命令*//***********************************************/void LCD_WriteCom(uchar com){rs = 0;P3= com;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}/***********************************************//* LCD函数:void LCD_WriteData(uchar dat) *//* 功能:向LCD写入数据*//***********************************************/void LCD_WriteData(uchar dat)rs = 1; //选择LCD为写入数据状态lcden = 0;P3= dat; //将待写入数据放到总线上delay(5);lcden = 1; //给LCD使能端一个脉冲delay(5); //信号将之前放到总线上lcden = 0; //的数据写入LCDdelay(5);}/***********************************************//* LCD函数:void LCD_Init() *//* 功能:初始化LCD,设定LCD的初始状态*//***********************************************/void LCD_Init(){LCD_WriteCom(0x38); //LCD显示模式设定delay(15);LCD_WriteCom(0x08); //关闭LCD显示delay(3);LCD_WriteCom(0x01); //LCD显示清屏delay(3);LCD_WriteCom(0x06); //设定光标地址指针为自动加1delay(3);LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标}/**********************************************//**//* 显示18B20序列号*//*/**********************************************/void Display18B20Rom(char Rom){uchar h,l;l = Rom & 0x0f; //取低4位h = Rom & 0xf0; //取高4位h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30);//取ASCII码elseLCD_WriteData(h+0x37);//取ASCII码if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30); //取ASCII码elseLCD_WriteData(l+0x37); //取ASCII码}。
stm32f103采集DS18B20温度驱动程序
#include "delay.h"
#define DQ_READ GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
//功能描述:DS18B20初始化
void DS18B20_Init(void)
{
temp =(~temp+1)&0xffff;
}
else
temp = temp*625/1000; //温度值
void DQ_Mode(u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
if(mode==DOUT)
{
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; // 配置IO为开漏输出模式
ack = DQ_READ;
Delay(250);
return ack;
}
// 函数名称:DS18B20_Write
//功能描述:向DS18B20写入一个字节
void DS18B20_Write (u8 dat )
return (u16)temp;
}
int MAIN(viod)
{
DS18B20_Init();
while(1)
{
Temperature4=Get_DS18B20_Tmp()/10;
}
}
GPIO_InitTypeDef GPIO_InitStructure;
DS18B20温度传感器设计原理图及c程序代码
/*******************代码部分**********************//*************** writer:shopping.w ******************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}sbit DQ = P3^3;sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;uchar code Temp_Disp_Title[]={"Current Temp : "};uchar Current_Temp_Display_Buffer[]={" TEMP: "};uchar code Temperature_Char[8] ={0x0c,0x12,0x12,0x0c,0x00,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}; uchar Display_Digit[]={0,0,0,0};bit DS18B20_IS_OK = 1;void DelayXus(uint x){uchar i;while(x--){for(i=0;i<200;i++);}}bit LCD_Busy_Check(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delayNOP();result = (bit)(P0&0x80);LCD_EN=0;return result;}void Write_LCD_Command(uchar cmd) {while(LCD_Busy_Check());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();P0 = cmd;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void Write_LCD_Data(uchar dat){while(LCD_Busy_Check());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void LCD_Initialise(){Write_LCD_Command(0x01);DelayXus(5);Write_LCD_Command(0x38);DelayXus(5);Write_LCD_Command(0x0c);DelayXus(5);Write_LCD_Command(0x06);DelayXus(5);}void Set_LCD_POS(uchar pos){Write_LCD_Command(pos|0x80); }void Delay(uint x){while(--x);}uchar Init_DS18B20(){uchar status;DQ = 1;Delay(8);DQ = 0;Delay(90);DQ = 1;Delay(8);DQ = 1;return status;}uchar ReadOneByte(){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;Delay(30);DQ = 1;}return dat;}void WriteOneByte(uchar dat) {uchar i;for(i=0;i<8;i++){DQ = 0;DQ = dat& 0x01;Delay(5);DQ = 1;dat >>= 1;}}void Read_Temperature(){if(Init_DS18B20()==1)DS18B20_IS_OK=0;else{WriteOneByte(0xcc);WriteOneByte(0x44);Init_DS18B20();WriteOneByte(0xcc);WriteOneByte(0xbe);Temp_Value[0] = ReadOneByte();Temp_Value[1] = ReadOneByte();DS18B20_IS_OK=1;}}void Display_Temperature(){uchar i;uchar t = 150, ng = 0;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]++;ng = 1;}Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);Display_Digit[3] = CurrentT/100;Display_Digit[2] = CurrentT%100/10;Display_Digit[1] = CurrentT%10;Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';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';if(Display_Digit[3] == 0)Current_Temp_Display_Buffer[7] = ' ';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] = '-';elseCurrent_Temp_Display_Buffer[6] = '-';}Set_LCD_POS(0x00);for(i=0;i<16;i++){Write_LCD_Data(Temp_Disp_Title[i]);}Set_LCD_POS(0x40);for(i=0;i<16;i++){Write_LCD_Data(Current_Temp_Display_Buffer[i]);}Set_LCD_POS(0x4d);Write_LCD_Data(0x00);Set_LCD_POS(0x4e);Write_LCD_Data('C');}void main(){LCD_Initialise();Read_Temperature();Delay(50000);Delay(50000);while(1){Read_Temperature();if(DS18B20_IS_OK)Display_Temperature();DelayXus(100);}}。
ds18b20温度计程序
ORG 0000HAJMP MAINORG 0030HMAIN: MOV R5,#0FFHMAIN1:MOV P0,#00H ;系统自检。
自高位向低位带小数点显示8扫描256次CLR P2.4LCALL DELAYSETB P2.4CLR P2.5LCALL DELAYSETB P2.5CLR P2.6LCALL DELAYSETB P2.6CLR P2.7LCALL DELAYSETB P2.7DJNZ R5,MAIN1SETB P2.4 ;关显示SETB P2.5SETB P2.6SETB P2.7SJMP MAIN2DELAY:MOV R7 ,#05H //;延时LP8: MOV R6,#19HLP7:DJNZ R6,LP7DJNZ R7,LP8RET; DS18B20初始化汇编程序;*****************************************//MAIN2:LCALL DISP //;主程序SETB P3.2 // ;18B20DQ置1拉高LCALL INIT // ;调初始化MOV A,#0CCH //;跳过ROM匹配------0CCLCALL WRITE // ;调写DS18B20的程序MOV A,#44H // ;发出温度转换命令LCALL WRITE // ;调写DS18B20的程序MOV R6,#34H //;延时136微秒转换时间,写一个字约需70微秒。
DJNZ R6,$LCALL DISPLCALL INITMOV A,#0CCHLCALL WRITEMOV A,#0BEH // ;发出读温度命令LCALL WRITELCALL READCLR CLCALL CONVTEMPLCALL DISPBCDLCALL DISPSJMP MAIN2WRITE:MOV R0,#8 // ;写子程序CLR CWR1: CLR P3.2MOV 20H,#3 // ;延时17微秒DJNZ 20H,$RRC AMOV P3.2,CMOV 21H,#10 // ;发送后延时45微秒DJNZ 21H,$SETB P3.2NOPDJNZ R0,WR1 // ;8位未发送完转SETB P3.2RETREAD: MOV R6,#2 // ;读子程序CLR PSW.5 // ;清清标志F0RE0:MOV R2,#8RE1:CLR CSETB P3.2 // ;拉高DQNOP // ;延时2微秒CLR P3.2 // ;拉低DQSETB P3.2MOV 22H,#3RE2:DJNZ 22H,RE2MOV C,P3.2MOV 23H,#10RE3:DJNZ 23H,RE3RRC ADJNZ R2,RE1 //;8位未读完继续读CPL PSW.5JNB PSW.5,RE4 // ;高8位保存至28HMOV 29H,A // ;低8位及小数保存至29HRE4:MOV 28H,ADJNZ R6,RE0 //;高8位未读继续RETINIT:SETB P3.2 // ;初始化开始DQ置1(整个时隙和理论值不是很准确)NOP //;延时L0:CLR P3.2 // ;DQ拉低MOV 24H,#100 // ;延时400微秒DJNZ 24H,$SETB P3.2 // ;DQ拉高MOV 25H,#10 // ;置40微秒延时常数L01:JNB P3.2,L2 // ;有18B20响应转L2DJNZ 25H,L01 // ;无18B20响应等待40微秒SJMP L0 // ;无18B20重新初始化L2:MOV R7,#60 // ,延时240微秒L3:DJNZ R7,L3SETB P3.2 //;DQ拉高、退出RETCONVTEMP:MOV A,28H //;温度转换ANL A,#80H //;温度正负判别JZ TEMPC1 //;温度为正转CLR C // ;温度为负调整MOV A,29HCPL AADD A,#01HMOV 29H,AMOV A,28HCPL AADDC A,#00HMOV 28H,AMOV 26H,#0BH // ;温度为负26H内送#0BHSJMP TEMPC11TEMPC1:MOV 26H,#0AH //;温度为正26H内送#0AHTEMPC11:MOV A,26HSWAP AMOV 26H,A // ;26H高4位为温度符号MOV A,29H // ;取温度小数部分ANL A,#0FH ;去整数个位MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV 27H,A // ;查表得小数值,并保存至27H单元MOV A,29H // ;温度整数部分拼装后暂时存入AANL A,#0F0H // ;留下整数个位SWAP AMOV 29H,AMOV A,28HANL A,#0FHSWAP AHEX2BCD1:MOV B,#64H // ;温度整数部分除100得整数百位,并存入R7中DIV ABMOV R7,A // ;R7中为百位,B中为十位和个位MOV A,#0AH // ;温度整数部分除10得整数十位和个位XCH A,B // ;除数与被除数交换DIV ABSWAP AORL A,BTEMPC10:MOV 29H,A // ;温度十位和个位存入29H单元中,十位在高4位,个位在低4位ANL A,#0F0H // ;取温度十位SWAP AORL A,26H //;十位加温度符号存入26H单元;高4位为符号MOV 26H,AMOV A,29HANL A,#0FH // ;取温度个位SWAP AORL A,27HMOV 27H,A // ;27H单元中高4位为个位,低4位为小数MOV A,R7JZ TEMPC12 // ;百位为0退出ANL A,#0FH // ;百位不为0即温度为正和十位重新拼装后存入26H,高4位为百位SWAP A // ;MOV R7,AMOV A,26HANL A,#0FH ; // ;去除26H单元的符号ORL A,R7 //;百位和十位拼装,放入26H单元高4位为百位MOV 26H,A // ;低4位为十位TEMPC12:RETDOTTAB:DB 00H,01H,01H,02H,03HDB 03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09HDISPBCD:MOV A,27H // ;BCD码转换ANL A,#0FHMOV 70H,A // ;取小数,并保存在70H中SWAP AANL A,#0FHMOV 71H,A // ;取整数个位,并保存在71H中MOV A,26HANL A,#0FHMOV 72H,A //;取整数十位,并保存在72H中MOV A,26HSWAP AANL A,#0FHMOV 73H,A // ;取整数百位,并保存在73H中MOV A,72H //;取整数十位ANL A,#0F0HCJNE A,#00H,DISPBCD2SJMP DISPBCD2DISPBCD0:MOV A,26H // ;取整数百位ANL A,#0F0HCJNE A,#00H,DISPBCD2 //;百位不等于0退出MOV A,26HSW AP AANL A,#0FH //;十位保留符号MOV 73H,#0AHMOV 72H,ADISPBCD2:RETDISP:MOV R1,#70H // ;显示子程序MOV R5,#11101111B // ;送Y4位码PLAY:MOV P0,#0FFH // ;关段码MOV A,R5 // ;取Yn位码MOV P2,A // ;送位码MOV A,@R1 //;取段码MOV DPTR,#TABMOVC A,@A+DPTRMOV P0,A // ;送段码MOV A,R5JB ACC.5,LOOP1 // ;位码未指向Y2(整数个位)转CLR P0.7 ;;开小数点LOOP1:LCALL DL1MS //;调显示延时INC R1 // ;指向下一位显示段码MOV A,R5 ;取显示位码JNB ACC.7,ENDOUTRL A // ;向下一位位码MOV R5,AAJMP PLAYENDOUT:MOV P0,#0FFHMOV P3,#0FFHRETTAB: DB 0C0H,0F9H,0A4H,0B0HDB 99H,92H,82H,0F8HDB 80H,90H,0FFH,0BFHDL1MS:MOV R6,#14H // ;延时1mS DL1: MOV R7,#19HDL2: DJNZ R7,DL2DJNZ R6,DL1RETEND。
C++写的控制DS18B20温度传感器的代码
这是用C++写的控制DS18B20温度传感器的代码1#include <reg51.H>2#include<intrins.h>3#include <math.H> //要用到取绝对值函数abs()4//通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度5sbit wela = P2^7; //数码管位选6sbit dula = P2^6; //数码管段选7sbit ds = P2^2;8int tempValue;910//0-F数码管的编码(共阴极)11unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,12 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};13//0-9数码管的编码(共阴极), 带小数点14unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,15 0x87, 0xff, 0xef};1617//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.18void delay(unsi gned int i)19{20 unsigned int j;21 while(i--)22 {23 for(j = 0; j < 125; j++);24 }25}2627//初始化DS18B2028//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动29void dsInit()30{31 //对于11.0592MHz时钟, unsi gned int型的i, 作一个i++操作的时间大于为8us32 unsigned int i;33 ds = 0;34 i = 100; //拉低约800us, 符合协议要求的480us以上35 while(i>0) i--;36 ds = 1; //产生一个上升沿, 进入等待应答状态37 i = 4;38 while(i>0) i--;39}4041void dsWait()42{43 unsigned int i;44 while(ds);45 while(~ds); //检测到应答脉冲46 i = 4;47 while(i > 0) i--;48}4950//向DS18B20读取一位数据51//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 52//之后DS18B20则会输出持续一段时间的一位数据53bit readBit()54{55 unsigned int i;56 bit b;57 ds = 0;58 i++; //延时约8us, 符合协议要求至少保持1us59 ds = 1;60 i++; i++; //延时约16us, 符合协议要求的至少延时15us以上61 b = ds;62 i = 8;63 while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求64 return b;65}6667//读取一字节数据, 通过调用readBit()来实现68unsigned char readByte()69{70 unsigned int i;71 unsigned char j, dat;72 dat = 0;73 for(i=0; i<8; i++)74 {75 j = readBit();76 //最先读出的是最低位数据77 dat = (j << 7) | (dat >> 1);78 }79 return dat;80}8182//向DS18B20写入一字节数据83void writeByte(unsigned char dat)84{85 unsigned int i;86 unsigned char j;87 bit b;88 for(j = 0; j < 8; j++)89 {90 b = dat & 0x01;91 dat >>= 1;92 //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写193 if(b)94 {95 ds = 0;96 i++; i++; //拉低约16us, 符号要求15~60us内97 ds = 1;98 i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求99 }100 else //写"0", 将DQ拉低60us~120us101 {102 ds = 0;103 i = 8; while(i>0) i--; //拉低约64us, 符号要求104 ds = 1;105 i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了106 }107 }108}109110//向DS18B20发送温度转换命令111void sendChangeCmd()112{113 dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化114 dsWait(); //等待DS18B20应答115 delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号116 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom117 writeByte(0x44); //写入温度转换命令字 Convert T118}119120//向DS18B20发送读取数据命令121void sendReadCmd()122{123 dsInit();124 dsWait();125 delay(1);126 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom127 writeByte(0xbe); //写入读取数据令字 Read Scratchpad128}129130//获取当前温度值131int getTmpValue()132{133 unsigned int tmpvalue;134 int value; //存放温度数值135 float t;136 unsigned char low, high;137 sendReadCmd();138 //连续读取两个字节数据139 low = readByte();140 high = readByte();141 //将高低两个字节合成一个整形变量142 //计算机中对于负数是利用补码来表示的143 //若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的val ue144 tmpvalue = high;145 tmpvalue <<= 8;146 tmpvalue |= low;147 value = tmpvalue;148149 //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度150 t = value * 0.0625;151 //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入152 //如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度153 //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度154 value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5155 return val ue;156}157158unsi gned char const timeCount = 3; //动态扫描的时间间隔159//显示当前温度值, 精确到小数点后一位160//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码161void di splay(int v)162{163 unsigned char count;164 unsigned char datas[] = {0, 0, 0, 0, 0};165 unsigned int tmp = abs(v);166 datas[0] = tmp / 10000;167 datas[1] = tmp % 10000 / 1000;168 datas[2] = tmp % 1000 / 100;169 datas[3] = tmp % 100 / 10;170 datas[4] = tmp % 10;171 if(v < 0)172 {173 //关位选, 去除对上一位的影响174 P0 = 0xff;175 wela = 1; //打开锁存, 给它一个下降沿量177 //段选178 P0 = 0x40; //显示"-"号179 dula = 1; //打开锁存, 给它一个下降沿量180 dula = 0;181182 //位选183 P0 = 0xfe;184 wela = 1; //打开锁存, 给它一个下降沿量185 wela = 0;186 delay(timeCount);187 }188 for(count = 0; count != 5; count++)189 {190 //关位选, 去除对上一位的影响191 P0 = 0xff;192 wela = 1; //打开锁存, 给它一个下降沿量193 wela = 0;194 //段选195 if(count != 2)196 {197 /**//* if((count == 0 && datas[count] == 0)198 || ((count == 1 && datas[count] == 0) && (count == 0 && datas[count - 1] == 0))) 199 {200 P0 = 0x00; //当最高位为0时, 不作显示201 }202 else*/203 P0 = table[datas[count]]; //显示数字204 }205 else206 {207 P0 = tableWi dthDot[datas[count]]; //显示带小数点数字208 }209 dula = 1; //打开锁存, 给它一个下降沿量210 dula = 0;211212 //位选213 P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管214 wela = 1; //打开锁存, 给它一个下降沿量215 wela = 0;216 delay(timeCount);217 }218}219221{222 unsigned char i;223224 while(1)225 {226 //启动温度转换227 sendChangeCmd();228 //显示5次229 for(i = 0; i < 40; i++)230 {231 display(tempValue);232 }233 tempValue = getTmpValue(); 234 }235}。
ds18b20温度检测程序(C语言)
//18B20单线温度检测的应用样例程序#include<REG52.H>#include<math.h>#include<INTRINS.H>#include<stdio.h>#define uchar unsigned char#define uint unsigned int;/*****************************************************************************/ sbit seg1=P2^0;sbit seg2=P2^1;sbit seg3=P2^2;sbit DQ=P1^7;//ds18b20 端口sfr dataled=0x80;//显示数据端口/**********************************************************************/uchar temp;uchar flag_get,count,num,minute,second;uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数码管段码表共阳uchar str[3];/***********************************************************************/void delay1(uchar MS);unsigned char ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);void delay(unsigned int i);void INITchuangkou(void);//void Initdingshiqi1(void);/************************************************************************/main(){TMOD|=0x21;//定时器设置TH0=0xef;TL0=0xf0;EA=1;TR0=1;//Initdingshiqi1();INITchuangkou();P2=0x00;count=0;while(1){str[2]=0x39;//显示C符号str[0]=tab[temp/10]; //十位温度str[1]=tab[temp%10]; //个位温度if(flag_get==1) //定时读取当前温度{temp=ReadTemperature();printf("%d",temp);flag_get=0;}}}void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效second++;if(second>=60){second=0;minute++;}}count++;if(count==1){P2=0;dataled=str[0];}//数码管扫描if(count==2){P2=1;dataled=str[1];}if(count==3){ P2=2;dataled=str[2];count=0;}}/******************************************************************************void delay(unsigned int i)//延时函数{while(i--);}/****************************************************************************** *********///18b20初始化函数void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(5);}//读一个字节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(5);}return(dat);}//写一个字节void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}delay(5);}//读取温度unsigned char ReadTemperature(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;//float tt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar();b=ReadOneChar();b<<=4;b+=(a&0xf0)>>4;t=b;//tt=t*0.0625;//t= tt*10+0.5; //放大10倍输出并四舍五入return(t);}void INITchuangkou(void){SCON=0X50;TH1=0XFD;TR1=1;TI=1;}/*void Initdingshiqi1(void);{TMOD=0X11;TH1=0XFD;TL1=0XFD; TR1=1;}*/。
DS18B20程序设计代码实例
#include<atmel\at89x52.h>#include<intrins.h>#include<stdio.h>#include<string.h>#include"ds18b20.h"#include"ser.h"#define TRUE 1#define FALSE !TRUEstatic unsigned char Next(void);xdata signed int Ds18b20_resault[MAXDS18b20];static xdata unsigned char numDS18B20s=0;static unsigned char xdata ROMCODE[MAXDS18b20][8];/*{{0x28,0xb3 ,0x96 ,0x30 ,0x00 ,0x00,0x00,0x23},{0x28,0x2b ,0x21 ,0x30 ,0x00 ,0x00,0x00,0x2d},};*///xdata signed int Ds18b20_resault[MAXDS18b20];static xdata char tmpbuf[100] ;static unsigned char DS18b20_chanle=0;/****************************************************************************** //* DS18B20 TEMPERA TURE CONVERSION*//* FileName: DS18B20.C*//* Purpose: to illustrate the effectiveness of the ccs C Compiler *//* History: 2002-3-26 Designed By Jinag_Zhi_Hong*//* History: 2002-6-5 modifed Designed By 郝太忠*//****************************************************************************** /#define DQ P1_0unsigned char Ds18b20_present(void){bit presence;unsigned char i;DQ=0;i=230;while(--i);DQ=1;i = 35; while(--i);presence=!DQ;i =200;while(--i);if(presence) {// wrt_string("Ds18b20_present OK\n\r");return (TRUE);}else// wrt_string("Ds18b20_present ERR!!!\n\r");return(FALSE); /* presence signal returned 1=presence, 0 = no part */}//////////////////////////////////////////////////////////////////////////////// READ_BIT - reads a bit from the one-wire bus. The delay// required for a read is 15us, so the DELAY routine won't work.// We put our own delay function in this routine in the form of a// for() loop.//unsigned char Ds18b20_read_bit(void){unsigned char i,c;DQ = 0; _nop_(); _nop_();DQ=1;i = 8; while(--i);c=(unsigned char ) DQ;i = 25;while(--i);return( c ); // return value of DQ line}//////////////////////////////////////////////////////////////////////////////// WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.//void Ds18b20_write_bit(unsigned char bitval){unsigned char i;DQ=0;if(1==bitval&0x01) DQ=1;// return DQ high if write 1i = 25; while(--i);DQ=1;}// Delay provides 16us per loop, plus 24us. Therefore delay(5) = 104us/******************************************************************/ /* READ_BYTE - reads a byte from the one-wire bus.*//******************************************************************/ unsigned char Ds18b20_read_byte(void){unsigned char i,j;unsigned char temp = 0;// EA = 0;for (i=0;i<8;i++){DQ = 0; _nop_(); _nop_();DQ = 1;j = 8; while(--j);j = DQ;temp>>=1;if (j) temp|=0x80;j = 25;while(--j); /* wait forrest of timeslot */}// EA = 1;return(temp);}/******************************************************************/ /* WRITE_BYTE - writes a byte to the one-wire bus.*//******************************************************************/unsigned char Ds18b20_write_byte(unsigned char val){unsigned char i,j;unsigned char temp;for (i=0; i<8; i++) /* writes byte, one bit at a time */ {temp = val&0x01;DQ = 0;if (temp) DQ = 1;val>>=1;j = 25; while(--j);DQ = 1;}return (TRUE);}/*void Ds18b20_Read_ROMCode(void){unsigned char i;unsigned char xdata buf[10];unsigned char xdata *ptr;ptr=tmpbuf;if(Ds18b20_present()){Ds18b20_write_byte(0x33);for (i=0;i<9;i++){buf[i]=Ds18b20_read_byte();sprintf(ptr,"%02x,",(int)buf[i]);ptr += 3;}wrt_string(tmpbuf);}}*/void Ds18b20_Send_MatchRom(void){unsigned char i;Ds18b20_present();Ds18b20_write_byte(0x55);for(i=0;i<8;i++){Ds18b20_write_byte(ROMCODE[DS18b20_chanle][i]); }}void Ds18b20_Convert_commond(void){Ds18b20_present();// Ds18b20_Send_MatchRom();Ds18b20_write_byte(0xCC); //Skip ROMDs18b20_write_byte(0x44); // Start Conversion }void Ds18b20_Write_Scratchpad(void){unsigned char i;unsigned char buf[9];buf[2]=127;Ds18b20_present();Ds18b20_Send_MatchRom();// Ds18b20_write_byte(0xCC); //Skip ROM Ds18b20_write_byte(0x4E);for (i=0;i<3;i++){Ds18b20_write_byte(buf[i]);}}void Ds18b20_Copy_Scratchpad(void){Ds18b20_present();Ds18b20_Send_MatchRom();// Ds18b20_write_byte(0xCC); //Skip ROM Ds18b20_write_byte(0x48);}void Ds18b20_Read_ScratchPad(void){//byte i;int tmp;xdata unsigned char buf[9];Ds18b20_present();Ds18b20_Send_MatchRom();// Ds18b20_write_byte(0xCC); //Skip ROMDs18b20_write_byte(0xBE);for (tmp=0;tmp<9;tmp++){buf[tmp]=Ds18b20_read_byte();}if(buf[2] != 127) {Ds18b20_Write_Scratchpad();Ds18b20_Copy_Scratchpad();}tmp=buf[1]*256+buf[0];if(tmp<0) {Ds18b20_resault[DS18b20_chanle] = -( (~tmp) + 1);}else {Ds18b20_resault[DS18b20_chanle]=tmp;}// sprintf(tmpbuf,"Ds18b20_resault[%d]=%ld\n\r",(int)DS18b20_chanle,Ds18b20_resault[DS18b20_chanle]);// wrt_string(tmpbuf);}////////////////////////////////////////////////////////////////////////////// GLOBAL V ARIABLES//static unsigned char xdata ROM[8]; // ROM Bitstatic unsigned char lastDiscrep = 0; // last discrepancystatic unsigned char doneFlag = 0; // Done flagstatic unsigned char xdata FoundROM[10][8]; // table of found ROM codes static unsigned char numROMs;static unsigned char dowcrc;static code const unsigned char dscrc_table[] = {0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 };//////////////////////////////////////////////////////////////////////////////// ONE WIRE CRC//static unsigned char ow_crc( unsigned char x){dowcrc = dscrc_table[dowcrc^x];return dowcrc;}/*unsigned char Ds18b20_crc(unsigned char num,unsigned char *Src) {unsigned char i;unsigned char crcdata = 0;for ( i = 0; i < num-1; i++ ){crcdata = crcdata ^ (*Src); Src++;crcdata = dscrc_table[crcdata];}if (crcdata==*Src) return 1;else return 0;}*/// NEXT// The Next function searches for the next device on the 1-wire bus. If // there are no more devices on the 1-wire then false is returned.//static unsigned char Next(void){unsigned char m = 1; // ROM Bit indexunsigned char n = 0; // ROM Byte indexunsigned char k = 1; // bit maskunsigned char x = 0;unsigned char discrepMarker = 0; // discrepancy markerunsigned char g; // Output bitunsigned char nxt; // return valueunsigned char flag;nxt = FALSE; // set the next flag to falsedowcrc = 0; // reset the dowcrcflag =!Ds18b20_present(); // reset the 1-wireif(flag||doneFlag) // no parts -> return false{lastDiscrep = 0; // reset the searchreturn FALSE;}Ds18b20_write_byte(0xF0); // send SearchROM command// wrt_string("Ds18b20_funciton 0xF0\n\r");do// for all eight bytes{x = 0;if(1==Ds18b20_read_bit()) x = 2;if(1==Ds18b20_read_bit()==1) x |= 1; // and its complementif(x ==3) {// wrt_string("Ds18b20_funciton x=3\n\r");break;// there are no devices on the 1-wire}else {if(x>0) // all devices coupled have 0 or 1g = x>>1; // bit write value for searchelse{ // if this discrepancy is before the last discrepancy on a previous Next then pick// the same as last timeif(m<lastDiscrep)g = ((ROM[n]&k)>0);else g = (m==lastDiscrep); // if equal to last pick 1// if not then pick 0 if 0 was picked then record// position with mask kif (g==0) discrepMarker = m;}if(g==1) ROM[n] |= k;// isolate bit in ROM[n] with mask kelse ROM[n] &= ~k;Ds18b20_write_bit(g); // ROM search writem++; // increment bit counter mk <<= 1; // and shift the bit mask kif(k==0) // if the mask is 0 then go to new ROM{ // byte n and reset maskow_crc(ROM[n]); // accumulate the CRCn++; k++;}}} while(n<8); //loop until through all ROM bytes 0-7if(m<65||dowcrc) // if search was unsuccessful thenlastDiscrep=0; // reset the last discrepancy to 0else {// search was successful, so set lastDiscrep,// lastOne, nxtlastDiscrep = discrepMarker;doneFlag = (lastDiscrep==0);nxt = TRUE; // indicates search is not complete yet, more parts remain }return nxt;}//// FIRST// The First function resets the current state of a ROM search and calls// Next to find the first device on the 1-wire bus.//static unsigned char First(void){lastDiscrep = 0; // reset the rom search last discrepancy globaldoneFlag = FALSE;return Next(); // call Next and return its return value}// FIND DEVICESvoid FindDevices(void){unsigned char m;// xdata char ROMbuf[100];xdata char *ptr;unsigned char c;if(Ds18b20_present()) //Begins when a presence is detected{//wrt_string("Ds18b20_present ok\n\r");if(First()) //Begins when at least one part is found{// wrt_string("First ok\n\r");numROMs=0;do {numROMs++;for(m=0;m<8;m++){FoundROM[numROMs][m]=ROM[m]; //Identifies ROM number on found device}// strcpy(ROMbuf,"ROM CODE =");// ptr=ROMbuf+strlen(ROMbuf);for(c=0;c<8;c++) {ROMCODE[numDS18B20s][c]=FoundROM[numROMs][c];//// sprintf(ptr,"%02x,",(int)FoundROM[numROMs][c]);ptr+=3;}numDS18B20s++;// strcat(ROMbuf,"\n\r");// wrt_string(ROMbuf);}while (Next()&&(numROMs<10)); //Continues until no additional devices are found}}}//void Ds18b20_tsk(void ){// bDs18b20_TSK=FALSE;Ds18b20_Send_MatchRom();Ds18b20_Read_ScratchPad();Ds18b20_Convert_commond();DS18b20_chanle++;if(MAXDS18b20 <=DS18b20_chanle) DS18b20_chanle=0;}/*void disROMCODE (void){unsigned char c;xdata char dbuf[100];for(c=0;c<MAXDS18b20;c++){sprintf(dbuf,"ROMCODE =%02x %02x %02x %02x %02x %02x %02x %02x\n\r",(int)ROMCODE[c][0],(int)ROMCODE[c][1],(int)ROMCODE[c][2],(int)ROMCODE[c][3],(int)ROMCODE[c][4],(int)ROMCODE[c][5],(int)ROMCODE[c][6],(int)ROMCODE[c][7]);wrt_string(dbuf);}}*/。
完整DS18B20温度测控程序
#include<reg52.h>sbit s2=P0^0;sbit led=P1^3;unsigned char wendushangxian=0;sbit DQ=P1^6;sbit wei1=P3^0;sbit wei2=P3^1;sbit wei3=P3^2;sbit wei4=P3^3;sbit key_Max_jia=P0^0;sbit key_Max_jian=P0^1;sbit key_Min_jia=P0^2;sbit key_Min_jian=P0^3;sbit dianji_jian=P1^2;sbit dianji_jia=P1^7;sbit Led_tempreture_Max=P1^3;sbit Led_tempreture_Min=P1^4;sbit Led_normal=P1^5;unsigned char num[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; int tempreture_Max=40;int tempreture_Min=-10;void delay_mylself(int temp){unsigned int i,j;for(i=0;i<temp;i++)for(j=0;j<1140;j++);}void delay(unsigned int i) //如果i是unsigend char类型,则会出现错误结果{while(i--);}void DS18B20_Init(void)//初始化{unsigned char flag=0;DQ = 1; //DQ复位delay(1);DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480us小于960usDQ = 1; //拉高总线delay(6);while(DQ);while(!DQ);//flag=DQ; //稍做延时后如果flag=0则初始化成功flag=1则初始化失败//delay(30);}unsigned char Read(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(5);}return(dat);}void Write(unsigned char dat)//写字节{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}}void init(){wei1=0;wei2=0;wei3=0;wei4=0;}void Display(unsigned int temp){unsigned char one,two,three,four;int wendu=0;if(temp<=0xf000){ temp>>=4; //右移4位,相当于乘0.0625,将温度化为十进制//temp*=10; //扩大10倍,显示一位小数one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=temp;}else{temp=~temp;temp+=1;temp>>=4;one=10; //负数two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=-temp;}if(wendu>tempreture_Max){Led_tempreture_Max=0;Led_tempreture_Min=1;Led_normal=1;dianji_jian=1;dianji_jia=0;}else if(wendu<tempreture_Min){Led_tempreture_Max=1;Led_tempreture_Min=0;Led_normal=1;dianji_jia=1;dianji_jian=0;}else{Led_tempreture_Max=1;Led_tempreture_Min=1;Led_normal=0;dianji_jian=0;dianji_jia=0;}//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(1);//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(1);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(1);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(10);}void common_display(int temp){unsigned char one,two,three,four;one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位if(temp<0){temp=-temp;two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[10];delay_mylself(50);}else{//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(50);}//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(50);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(50);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(60);}void key(){unsigned char flag=0;if(key_Max_jia==0){flag=1;tempreture_Max+=1;if(tempreture_Max>125){tempreture_Max=125;}while(!key_Max_jia); //按键松手检测}else if(key_Max_jian==0){flag=2;tempreture_Max-=1;if(tempreture_Max<tempreture_Min){tempreture_Max=tempreture_Min;}while(!key_Max_jian); //按键松手检测}else if(key_Min_jia==0){flag=3;tempreture_Min+=1;if(tempreture_Min>tempreture_Max){tempreture_Min=tempreture_Max;}while(!key_Min_jia); //按键松手检测}else if(key_Min_jian==0){flag=4;tempreture_Min-=1;if(tempreture_Min<-55){tempreture_Min=-55;}while(!key_Min_jian); //按键松手检测}if(flag==1||flag==2){common_display(tempreture_Max);delay_mylself(200);flag=0;}else if(flag==4||flag==3){common_display(tempreture_Min);delay_mylself(200);flag=0;}}void main(){unsigned int temp;unsigned char tl=0,th=0;while(1){DS18B20_Init();Write(0xCC); // 跳过读序号列号的操作Write(0x44); // 启动温度转换delay(100);DS18B20_Init();Write(0xCC); //跳过读序号列号的操作Write(0xBE); //读取温度寄存器等delay(100);tl=Read(); //读取温度值低位th=Read(); //读取温度值高位temp=th<<8;temp|=tl;Display(temp);key();}}。
基于ds18b20的温度计设计代码
基于DS18B20的温度计设计代码一、介绍DS18B20温度计DS18B20是一种数字温度传感器,由美国达拉斯半导体公司生产。
它采用单总线通信协议,并可以通过单总线接口进行多级串联。
DS18B20具有精度高、稳定性好、响应速度快等特点,因此在各种温度测量应用中被广泛使用。
二、DS18B20温度计设计代码在使用DS18B20温度传感器时,我们通常需要编写相应的代码来读取传感器的数据并进行温度计算。
以下是基于Arduino评台的DS18B20温度计设计代码:```c#include <OneWire.h>#include <DallasTemperature.h>#define ONE_WIRE_BUS 2 // 设置DS18B20数据线连接的Arduino 引脚OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup() {Serial.begin(9600);sensors.begin();}void loop() {sensors.requestTemperatures(); // 发送获取温度命令float temperatureC = sensors.getTempCByIndex(0); // 获取温度值(摄氏度)float temperatureF = sensors.toFahrenheit(temperatureC); // 转换为华氏度Serial.print("Temperature: ");Serial.print(temperatureC);Serial.print("°C / ");Serial.print(temperatureF);Serial.println("°F");delay(1000); // 延时1s}```以上代码使用了OneWire库和DallasTemperature库来实现对DS18B20的温度测量。
单片机DS18B20温度传感器C语言程序含CRC校验
单片机中使用DS18B20温度传感器C语言程序(参考1)/******************************************************************************** DS18B20 测温程序硬件:AT89S52(1)单线ds18b20接 P2.2(2)七段数码管接P0口(3)使用外部电源给ds18b20供电,没有使用寄生电源软件:Kei uVision 3**********************************************************************************/ #include "reg52.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intsbit ds=P2^2;sbit dula=P2^6;sbit wela=P2^7;uchar flag ;uint temp; //参数temp一定要声明为 int 型uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点数字编码/*延时函数*/void TempDelay (uchar us){ while(us--); }void delay(uint count) //延时子函数{ uint i;while(count){ i=200;while(i>0)i--;count--; } }/*串口初始化,波特率9600,方式1 */void init_com(){ TMOD=0x20; //设置定时器1为模式2TH1=0xfd; //装初值设定波特率TL1=0xfd;TR1=1; //启动定时器SM0=0; //串口通信模式设置SM1=1;// REN=1; //串口允许接收数据PCON=0; //波特率不倍频// SMOD=0; //波特率不倍频// EA=1; //开总中断//ES=1; //开串行中断}/*数码管的显示 */void display(uint temp){ uchar bai,shi,ge;bai=temp/100;shi=temp%100/10;ge=temp%100%10;dula=0;P0=table[bai]; //显示百位dula=1; //从0到1,有个上升沿,解除锁存,显示相应段dula=0; //从1到0再次锁存wela=0;P0=0xfe;wela=1;wela=0;delay(1); //延时约2msP0=table1[shi]; //显示十位dula=1;dula=0;P0=0xfd;wela=1;wela=0;delay(1);P0=table[ge]; //显示个位dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(1); }/*****************************************时序:初始化时序、读时序、写时序。
DS18B20测温程序
//温度高于26摄氏度则蜂鸣器响#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbitdula=P2^6;sbitwela=P2^7;sbit beer=P2^3; //控制蜂鸣器sbitdsb=P2^2; //ds18b20的数据总线sbitrs=P3^5; //液晶显示数据命令选择端口sbitlcme=P3^4; //液晶显示使能信号sbit key=P3^7;uint temp; //温度传感器测得的温度uchar code listone[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};ucharcodelisttwo[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; ucharcodelistthree[]={"The temp is under:"};void delay(uchari){while(--i);}Voiddelayone(uint z){uintx,y;for(x=100;x>0;x--)for(y=z;y>0;y--);}/*液晶显示写命令初始化*/ Voidwritecom(uchar com) {rs=0;delayone(2);lcme=0;P0=com;lcme=1;delayone(2);lcme=0;}/*液晶显示写数据初始化*/ void writebyte(uchar byte) {rs=1;delayone(2);lcme=0;P0=byte;lcme=1;delayone(2);lcme=0;}/*液晶显示初始化*/ void ds18b20init() {uinttempone;uinti;dula=0;wela=0;lcme=0;writecom(0x38);writecom(0x0f);writecom(0x06);writecom(0x80);for(i=0;i<16;i++){writebyte(listthree[i]);delayone(2);}writecom(0x80+0x40);for(i=0;i<16;i++){tempone=temp&0x80;writebyte(tempone);delay(2);temp<<=1;}writecom(0x0c);}/*温度传感器初始化*/ voidtempinit(){dsb=1;delay(1);dsb=0;delay(250);dsb=1;delay(100);}voidwritedata(uchardat) {uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();dsb=dat&0x01;delay(10);dat>>=1;delay(1);}dsb=1;}ucharreaddata(){uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();// date>>=1;dsb=1;delay(1);date>>=1; //右移放于此处也可以if(dsb==1)date|=0x80;delay(10);}return date;}uint control(){floattt;// uint temp;tempinit();writedata(0xcc);writedata(0x44);tempinit();writedata(0xcc);writedata(0xbe);a =readdata();b = readdata();temp = b;temp<<= 8;temp = temp|a;tt = temp*0.0625;temp = tt*100+0.05;return temp;}voidshuma(uint temp) {ucharbai,shi,ge,xiaoshu; bai=(temp/1000);shi=temp%1000/100; ge=temp%100/10; xiaoshu=temp%10;dula=1;P0=listone[bai];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delayone(1);dula=1;P0=listtwo[shi];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayone(1);dula=1;P0=listone[ge];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delayone(1);dula=1;P0=listone[xiaoshu];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(10);}void warning(uint temp){if((temp>=2600)&&(temp<2800)&&(key==1)){beer=0;P1=0x55;delayone(4);}if((key==0)||(temp<2600)){delayone(5);if((key==0)||(temp<2600)){beer=1;P1=0xff;}}}void main(){while(1){if(temp<2600){shuma(control());}if((temp>=2600)&&(temp<2800)){shuma(control());warning(temp);}if(temp>=2800){dula=0;wela=0;P0=0xff;}}}。
DS18B20温度传感器程序
{ LCD_ShowNumber(1,10,DS18B20_Read()); LCD_ShowNumber(0,10,DS18B20_Check());
} } #endif
/****************************************************************************** * File name:DS18B20.c Author:zzm Data:2011.12.13 Description:DS18B20 测温传感器的控制 Version:Thermostat V1.0 History: Others:测量范围为 -55 ℃ ~+ 125 ℃ ******************************************************************************* / #include"System_cfg.h"
void DS18B20_Ready(void) {
DS18B20_Init();
/*跳过读序号列号的操作*/ DS18B20_WriteByte(0xCC);
/*启动温度转换*/ DS18B20_WriteByte(0x44);
/*等待转换完成*/ while (!DQ);
DS18B20_Init(); DS18B20_WriteByte(0xCC);
/*对负温度的特殊处理*/ if((TH&0xf8)!=0x00)
{ flag=1; TL=~TL; TH=~TH; TL=TL+1;
/*如果低 8 位大于 255,向高 8 位进 1*/ if(TL>255)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
*输出:无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
uchar x,j;
for(j=0;j<i;j++)
/********************************************************************
*名称: delay()
*功能:延时函数
*输入:无
*输出:无
***********************************************************************/
P2 = 6;
Delay_1ms(5);
P0 = table[temp%10];
P2 = 7;
Delay_1ms(5);
}
}
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define jump_ROM 0xCC
*名称: Main()
*功能:主函数
*输入:无
*输出:无
***********************************************************************/
void main()
{
uint temp;
P2 = 0x00;
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;
P0 = table[temp/10%10];
*输出:无Байду номын сангаас
***********************************************************************/
void write_bit(uchar bitval)
{
DQ=0;if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}
/********************************************************************
/********************************************************************
*文件名:温度采集DS18B20.c
*描述:该文件实现了用温度传感器件DS18B20对温度的采集,并在数码管上显示出来。
*创建人:东流,2012年2月10日
*版本号:2.0
void delay(uint N)
{
int i;
for(i=0; i<N; i++)
;
}
/********************************************************************
*名称: Delay_1ms()
*功能:延时子程序,延时时间为1ms * x
for(x=0;x<=148;x++);
}
/********************************************************************
*名称: Reset()
*功能:复位DS18B20
*输入:无
*输出:无
***********************************************************************/
{
uchar i,temp;
for(i=0; i<8; i++)
{
temp = val >> i;
temp = temp & 0x01;
write_bit(temp);
delay(5);
}
}
/********************************************************************
*名称: read_byte()
*功能:从DS18B20读一个字节
*输入:无
*输出:从DS18B20读到的值
***********************************************************************/
uchar read_byte(void)
{
uchar i,m,receive_data;
*名称: read_bit()
*功能:从DS18B20读一个位值
*输入:无
*输出:从DS18B20读出的一个位值
***********************************************************************/
uchar read_bit(void)
{
uchar i;
#define start 0x44
#define read_EEROM 0xBE
sbit DQ = P2^3; //DS18B20数据口
unsigned char TMPH,TMPL;
uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
DQ = 0;
DQ = 1;
for(i=0; i<3; i++);
return(DQ);
}
/********************************************************************
*名称: write_bit()
*功能:向DS18B20写一位
*输入: bitval(要对DS18B20写入的位值)
*名称: write_byte()
*功能:向DS18B20写一个字节
*输入: val(要对DS18B20写入的命令值)
*输出:无
***********************************************************************/
void write_byte(uchar val)
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);
}
/********************************************************************
uchar Reset(void)
{
uchar deceive_ready;
DQ = 0;
delay(29);
DQ = 1;
delay(3);
deceive_ready = DQ;
delay(25);
return(deceive_ready);
}
/********************************************************************