[PIC16F877A+汇编语言]DS18B20温度采集程序
DS18B20温度检测程序
(1)先将数据线置高电平“1”。
(2)延时(该时间要求的不是很严格,但是尽可能的短一点)(3)数据线拉到低电平“0”。
(4)延时750微秒(该时间的时间范围可以从480到960微秒)。
(5)数据线拉到高电平“1”。
(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。
据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。
(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。
(8)将数据线再次拉高到高电平“1”后结束。
(1)数据线先置低电平“0”。
(2)延时确定的时间为15微秒。
(3)按从低位到高位的顺序发送字节(一次只发送一位)。
(4)延时时间为45微秒。
(5)将数据线拉到高电平。
(6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。
(7)最后将数据线拉高。
DS18B20的写操作时序图如图DS18B20的读操作(1)将数据线拉高“1”。
(2)延时2微秒。
(3)将数据线拉低“0”。
(4)延时15微秒。
(5)将数据线拉高“1”。
(6)延时15微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时30微秒。
DS18B20的读操作时序图如图所示。
DS18B20的Protues仿真图源程序代码:#include "reg51.h"#include "intrins.h" // 此头文件中有空操作语句NOP 几个微秒的延时可以用NOP 语句,但本人没用NOP,直接用了I++来延时#define uchar unsigned char#define uint unsigned intuchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};sbit ds18b20_io=P2^0; //单片机与DS18B20的连接口sbit lcdrs=P2^6; //1602与单片机的接口sbit lcden=P2^7;unsigned char flag,tflag,i;unsigned int temper0,temper1,tvalue;float temperature;void delay() //6us 在KEIL中仿真出来的时间,这是调用DELAY所用的时间{i++;i++;}void Delay_50us(unsigned char t) //50us延时程序{unsigned char j;for(;t>0;t--)for(j=20;j>0;j--);}void delay1(uint z) //这个延时主要用在1602中,1602的读写时序没有//DS18B20那么严格{uint x,y;for(x=0;x<z;x++){ for(y=0;y<121;y++){;};};}uchar ds18b20_rst(){unsigned char j;ds18b20_io=1;i++; //1usds18b20_io=0;for(j=0;j<60;j++) //543us{delay();}ds18b20_io=1;for( j=0;j<7;j++) //65us{delay();}if(!ds18b20_io) //如果读到低电平,即复位成功{flag=1;}else flag=0; //如果没有读到低电平,则复位失败Delay_50us(9); //450usds18b20_io=1;return flag;}void ds18b20_writebyte(unsigned char byte){unsigned char j;for(j=0;j<8;j++){ds18b20_io=1;i++;ds18b20_io=0;delay(); //15usdelay();i++;i++;i++;ds18b20_io=byte&0x01;delay(); delay();delay();delay(); //48usdelay(); delay();delay();byte>>=1;ds18b20_io=1;delay();}ds18b20_io=1;}unsigned char ds18b20_readbyte() {unsigned char k,jj,i;jj=0;for(k=0;k<8;k++){ds18b20_io=1;i++; i++;ds18b20_io=0;delay(); //15usdelay(); i++;i++;i++;ds18b20_io=1;delay(); //15usdelay(); i++; i++;i++;if(ds18b20_io) //17us jj=(jj>>1)|0x80;elsejj>>=1;delay();delay(); delay(); //18us }return jj;}void write_com(uchar com){lcdrs=0;P1=com;delay1(5);lcden=1;delay1(5);lcden=0;}void write_data(uchar date){lcdrs=1;P1=date;delay1(5);lcden=1;delay1(5);lcden=0;}void init(){lcden=0;write_com(0x38);write_com(0x0C);write_com(0x06);write_com(0x01);}float read_temp()/*读取温度值并转换*/{if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ ds18b20_writebyte(0x44);//*启动温度转换*/ Delay_50us(30);}if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ds18b20_writebyte(0xbe);//*读取温度*/temper0 =ds18b20_readbyte();temper1 =ds18b20_readbyte();Delay_50us(20);}if(temper1&0xf8) //判断是正温度还是负温度{ //如果是高5位是0 为正温度,反则为负温度tflag=1;tvalue=(temper1<<8)|temper0;tvalue=((~tvalue)+1);temperature=tvalue*(0.0625);}else{tflag=0;tvalue=(temper1<<8)|temper0;temperature=tvalue*0.0625; //不用把tvalue进行转换,直接乘0.0625//的精度}return(temperature);}void write_xian(float date){uint bai,shi,ge,xiaozheng,xqian,xbai,xshi,xge;float k,m; //把浮点的DATA转换为整数,得到浮点娄的整数部分bai=(int)(date)/100; //把得到的整数部分拆开分别存在BAI SHI GE 中shi=((int)(date)%100)/10;ge=(int)(date)%10;if (bai!=0) //如果百不为0 则把整数部分全部显示{write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}else if (shi!=0) //如果十不为0 则把十位和个位显示{write_data(0x30+shi);write_data(0x30+ge);}else write_data(0x30+ge);//如果百和十位都为0 ,则只显示个位数write_data(0x2e);k=date-(int)date; //取浮点娄的小数部分m=k*10000; //把得到的小数变为整数并显示xiaozheng=(int)m;xqian=(xiaozheng)/1000;xbai=((xiaozheng)%1000)/100;xshi=((xiaozheng)%100)/10;xge=(xiaozheng)%10;write_data(0x30+xqian);write_data(0x30+xbai);write_data(0x30+xshi);write_data(0x30+xge);}void main(){temperature=0.0;flag=0;tflag=0;tvalue=0;init();while(1){read_temp();if(tflag==0){write_xian(temperature); write_data(' '); write_data(' '); }if(tflag==1){write_data('-');write_xian(temperature); write_data(' '); write_data(' '); }write_com(0x80);}}。
基于PIC16F877单片机与DS18B20的温度采集与显示
河北联合大学轻工学院QINGGONG COLLEGE, HEBEI UNITED UNIVERSITY 《PIC单片机课程设计》学生姓名:肖晓峰学号:201124520121学部:信息科学技术部专业班级:电信1指导教师:曹义2014年7 月 4 日本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICC C语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。
2.1 设计题目:基于PIC16F877单片机与DS18B20的温度采集与显示2.2 功能实现:实时温度显示,并具有超限报警功能。
输出显示采用LCD1602。
2.3 设计要求:自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus 仿真,最终可实现脱机运行。
三、设计原理说明3.2 显示模块如用LCD1602作为显示设备,要求显示屏分两行显示,第一行显示日期(年-月-日)和星期,第二行显示时间(时:分:秒)和温度。
显示秒由00一直加到59,分钟数也由00加到59,小时采用24小时制,由00加到23,如此循环显示。
3.3 按键模块按键用来作为时间调整。
要求至少设计4个按键,按键1作为设置键;按键2、按键3分别为增加、减少键,在设置键按下时,此两个按键方有效;按键4是确定键,在设置键按下时方才有效。
3.4 温度采集模块DS18B20是美国DALLAS公司推出的单总线数字温度传感器。
DS18B20内部集成了温敏元件、数据转换芯片、存储器芯片和计算机接口芯片等多功能模块。
其主要技术特点有:具有独特的单线接口方式;可以通过数据线供电,具有超低功耗工作方式;测温范围为-55℃~125℃,测温精度为0.5℃;温度转换精度9~12位可编程,直接将温度转换值以二进制数码的方式串行输出。
四、硬件原理图(含原理图、电路仿真图)图2电路仿真图五、软件设计(含流程图、带注释的程序清单)程序设计流程图主文件he//**********************************************/#include<pic.h>__CONFIG(0x3B31);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡//宏定义#define DQ RC1 //温度数据口#define DQ_HIGH() TRISC1=1#define DQ_LOW() TRISC1=0;DQ=0#define uchar unsigned char#define uint unsigned int#define RS RA0 //LCD功能选择位#define RW RA1 //读写选择#define EN RA2 //使能//变量定义int temper;char f = 0 ;uchar a1,a2,a3,a4;uchar Prompt[]="P1ress K1 - K3 To Start Demo Prog";//各种申明void init();void DelayMS(uint ms);uchar Busy_Check();void Write_LCD_Command(uchar cmd);void Write_LCD_Data(uchar dat);void Initialize_LCD();void ShowString(uchar x,uchar y,uchar *str);void Showword0(uchar x,uchar y,char word );void Showword1(char word );void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4);//18b20void delay(uint x);void delayus(uint,uchar);void init();void write_byte(uchar date);uchar read_byte();void get_tem();//***子函数****************************************///系统初始化函数void init(){ADCON1=0X07; //设置A口为普通数字口TRISA =0X00; //设置A口方向为输出TRISB =0x00;OPTION=0x00; //B口电阻上拉TRISC = 1;PORTC = 0x20;TRISD =0X00;TRISD =0x00;}//延时函数void delayus(uint x,uchar y){uint i;uchar j;for(i=x;i>0;i--);for(j=y;j>0;j--);}void delay(uint x){uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}//ds18b20复位函数void reset(){uchar st=1;DQ_HIGH(); //开始于高电平NOP();NOP(); //延时2uswhile(st){DQ_LOW();delayus(70,30); //750DQ_HIGH(); //释放总线delayus(4,4); //等70if(DQ==1) //应答判断st=1;elsest=0;delayus(50,10); //延时450}}//ds18b20写函数void write_byte(uchar date){uchar i,temp;DQ_HIGH(); //开始于高电平NOP();NOP();for(i=8;i>0;i--){temp=date&0x01;//01010101 //分位写入DQ_LOW();delayus(0,0); //15if(temp==1)DQ_HIGH();delayus(2,2); //45DQ_HIGH();date=date>>1;//00101010}}//ds18b20读函数uchar read_byte(){uchar i,date;static bit j;for(i=8;i>0;i--){date=date>>1;DQ_HIGH(); //开始于高电平NOP();NOP();DQ_LOW();NOP();NOP();NOP();NOP();NOP();NOP(); //6DQ_HIGH();NOP();NOP();NOP();NOP(); //4j=DQ; //读取总线if(j==1)date=date|0x80;//1000 0000delayus(1,1); //30 }return (date); //返回函数值}//温度读取处理函数void get_tem(){uchar tem1,tem2,num;float aaa;reset(); //复位write_byte(0xCC);//跳过ROMwrite_byte(0x44);//温度转换reset();write_byte(0xCC); //跳过ROMwrite_byte(0xBE); //温度传递tem1=read_byte(); //读取低8位tem2=read_byte();//读取高8位if(tem2>7) //符号判断{tem2=255-tem2;tem1=255-tem1;f=1;}else {f=0;}aaa=(tem2*256+tem1)*6.25*8; //转化为实际温度值temper=(int)aaa; //强行转化位整数a1=temper/1000; //十进制分位a2=temper%1000/100;a3=temper%100/10;a4=temper%10;if(a1>7||a1<5) RD7=1;else RD7=0;}//延时void DelayMS(uint ms) //毫秒{uchar i;while(ms--) for(i=0;i<120;i++);}//LCD忙检查函数uchar Busy_Check(){uchar LCD_Status;RS=0; //寄存器选择(0指令1数据)RW=1; //读状态寄存器EN=1; //开始读DelayMS(1);LCD_Status=PORTB;EN=0;return LCD_Status;}//写LCD命令函数void Write_LCD_Command(uchar cmd){// while((Busy_Check()&0x80)==0x80); //忙等待RS=0; //选择命令寄存器RW=0; //写EN=0;PORTB=cmd;EN=1;DelayMS(1);EN=0;}//LCD发送数据函数void Write_LCD_Data(uchar dat){// while((Busy_Check()&0x80)==0x80); //忙等待RS=1;RW=0;EN=0;PORTB=dat;EN=1;DelayMS(1);EN=0;}//LCD初始化函数void Initialize_LCD(){Write_LCD_Command(0x38);DelayMS(1); //38:数据长8位,两行显示,字体5*7点阵(80)Write_LCD_Command(0x01);DelayMS(1); //清屏Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关;0x0e 是开光标}//显示字符函数void Showword0(uchar x,uchar y,char word ) //y:行地址,x:列地址{if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置(x,0)第一行if(y==1) Write_LCD_Command(0xc0|x); // (x,1)第二行Write_LCD_Data(word+0x30); //str[i]等价于*(str+i)}//显示温度函数void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4){if(f){Showword0(0,0,-3 );} //负号Showword0(1,0,num1 ); //十位Showword0(2,0,num2 );Showword0(3,0,-2 ); //小数点Showword0(4,0,num3 );Showword0(5,0,num4 );DelayMS(5);}//主函数void main(){init(); //调用系统初始化函数Initialize_LCD(); //LCD初始化while (1){ get_tem(); //读取温度write_shuzi(a1,a2,a3,a4 ); //显示}}六、设计总结1 打好基础,清楚硬件工作原理,性能,以便于编程。
[PIC16F877A+汇编语言]DS18B20温度采集程序
[PIC16F877A+汇编语言]DS18B20温度采集程序DS18B20温度采集程序[PIC16F877A+汇编语言];六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_W DT_OFF&_HS_OSC;调试模式关闭,写保护,一半ROM可在线改写,EEPROM加密,低压编程关闭,掉电检测关闭,上电延时开,看门狗关,4M晶振HS 振荡CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000us DQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序*******************************MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源 BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOP CALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1 GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
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多路温度采集汇编程序
4路DS18B20温度显示汇编程序(可设置上下限和分路查看)作者蔡雄略;操作说明:;------------------------------------------;功能说明:模式选择键按下后,选择循环显示、分路查看,上限设置,下限设置功能;每按一次模式键,对应的模式指示灯会亮起。
;循环显示模式时候,每秒显示一下各路温度状况;分路查看时界面冻结每按一次+或-键进行各路切换;上限设置时每按一次+或-键对各路上限报警进行设置;下限设置时每按一次+或-键对各路下限报警进行设置;------------------------------------------仿真效果图:程序如下:;------------------------------------------;功能说明:模式选择键按下后,选择循环显示、分路查看,上限设置,下限设置功能;循环显示模式时候,每秒显示一下各路温度状况;分路查看时界面冻结每按一次+或-键进行各路切换;上限设置时每按一次+或-键对各路上限报警进行设置;下限设置时每按一次+或-键对各路下限报警进行设置;------------------------------------------;主程序S0EQU30H;50ms计数寄存器MODE_CONT EQU S0+1;模式计数器DS18B20_CONT EQU S0+2HI_TMP_SET_IN EQU S0+3;进水口LOW_TMP_SET_IN EQU S0+4HI_TMP_SET_OUT EQU S0+5;出水口LOW_TMP_SET_OUT EQU S0+6HI_TMP_SET_FRONT EQU S0+7;前后点HI_TMP_SET_BACK EQU S0+8TMP_IN EQU S0+12TMP_OUT EQU S0+13TMP_FRONT EQU S0+14TMP_BACK EQU S0+15DISPLAY_DATA EQU P0;LED数据口KEY_PORT EQU P3;按键口COM_TEMPERL_L BIT P2.7COM_TEMPERL_H BIT P2.6COM_TEMPERH_L BIT P2.5COM_TEMPERH_H BIT P2.4COM_DS18B20_NUM BIT P2.2LED_LOW_SET BIT P3.0LED_HI_SET BIT P3.1LED_CHECK BIT P3.2LED_NORMAL BIT P3.3IN_LED_ALARM_HI BIT P1.1;ININ_LED_ALARM_LOW BIT P1.3OUT_LED_ALARM_HI BIT P1.0;INOUT_LED_ALARM_LOW BIT P1.2FRONT_LED_ALARM_HI BIT P2.0BACK_LED_ALARM_HI BIT P2.1FLAG1BIT20H.5;DS18B20存在标志位DQ1BIT P1.7DQ2BIT P1.6DQ3BIT P1.5DQ4BIT P1.4TEMPER_L EQU28HTEMPER_H EQU27H;------------------------------------------ORG0000HAJMP STARTORG000BH;T0入口LJMP T_INT;------------------------------------------;START初始化;------------------------------------------ORG100HSTART:MOV TEMPER_L,#00HMOV TEMPER_H,#00HMOV MODE_CONT,#00HMOV DS18B20_CONT,#00HMOV HI_TMP_SET_IN,#100;进水口MOV LOW_TMP_SET_IN,#10MOV HI_TMP_SET_OUT,#100;出水口MOV LOW_TMP_SET_OUT,#10MOV HI_TMP_SET_FRONT,#100MOV HI_TMP_SET_BACK,#100CLR TMP_INCLR TMP_OUTCLR TMP_FRONTCLR TMP_BACKMOV S0,#00HMOV TMOD,#01HMOV TH0,#3CH;定时器0,模式1,定时时常50mS MOV TL0,#0B0HMOV IE,#82HMOV KEY_PORT,#0F8HSETB TR0;运行T0LCALL INIT_18B20;------------------------------------------;主函数;------------------------------------------MAIN:LCALL KEYLCALL GET_TEMPER;获取各路温度LCALL DISPLAY;调用显示程序LJMP MAIN;------------------------------------------;T0中服程序,实现1秒一次切换,同时1秒一次的比较各路温度是否超标;------------------------------------------;T0中服程序T_INT:PUSH ACCPUSH PSWMOV TH0,#3CH;定时器0,模式1,定时时常50mSMOV TL0,#0B0H;------------------------------NEXT:INC S0MOV A,S0CJNE A,#14H,ZDMOV S0,#00H;到1S后进行切换INC DS18B20_CONTMOV A,DS18B20_CONTCJNE A,#04H,ZDMOV DS18B20_CONT,#00HLCALL CHECK1;判断各路温度是否超标ZD:POP PSWPOP ACCRETI;-------------------------------------------;ALARM_CHECK;判断各路温度是否超标;-------------------------------------------CHECK1:MOV R0,TMP_INMOV R1,HI_TMP_SET_INLCALL ALARM_CALJZ ALARM_HI_NORMALSETB IN_LED_ALARM_HIJMP CHECK2ALARM_HI_NORMAL:CLR IN_LED_ALARM_HICHECK2:MOV R0,TMP_INMOV R1,LOW_TMP_SET_INLCALL ALARM_CALJNZ CCSETB IN_LED_ALARM_LOWJMP DDCC:CLR IN_LED_ALARM_LOW DD:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_OUTLCALL ALARM_CALJZ EESETB OUT_LED_ALARM_HIJMP DDDEE:CLR OUT_LED_ALARM_HI DDD:MOV R0,TMP_OUTMOV R1,LOW_TMP_SET_OUTLCALL ALARM_CALJNZ FFSETB OUT_LED_ALARM_LOWJMP GGFF:CLR OUT_LED_ALARM_LOW GG:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_FRONTLCALL ALARM_CALJZ HHSETB FRONT_LED_ALARM_HIJMP IIHH:CLR FRONT_LED_ALARM_HI II:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_BACKLCALL ALARM_CALJZ JJSETB BACK_LED_ALARM_HIJMP ALARM_RET1JJ:CLR BACK_LED_ALARM_HI ALARM_RET1:RET;------------------------------------------;R0=R1A=2,R0<R1A=0,R0>R1A=1 ;比较大小;------------------------------------------ALARM_CAL:;R0,R1MOV A,R0SUBB A,R1JC SMALLMOV A,#01HJMP COMP_RETSMALL:MOV A,#0HCOMP_RET:RET;------------------------------------------;显示子程序;时分秒显示;------------------------------------------DISPLAY:MOV DPTR,#TABMOV A,TEMPER_LMOV B,#10DIV ABMOV R4,AMOV R5,BMOV A,R5;温度低位MOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_TEMPERL_LLCALL DELAY5MSCLR COM_TEMPERL_LMOV A,R4MOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_TEMPERL_HLCALL DELAY5MSCLR COM_TEMPERL_HMOV A,TEMPER_H;温度高位MOV B,#10DIV ABMOV R4,AMOV R5,BMOV A,R5MOVC A,@A+DPTR;显示输出ANL A,#7FH;MOV DISPLAY_DATA,ASETB COM_TEMPERH_LLCALL DELAY5MSCLR COM_TEMPERH_LMOV A,R4MOVC A,@A+DPTRMOV DISPLAY_DATA,ASETB COM_TEMPERH_HLCALL DELAY5MSCLR COM_TEMPERH_HMOV A,DS18B20_CONTINC AMOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_DS18B20_NUMLCALL DELAY5MSCLR COM_DS18B20_NUMRET;------------------------------------------;键盘扫描程序;------------------------------------------KEY:;KEY_PORT,#0FFHMOV A,KEY_PORTCPL AANL A,#0F0HJZ RET1LCALL DELAY10MSMOV A,KEY_PORTCPL AANL A,#0F0HJZ RET1JB ACC.7,MODE_CHANGEJB ACC.6,MODE_DEC_JJB ACC.5,MODE_ADD_JJB ACC.4,NUM_ADD_JRET1:RETMODE_DEC_J:LJMP MODE_DECRETMODE_ADD_J:LJMP MODE_ADDRETNUM_ADD_J:LJMP NUM_ADDRETMODE_CHANGE:INC MODE_CONTMOV A,MODE_CONTCJNE A,#04H,MODE_RETMOV MODE_CONT,#00HSETB TR0MODE_RET:LCALL MODE_DEL WAIT:LCALL DISPLAYJNB P3.7,WAITRETMODE_DEL:MOV A,MODE_CONTCJNE A,#00H,MOD_1CLR LED_LOW_SETCLR LED_HI_SETCLR LED_CHECKSETB LED_NORMALRETMOD_1:CJNE A,#01H,MOD_2CLR LED_LOW_SETCLR LED_HI_SETSETB LED_CHECKCLR LED_NORMALCLR TR0RETMOD_2:CJNE A,#02H,MOD_3CLR LED_LOW_SETSETB LED_HI_SETCLR LED_CHECKCLR LED_NORMALCLR TR0RETMOD_3:SETB LED_LOW_SETCLR LED_HI_SETCLR LED_CHECKCLR LED_NORMALCLR TR0RET;-----------------------------------;----------------------------------MODE_DEC:;模式0MOV A,MODE_CONTCJNE A,#00H,MODE_DEC_1 WAIT1:LCALL DISPLAYJNB P3.6,WAIT1RETMODE_DEC_1:;模式1CJNE A,#01H,MODE_DEC_2MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_11MOV DS18B20_CONT,#03H WAIT2:LCALL DISPLAYJNB P3.6,WAIT2RETMODE_DEC_11:DEC DS18B20_CONTWAIT3:LCALL DISPLAYJNB P3.6,WAIT3RETMODE_DEC_2:;模式2IN口CJNE A,#02H,MODE_DEC_3MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_21DEC HI_TMP_SET_INMOV A,HI_TMP_SET_OUTJNZ MODE_DEC_DELMOV HI_TMP_SET_IN,#64H MODE_DEC_DEL:MOV TEMPER_H,HI_TMP_SET_INMOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_21:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_DEC_22DEC HI_TMP_SET_OUTMOV A,HI_TMP_SET_OUTJNZ MODE_DEC_RET1MOV HI_TMP_SET_OUT,#64H MODE_DEC_RET1:MOV TEMPER_H,HI_TMP_SET_OUTMOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_22:;前点CJNE A,#02H,MODE_DEC_23DEC HI_TMP_SET_FRONTMOV A,HI_TMP_SET_FRONTJNZ MODE_DEC_RET2MOV HI_TMP_SET_FRONT,#64H MODE_DEC_RET2:MOV TEMPER_H,HI_TMP_SET_FRONT MOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_23:;后点DEC HI_TMP_SET_BACKMOV A,HI_TMP_SET_BACKJNZ MODE_DEC_XMOV HI_TMP_SET_BACK,#64H MODE_DEC_X:MOV TEMPER_H,HI_TMP_SET_BACK MOV TEMPER_L,#00HMODE_DEC_RET:WAIT4:LCALL DISPLAYJNB P3.6,WAIT4RET;------------------------------------;-----------------------------------MODE_DEC_3:;模式3MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_21BDEC LOW_TMP_SET_INMOV A,LOW_TMP_SET_INJNZ MODE_DEC_DELBMOV LOW_TMP_SET_IN,#64H MODE_DEC_DELB:MOV TEMPER_H,LOW_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_DEC_RETBMODE_DEC_21B:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_DEC_RETBDEC LOW_TMP_SET_OUTMOV A,LOW_TMP_SET_OUTJNZ MODE_DEC_RET1BMOV LOW_TMP_SET_OUT,#64H MODE_DEC_RET1B:MOV TEMPER_H,LOW_TMP_SET_OUT MOV TEMPER_L,#00HMODE_DEC_RETB:WAIT5:LCALL DISPLAYJNB P3.6,WAIT5RET;-----------------------------------;----------------------------------MODE_ADD:MOV A,MODE_CONTCJNE A,#00H,MODE_ADD_1WAIT6:LCALL DISPLAYJNB P3.5,WAIT6RETMODE_ADD_1:;模式1CJNE A,#01H,MODE_ADD_2MOV A,DS18B20_CONTCJNE A,#03H,MODE_ADD_11MOV DS18B20_CONT,#00HWAIT7:LCALL DISPLAYJNB P3.5,WAIT7RETMODE_ADD_11:INC DS18B20_CONTWAIT8:LCALL DISPLAYJNB P3.5,WAIT8RETMODE_ADD_2:;模式2IN口CJNE A,#02H,MODE_ADD_3MOV A,DS18B20_CONTCJNE A,#00H,MODE_ADD_21INC HI_TMP_SET_INMOV A,HI_TMP_SET_OUTCJNE A,#64H,MODE_ADD_DELMOV HI_TMP_SET_IN,#00H MODE_ADD_DEL:MOV TEMPER_H,HI_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_21:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_ADD_22INC HI_TMP_SET_OUTMOV A,HI_TMP_SET_OUTCJNE A,#64H,MODE_ADD_RET1MOV HI_TMP_SET_OUT,#00H MODE_ADD_RET1:MOV TEMPER_H,HI_TMP_SET_OUTMOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_22:;前点CJNE A,#02H,MODE_ADD_23INC HI_TMP_SET_FRONTMOV A,HI_TMP_SET_FRONTCJNE A,#64H,MODE_ADD_RET2MOV HI_TMP_SET_FRONT,#00H MODE_ADD_RET2:MOV TEMPER_H,HI_TMP_SET_FRONT MOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_23:;后点INC HI_TMP_SET_BACKMOV A,HI_TMP_SET_BACKCJNE A,#64H,MODE_ADD_XMOV HI_TMP_SET_BACK,#00HMODE_ADD_X:MOV TEMPER_H,HI_TMP_SET_BACKMOV TEMPER_L,#00HMODE_ADD_RET:WAIT9:LCALL DISPLAYJNB P3.5,WAIT9RET;------------------------------------;-----------------------------------MODE_ADD_3:;模式3MOV A,DS18B20_CONTCJNE A,#00H,MODE_ADD_21BINC LOW_TMP_SET_INMOV A,LOW_TMP_SET_INCJNE A,#64H,MODE_ADD_DELBMOV LOW_TMP_SET_IN,#00H MODE_ADD_DELB:MOV TEMPER_H,LOW_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_ADD_RETBMODE_ADD_21B:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_ADD_RETBINC LOW_TMP_SET_OUTMOV A,LOW_TMP_SET_OUTCJNE A,#64H,MODE_ADD_RET1BMOV LOW_TMP_SET_OUT,#64H MODE_ADD_RET1B:MOV TEMPER_H,LOW_TMP_SET_OUT MOV TEMPER_L,#00HMODE_ADD_RETB:WAIT71:LCALL DISPLAYJNB P3.5,WAIT71RET;----------------------------------;----------------------------------NUM_ADD:INC DS18B20_CONTMOV A,DS18B20_CONTCJNE A,#04H,NUM_ADD_RETMOV DS18B20_CONT,#00HNUM_ADD_RET:WAIT81:LCALL DISPLAYJNB P3.5,WAIT81RET;--------------------------------DELAY;延时程序;----------------------------------DELAY5MS:MOV R1,#2;5mS延时#5D1:MOV R2,#248D2:DJNZ R2,D2DJNZ R1,D1RET;------------------------------------------10MS DELAY DELAY10MS:MOV R3,#25;10mS延时D4:MOV R4,#200D3:DJNZ R4,D3DJNZ R3,D4RET;**********DS18B20复位程序***************** INIT_18B20:SETB DQ1SETB DQ2SETB DQ3SETB DQ4NOPNOPNOPNOPCLR DQ1CLR DQ2CLR DQ3CLR DQ4MOV R0,#0FBHTSR1:DJNZ R0,TSR1;延时SETB DQ1SETB DQ2SETB DQ3SETB DQ4MOV R0,#25HTSR2:JNB DQ1,TSR3JNB DQ2,TSR3JNB DQ3,TSR3JNB DQ4,TSR3DJNZ R0,TSR2TSR3:SETB FLAG1;置标志位,表明DS18B20存在AJMP TSR5TSR4:CLR FLAG1LJMP TSR7TSR5:MOV R0,#06BHTSR6:DJNZ R0,TSR6TSR7:SETB DQ1;表明不存在RET;********************设定DS18B20暂存器设定值************** RE_CONFIG:JB FLAG1,RE_CONFIG1RETRE_CONFIG1:MOV A,#0CCH;放跳过ROM命令LCALL WRITE_18B20MOV A,#4EHLCALL WRITE_18B20;写暂存器命令MOV A,#00H;报警上限中写入00HLCALL WRITE_18B20MOV A,#00H;报警下限中写入00HLCALL WRITE_18B20MOV A,#7FH;选择12位温度分辨率LCALL WRITE_18B20RET;*****************读转换后的温度值**************** GET_TEMPER:MOV A,MODE_CONTJZ GET_NEXT;只有模式零才GETCJNE A,#02H,AARETAA:CJNE A,#03H,GET_NEXTRETGET_NEXT:SETB DQ1SETB DQ2SETB DQ3SETB DQ4LCALL INIT_18B20JB FLAG1,TSS2RET;若不存在则返回TSS2:MOV A,#0CCH;跳过ROMLCALL WRITE_18B20MOV A,#44H;发出温度转换命令LCALL WRITE_18B20LCALL INIT_18B20MOV A,#0CCH;跳过ROMLCALL WRITE_18B20MOV A,#0BEH;发出读温度换命令LCALL WRITE_18B20MOV A,DS18B20_CONTCJNE A,#00H,READ_1LCALL READ2_18B20LCALL CHANGE1MOV TMP_IN,TEMPER_HRETREAD_1:MOV A,DS18B20_CONTCJNE A,#01H,READ_2LCALL READ2_18B20_2LCALL CHANGE1MOV TMP_OUT,TEMPER_HRETREAD_2:MOV A,DS18B20_CONTCJNE A,#02H,READ_3LCALL READ2_18B20_3LCALL CHANGE1MOV TMP_FRONT,TEMPER_HRETREAD_3:LCALL READ2_18B20_4;读两个字节的温度LCALL CHANGE1MOV TMP_BACK,TEMPER_HRET;**************************************;***************写DS18B20程序************ WRITE_18B20:MOV R2,#8CLR CWR1:CLR DQ1CLR DQ2CLR DQ3CLR DQ4MOV R3,#6DJNZ R3,$RRC AMOV DQ1,CMOV DQ2,CMOV DQ3,CMOV DQ4,CMOV R3,#23DJNZ R3,$SETB DQ1SETB DQ2SETB DQ3SETB DQ4NOPDJNZ R2,WR1SETB DQ1SETB DQ2SETB DQ3SETB DQ4RET;***********读18B20程序,读出两个字节的温度*********READ2_18B20:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE00:MOV R2,#8RE01:CLR CSETB CNOPNOPCLR DQ1NOPNOPSETB DQ1MOV R3,#7DJNZ R3,$MOV C,DQ1MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV@R1,ADEC R1DJNZ R4,RE00RET;***********读18B20_2程序,读出两个字节的温度********* READ2_18B20_2:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE001:MOV R2,#8RE012:CLR CSETB CNOPCLR DQ2NOPNOPNOPSETB DQ2MOV R3,#7DJNZ R3,$MOV C,DQ2MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE012MOV@R1,ADEC R1DJNZ R4,RE001RET;***********读18B20_3程序,读出两个字节的温度********* READ2_18B20_3:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE002:MOV R2,#8RE013:CLR CSETB CNOPNOPCLR DQ3NOPNOPNOPSETB DQ3MOV R3,#7DJNZ R3,$MOV C,DQ3MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE013MOV@R1,ADEC R1DJNZ R4,RE002RET;***********读18B20_3程序,读出两个字节的温度********* READ2_18B20_4:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE003:MOV R2,#8RE014:CLR CSETB CNOPNOPCLR DQ4NOPNOPNOPSETB DQ4MOV R3,#7DJNZ R3,$MOV C,DQ4MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE014MOV@R1,ADEC R1DJNZ R4,RE003RET;************读出的温度进行数据转换**************CHANGE1:MOV A,MODE_CONTJZ CHANGE1_NEXT;只有模式零和1才GETCJNE A,#02H,BBRETBB:CJNE A,#03H,CHANGE1_NEXTRETCHANGE1_NEXT:MOV A,TEMPER_LANL A,#0FHMOV B,#6HMUL ABMOV R0,AMOV A,TEMPER_LMOV C,TEMPER_H.0;将TEMPER_H中的最低位移入C RRC AMOV C,TEMPER_H.1RRC AMOV C,TEMPER_H.2RRC AMOV C,TEMPER_H.3RRC AMOV TEMPER_H,AMOV TEMPER_L,R0RET;***********************************D1MS:MOV R7,#80;1MS延时(按12MHZ算)DJNZ R7,$RET;*************************TAB:DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90HEND;DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,0H;共阴极LED;END。
DS18B20汇编程序
DS18B20汇编程序,1602液晶显示 2006-1-13 9:44:34TEMPER_L EQU 36HTEMPER_H EQU 35HTEMPER_NUM EQU 60HFLAG1 BIT 00HDQ BIT P3.3RS EQU P3.7 ;RS <---->P2.0RW EQU P3.6 ;R/W <--->P2.1E EQU P3.5 ;E <----->P2.2LCD_DB EQU P1AAA:MOV SP,#70HLCALL GET_TEMPERLCALL TEMPER_COVLCALL DISPLAY;调用显示子程序LJMP AAANOP;------------------读出转换后的温度值GET_TEMPER:SETB DQ ; 定时入口BCD:LCALL INIT_1820JB FLAG1,S22LJMP CC ; 若DS18B20不存在则返回S22:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配------0CCLCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820NOPLCALL DELAYLCALL DELAYCBA:LCALL INIT_1820JB FLAG1,ABCLJMP CBAABC:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;READ_1820RET;------------------读DS18B20的程序,从DS18B20中读出一个字节的数据READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;-------------------写DS18B20的程序WRITE_1820:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;-------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H)RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;-------------------将从DS18B20中读出的温度数据进行转换TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,AMOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUMMOV TEMPER_NUM,A ; 保存变换后的温度数据LCALL BIN_BCDRET;-------------------将16进制的温度数据转换成压缩BCD码BIN_BCD:MOV DPTR,#TEMP_TABMOV A,TEMPER_NUMMOVC A,@A+DPTRMOV TEMPER_NUM,ARETTEMP_TAB:DB 00H,01H,02H,03H,04H,05H,06H,07H DB 08H,09H,10H,11H,12H,13H,14H,15H DB 16H,17H,18H,19H,20H,21H,22H,23H DB 24H,25H,26H,27H,28H,29H,30H,31H DB 32H,33H,34H,35H,36H,37H,38H,39H DB 40H,41H,42H,43H,44H,45H,46H,47H DB 48H,49H,50H,51H,52H,53H,54H,55H DB 56H,57H,58H,59H,60H,61H,62H,63H DB 64H,65H,66H,67H,68H,69H,70H,71H DB 72H,73H,74H,75H,76H,77H,78H,79H DB 80H,81H,82H,83H,84H,85H,86H,87H DB 88H,89H,90H,91H,92H,93H,94H,95HDB 96H,97H,98H,99H;-------------------DS18B20初始化程序INIT_1820:SETB DQNOPCLR DQMOV R0,#80HTSR1:DJNZ R0,TSR1 ; 延时SETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQRET;------------------重新写DS18B20暂存存储器设定值RE_CONFIG:JB FLAG1,RE_CONFIG1 ; 若DS18B20存在,转RE_CONFIG1RETRE_CONFIG1:MOV A,#0CCH ; 发SKIP ROM命令LCALL WRITE_1820MOV A,#4EH ; 发写暂存存储器命令LCALL WRITE_1820MOV A,#00H ; TH(报警上限)中写入00HLCALL WRITE_1820MOV A,#00H ; TL(报警下限)中写入00HLCALL WRITE_1820MOV A,#7FH ; 选择12位温度分辨率LCALL WRITE_1820RET;------------------延时子程序DELAY:MOV R7,#00HMIN:DJNZ R7,YS500RETYS500:LCALL YS500USLJMP MINYS500US:MOV R6,#00HDJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RET;显示子程序display:ACALL LCD_INTMOV P1,#01H ;清屏ACALL ENABLEMOV P1,#81HLCALL ENABLEMOV P1,#'T'LCALL WRITERMOV P1,#'='LCALL WRITERCLR CLJMP DISP3RET;说明:使用前,必须先对液晶显示模块进行初始化。
DS18B20的报告(附带程序)..
DS18B20温度传感器数字温度传感器DS18B20是由Dallas半导体公司生产的,它具有耐磨耐碰,体积小,使用方便,封装形式多样(如图1.1.1),适用于各种狭小空间设备数字测温和控制领域。
图1.1.1引脚说明:GND为接地引脚;DQ为数据输入输出脚。
用于单线操作,漏极开路;VCC接电源正;单总线通常要求接一个约4.7K左右的上拉电阻,这样,当总线空闲时,其状态为高电平。
如图1.1.2是温度传感器DS18B20的接线图图1.1.2温度传感器DS18B20的参数:●适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电●温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃●可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温●在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快●被测温度用符号扩展的16位数字量方式串行输出●有两种供电方式既可以直接加 3.0~5.5V的电源,也可以采用寄生电源方式由数据线供电DS18B20内部结构及功能:DS18B20的内部结构如图1.1.3所示。
主要包括:寄生电源,温度传感器,64位ROM和单总线接口,存放中间数据的高速暂存器RAM,用于存储用户设定温度上下限值的TH和TL触发器,存储与控制逻辑,8位循环冗余校验码(CRC)发生器等7部分。
开始8位是产品类型的编号,接着共有48 位是DS18B20 唯一的序列号。
最后8位是前面56 位的CRC 检验码,这也是多个DS18B20 可以采用一线进行通信的原因。
高速暂存存储器:高速暂存存储器由9个字节组成,其分配如图所示。
高速暂存存储器字节0~1 温度寄存器当DS18B20接收到温度转换命令后,开始启动转换。
转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的第1,2字节。
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。
DS18B20汇编程序(完整版)
DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE<P16F877A.INC>#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSCCBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
基于51单片机——Ds18B20温度采集,LCD显示汇编程序(附带proteus仿真图).docx
TEMP_ZH EQU 24H ; 实测温度值存放单元TEMPL EQU 25HTEMPH EQU 26H高温报警值存放单元TEMP_TH EQU 27H ;低温报警值存放单元TEMP_TL EQU 28H ;正、负温度值标记TEMPHC EQU 29H ;TEMPLC EQU 2AHTEMPFC EQU 2BHK1 EQU P1.4 ; 查询按键K2 EQU P1.5 ; 设置/ 调整键调整键K3 EQU P1.6 ;K4 EQU P1.7 ; 确定键BEEP EQU P3.7 ; 蜂鸣器RELAY EQU P1.3 ; 指示灯LCD_X EQU FH ;LCD 字符显示位置寄存器选择信号LCD_RS EQU P2.0 ;LCD读写信号LCD_RW EQU P2.1 ;LCD允许信号LCD_EN EQU P2.2 ;LCD是否存在标志FLAG1 EQU 20H.0 ;DS18B20KEY_UD EQU 20H.1 5 设定按键的增、减标志DQ EQU P3.3 ;DS18B20 数据信号ORG 0000HLJMP MAINORG 0030H MAIN: MOV SP,#60HMOV A,#00HMOV R0,#20HMOV R1,#10HCLEAR: MOV @R0,AINC R0DJNZ R1,CLEARLCALL SET_LCDLCALL RE_18B20 START: LCALL RSTJNB FLAG1,START1LCALL MENU_OK 信息子程序MOV TEMP_TH,#055HMOV TEMP_TL,#019HLCALL RE_18B20ALCALL WRITE_E2 ;LCALL TEMP_BJ ;JMP START2;将20H~2FH单元清零;调用18B20复位子程序;DS 1 820不存在;DS1820 存在,调用显示正确;设置TH初值85度;设置TL初值25度; 调用暂存器操作子程序写入DS18B20显示温度标记LCALL TEMP_BJSJMP $START2: LCALL RSTJNB FLAG1,START1 MOV A,#0CCH LCALL WRITE MOV A,#44H LCALL WRITE LCALL RST MOV A,#0CCH LCALL WRITE MOV A,#0BEH LCALL WRITE LCALL READ 子程序LCALL CONVTEMP 程序LCALL DISPBCD LCALL CONV LCALLTEMP_COMP 值比较子程序显示温度标记;调用DS18B2(复位子程序QS18B20不存在;跳过RoM E配命令; 温度转换命令START1: LCALL MENU_ERROR ; 调用显示出错信息子程序;跳过ROM E配; 读温度命令;调用DS18B20数据读取操作;调用温度数据BCD码处理子; 调用温度数据显示子程序;调用LCD显示处理子程序; 调用实测温度值与设定温度调用键扫描子程序 ;循环 键扫描子PROC_KEY:JB K1,PROC_K1LCALL BEEP_BL JNB K1,$MOV DPTR,#M_ALAX1 MOV A,#1LCALL LCD_PRINT LCALL LOOK_ALARM JB K3,$LCALL BEEP_BL JMP PROC_K2PROC_K1: JB K2,PROC_ENDLCALL BEEP_BL JNB K2,$MOV DPTR,#RST_A1 MOV A,#1LCALL LCD_PRINT LCALL SET_ALARMLCALL RE_18B20 将设定的 TH,TL 值写入LCALL PROC_KEYSJMP START2・ ***************************5*****************************程序DS18B20LCALL WRITE_E2PROC_K2: LCALL MENU_OKLCALL TEMP_BJPROC_END:RET・ *************************** 设定温度报警值TH、TL ***************************SET_ALARM:LCALL LOOK_ALARMAS0: JB K1,AS00LCALL BEEP_BLJNB K1,$CPL 20H.1 ;UP/DOWN 标记AS00: JB 20H.1,ASZ01 ;20H.1=1 ,增加JMP ASJ01 ;20H.1=0 ,减小ASZ01: JB K2,ASZ02 ;TH 值调整(增加)LCALL BEEP_BLINC TEMP_THMOV A,TEMP_THCJNE A,#120,ASZ011MOV TEMP_TH,#0ASZ011: LCALL LOOK_ALARMMOV R5,#10 LCALL DELAY JMP ASZ01ASZ02: JB K3,ASZ03LCALL BEEP_BLINC TEMP_TLMOV A,TEMP_TLCJNE A,#99,ASZ021MOV TEMP_TL,#00H ASZ021: LCALL LOOK_ALARM MOV R5,#10LCALL DELAYJMP ASZ02ASZ03: JB K4,AS0LCALL BEEP_BLJNB K4,$RETASJ01: JB K2,ASJ02LCALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011 ;TL 值调整(增加); 确定调整;TH 值调整(减少)JMP ASJ022ASJ011: LCALL LOOK_ALARMMOV R5,#10LCALL DELAYJMP AS0ASJ02: JB K3,ASJ03 ;TL 值调整(减少)LCALL BEEP_BLDEC TEMP_TLMOV A,TEMP_TLCJNE A,#0FFH,ASJ021JMP ASJ022ASJ021: LCALL LOOK_ALARM ;MOV R5,#10LCALL DELAYJMP AS0ASJ022: CPL 20H.1JMP ASZ01ASJ03: JMP ASZ03RETRST_A1: DB " SET ALERT CODE " ,0・ *********************** 实测温度值与设定温度值比较子程序**********************TEMP_COMP:MOV A,TEMP_TH SUBB A,TEMP_ZH JCCHULI1MOV A,TEMPFCCJNE A,#0BH,COMP SJMPCHULI2COMP: MOV A,TEMP_ZHSUBB A,TEMP_TL ; JCCHULI2 ;MOV DPTR,#BJ5 LCALLTEMP_BJ3 CLR RELAYRETCHULI1: MOV DPTR,#BJ3 LCALL TEMP_BJ3 SETB RELAY ;LCALL BEEP_BL RET CHULI2: MOV DPTR,#BJ4 LCALL TEMP_BJ3SETB RELAY; 减数>被减数,则;借位标志位C=I,转减数>被减数,则借位标志位C=I ,转; 点亮指示灯熄灭指示灯; 蜂鸣器响熄灭指示灯LCALL BEEP_BL ; 蜂鸣器响RETTEMP_BJ3: MOV A,#0CEHLCALL WCOMMOV R1,#0MOV R0,#2BBJJ3: MOV A,R1MOVC A,@A+DPTRLCALL WDATAINC R1DJNZ R0,BBJJ3RETBJ3: DB ">H"BJ4: DB "<L"BJ5: DB " !"・ **************************** 显示温度标记子程序***************************TEMP_BJ: MOV A,#0CBHLCALL WCOMMOV DPTR,#BJ1 ; 指针指到显示消息MOV R1,#0MOV R0,#2BBJJ1: MOV A,R1MOVC A,@A+DPTRLCALL WDATAINC R1DJNZ R0,BBJJ1RETBJ1: DB 00H,"C"・ ********************************5***************************MENU_OK: MOV DPTR,#M_O MOV A,#1 ;LCALL LCD_PRINT MOVDPTR,#M_OK2 MOVA,#2 ;LCALL LCD_PRINTRETM_OK1: DB " DS18B20 OK显示正确信息子程序; 指针指到显示消息显示在第一行; 指针指到显示消息显示在第一行",0M_OK2: DB " TEMP: ",0・ ******************************** 显示出错信息子程序***************************MENU_ERROR:MoV DPTR,#M_ERROR针指到显示消息MOV A,#1 ; 显示在第一行LCALL LCD_PRINTMoV DPTR,#M_ERRoR2 ; 指针指到显示消息1MoV A,#2 ; 显示在第一行LCALL LCD_PRINTRETM_ERRoR1: DB " DS18B20 ERRoR ",0M_ERRoR2: DB " TEMP: ------ ",0;**************************** DS18B20 复位子程序*****************************RST: SETB DQNoPCLR DQMoV R0,#6BH ; 主机发出延时复位低脉冲MoV R1,#04HTSR1: DJNZ R0,$MoV R0,#6BHDJNZ R1,TSR1SETB DQ ; 拉高数据线NOPNOPNOPMOV R0,#32HTSR2: JNB DQ,TSR3DJNZ R0,TSR2JMP TSR4 ;TSR3: SETB FLAG1JMP TSR5TSR4: CLR FLAG1JMP TSR7TSR5: MOV R0,#06BH TSR6: DJNZ R0,$ TSR7: SETB DQRET・ ************************ 5***************************RE_18B20:JB FLAG1,RE_18B20A RET延时置1标志位,表示DS1820存在清0标志位,表示DS1820不存在时序要求延时一段时间RE_18B20A:;等待DS18B20回应DS18B20 暂存器操作子程序LCALL RSTMOV A,#0CCH LCALL WRITE WR_SCRAPD:MOV A,#4EH LCALL WRITE MOV A,TEMP_TH LCALL WRITE MOV A,TEMP_TL LCALL WRITE MOV A,#7FH LCALL WRITERET;跳过RoME 配; 写暂器;TH ( 报警上限);TL ( 报警下限);12 位精度复制暂存器子程序;跳过ROM E 配; 把暂存器里的温度报警值拷贝到 LCALL WRITE・ ************************5*******************************WRITE_E2:LCALL RSTMoV A,#0CCH LCALL WRITE MoV A,#48H EERoM********************************READ_E2:LCALL RSTMOV A,#0CCH LCALL WRITE MOV A,#0B8H暂存器LCALL WRITE RET ;跳过RoM E 配;把EEROMl 的温度报警值拷贝回*********************STORE_DATA:MOV A,#40H LCALL WCOM MOV R2,#08H MOV DPTR,#D_DATA MOV R3,#00H S_DATA: MOV A,R3MOVC A,@A+DPTRRET・ ***********************重 读 EEROM 子 程 序・ ************************将自定义字符写入 LCD 的CGRAM 中INC R3DJNZ R2,S_DATA RETD_DATA: DB 0CH,12H,12H,0CH,00H,00H,00H,00HDS18B20 数 据 写 入 操 作 子 程 序************************CLR CWR1: CLR DQ;开始写入DS18B20总线要处于复位(低)状态MOV R3,#07DJNZ R3,$ 总线复位保持 1 6微妙以上 RRC A把一个字节DATA 分成8个BlT环移给 CMOV DQ,C ; 写入一位MOV R3,#3CH DJNZ R3,$ 等待 100 微妙SETB DQ ; 重新释放总线NOPDJNZ R2,WR1 写入下一位SETB DQLCALL WDATA; 写入数据・ ***********************WRITE: MOV R2,#8一共 8 位数据RET・ ********************** DS18B20 数据读取操作子程序**************************READ: MOV R4,#4DS18B2冲读出MOV R1,#TEMPL 元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#09DJNZ R3,$MOV C,DQ; 将温度低位、高位、TH、TL 从; 存入25H、26H、27H、28H 单; 读前总线保持为低; 开始读总线释放; 延时18 微妙;从DS18B2(总线读得一位DJNZ R3,$ ; 等待 100 微妙RRC A ; 把读得的位值环移给 A DJNZ R2,RE01; 读下一位MOV @R1,AINC R1DJNZ R4,RE00RET*************************CONVTEMP: MOV A,TEMPHANL A,#08H JZ TEMPC1 ; CLR CMOV A,TEMPL ; CPL A ; ADD A,#01H MOV TEMPL,A MOV A,TEMPH CPL A ADDC A,#00H MOV TEMPH,A・ ************************温 度 值 BCD 码 处 理 子 程 序判温度是否零下温度零上转二进制数求补(双字节) 取反加 1MOV TEMPHC,#0BH ; 负温度标志MOV TEMPFC,#0BHSJMP TEMPC11TEMPC1: MOV TEMPHC,#0AH ; 正温度标志MOV TEMPFC,#0AHTEMPC11: MOV A,TEMPHCSWAP AMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ; 乘0.0625MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分BCD整数部分MOV A,TEMPL ;取出高四位ANL A,#0F0H ;SWAP AMOV TEMPL,A取出低四位MOV A,TEMPH ;ANL A,#0FHSWAP AORL A,TEMPL ; 重新组合ORL A,TEMPLC MOV TEMPLC,A MOV A,R4 JZ TEMPC12 ANL A,#0FH SWAP A MOV R4,A MOV A,TEMPHC;TEMPHC HI = 百位数BCDANL A,#0FHBCDBCDMOV TEMP_ZH,A LCALL HEX2BCD1 MOV TEMPL,A ANL A,#0F0H SWAP AORL A,TEMPHC ;TEMPHCMOV TEMPHC,A MOV A,TEMPL ANL A,#0FH SWAP A;TEMPLC HI =LOW= 十位数个位数ORL A,R4MOV TEMPHC,ATEMPC12: RET・ ************************ 二-十进制转换子程序*****************************HEX2BCD1: MOV B,#064HDIV ABMOV R4,AMOV A,#0AHXCH A,BDIV ABSWAP AORL A,BRETTEMPDOTTAB: DB 00H,00H,01H,01H,02H,03H,03H,04H ; 小数部分码表DB 05H,05H,06H,06H,07H,08H,08H,09H・ ********************** 查询温度报警值子程序***************************LOOK_ALARM: MOV DPTR,#M_ALAX2 指; 针指到显示信息区M_ALAX1: DB " LOOK ALERT CODE",0 M_ALAX2: DB "TH: TL: ",0 TEMP_BJ1: LCALL WCOMMOV DPTR,#BJ2 ; 指针指到显示信息区MOV R1,#0 MOV R0,#2 BBJJ2: MOV A,R1MOVC A,@A+DPTR LCALL WDATALCALL LCD_PRINTMOV A,#0C6HLCALL TEMP_BJ1MOV A,TEMP_TH ; 加载 TH 数据 MOV LCD_X,#3 ; 设置显示位置LCALL SHOW_DIG2H ;显示数据MOV A,#0CEHLCALL TEMP_BJ1MOV A,TEMP_TL ; 加载 TL 数据 MOV LCD_X,#12 ; 设置显示位置LCALL SHOW_DIG2L ;显示数据RETMOV A,#2; 显示在第二行INC R1DJNZ R0,BBJJ2RETBJ2: DB 00H,"C"POP B・ ************************** LCD 显示子程序**********************************SHOW_DIG2H: MOV B,#100DIV ABADD A,#30HPUSH BMOV B,LCD_XLCALL LCDP2POP BMOV A,#0AHXCH A,BDIV ABADD A,#30HINC LCD_XPUSH BMOV B,LCD_XLCALL LCDP2INC LCD_X MOV A,BMOV B,LCD_XADD A,#30HLCALL LCDP2RETSHOW_DIG2L:MOV B,#100 DIV ABMOV A,#0AHXCH A,B DIV ABADD A,#30H PUSH BMOV B,LCD_XLCALL LCDP2 POP B INC LCD_XMOV A,BMOV B,LCD_XADD A,#30HLCALL LCDP2RET;************************ 显示区BCD 码温度值刷新子程序**********************DISPBCD: MOV A,TEMPLCANL A,#0FHMOV 70H,A ; 小数位MOV A,TEMPLCSWAP AANL A,#0FHMOV 71H,A ; 个位MOV A,TEMPHCANL A,#0FHMOV 72H,A ; 十位MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,A ; 百位DISPBCD2: RET・ *************************** LCD 显示数据处理子程序*************************CONV: MOV A,73HMOV LCD_X,#6CJNE A,#1,CONV1JMP CONV2CONV1: CJNE A,#0BH,CONV11MOV A,#"-"JMP CONV111 CONV11: MOV A,#" " CONV111: MOV B,LCD_X LCALL LCDP2JMP CONV3CONV2: LCALL SHOW_DIG2CONV3: INC LCD_XMOV A,72HLCALL SHOW_DIG2INC LCD_XMOV A,71H LCALLSHOW_DIG2INC LCD_XMOV A,#'.'; 加载百位数据; 设置位置;"-" 号显示;"+" 号不显示; 显示数据; 十位; 个位第二行显示数字子程序设置显示地址设置LCD 的第二行地址写入命令 由堆栈取出 A; 写入数据MOV B,LCD_X LCALL LCDP2 MOV A,70H INC LCD_XLCALL SHOW_DIG2 RET; 加载小数点位 ; 设置显示位置 ; 显示数据第二行显示数字子程序・ ***************************5*************************SHOW_DIG2:ADD A,#30HMOV B,LCD_XLCALL LCDP2RET・ ***************************5*************************LCDP2: PUSH ACC MOVA,B ; ADD A,#0C0H ; LCALL WCOM ; POP ACC ;LCALL WDATARETLCALL WCOM・ ***************************5*************************SET_LCD: CLR LCD_ENLCALL INIT_LCD ; LCALL STORE_DATA ; RET・ ******************************5***********************************INIT_LCD: MOV A,#38H ;2LCALL WCOM LCALL DELAY1 MOV A,#38H LCALL WCOM LCALL DELAY1 MOV A,#38H LCALL WCOM LCALL DELAY1 MOV A,#0CH ;对 LCD 做 初 始 化 设 置 及 测 试初始化 LCD将自定义字符存入LCD 的CGRAMLCD 初 始 化开显示,显示光标,光标不闪烁LCALL DELAY1MOV A,#01H ; 清除 LCD 显示屏 LCALL WCOM LCALL DELAY1 RET清 除 LCD 的 第 一 行 字 符设置 LCD 的第一行地址 设置计数值载入空格符至 LCD 输出字符至 LCD 计数结束LCD 的 第一 行或第二行 显 示字符LCD_PRINT:CJNE A,#1,LINE2 ; 判断是否为第一行LINE1: MOV A,#80H ; 设置 LCD 的第一行地址LCALL WCOM ; 写入命令LCALL CLR_LINE ; 清除该行字符数据・ *****************************5**************************CLR_LINE1:MOV A,#80HLCALL WCOM MOV R0,#24 ;C1: MOV A,#' ' ; LCALLWDATA DJNZ R0,C1 ; RET・ *************************5**********************MOV A,#80H 设置 LCD 的第一行地址LCALL WCOM ; JMP FILL LINE2: MOV A,#0C0H LCALLWCOM ; LCALL CLR_LINEMOV A,#0C0H ;LCALL WCOMFILL: CLR A ;MOVC A,@A+DPTR CJNEA,#0,LC1 ;RETLC1: LCALL WDATA INCDPTR ; JMP FILL ; RET・ ***************************5****************************CLR_LINE: MOV R0,#24 CL1: MOV A,#' 'LCALL WDATA DJNZR0,CL1写入命令设置LCD 的第二行地址写入命令清除该行字符数据设置LCD 的第二行地址填入字符由消息区取出字符判断是否为结束码写入数据指针加1继续填入字符清除1 行LCD 的字符RET DE: MOV R7,#250DJNZ R7,$ RET・ ****************************5*************************WCOM: MOV P0,ACLR LCD_RS ;RS=L,RW=L,D0-D7= 指令码,E= 高脉冲CLR LCD_RW SETB LCD_EN LCALL DELAY1 CLR LCD_EN RETLCALL DELCD 间接控制方式命令写入写入命令・ ****************************5*************************WDATA: MOV P0,ASETB LCD_RS CLR LCD_RW SETB LCD_ENLCD 间接控制方式数据写 入写入数据CLR LCD_EN LCALL DE RET・ **************************5在LCD 的第一行显示字符**************************LCDP1: PUSH ACCMOV A,B ;设置显示地址ADD A,#80H ;设置LCD的第一行地址LCALL WCOM ;写入命令POP ACC ; 由堆栈取出ALCALL WDATA ; 写入数据RET・ ******************************5声光报警子程序*******************************BEEP_BL: MOV R6,#100BL2: LCALL DEX1CPL BEEPCPL RELAYDJNZ R6,BL2MOV R5,#10LCALL DELAYRETDEX1: MOV R7,#180DE2: NOPDJNZ R7,DE2RET・ ****************************** 延时子程序*******************************DELAY: MOV R6,#50DL1: MOV R7,#100DJNZ R7,$DJNZ R6,DL1DJNZ R5,DELAYRETDELAY1: MOV R6,#25 ; 延时5 毫秒DL2: MOV R7,#100DJNZ R7,$DJNZ R6,DL2RETENDLCDlLMOT6LDS18B2Θ OK TEMP : 82.0O C8sS23Sδ≥CRYSLUIXTALIXTAL2RSTPQOfAa) P0.1∕AD1PO2∕AD2 P0.3∕ACGP0.4∕ACU PO5∕AD6P0 6∕ACePO7∕AD7 ,°u∙远2QX 'KliS BP1 5 PI 6 Pl 7 ΘO5Γ <TEXT>K3K2 PSENALE EAP1.0 PII P1 2P2ΓUAfl P2.1)W P22∕A10 P23∕A11 P24∕A12 P25∕A13 P26∕A14 P27∕A15 P3.Q∕RXD P3.1∕7XD P3.2∕iF∏D P3 3∕INT1P3 4/TD P3 5f∏ P3 6Λ⅛5 P3 7WI ■■39■ 屮 ■ g■ 卜■ ■σ∙ O■ ■ ■ J■ --■↑2・ ■ 383" ■ 374・5" ■356"7" ■338∙■ 22 ....................... ...............................9・■51•■ 22•■ 23221 ∆2i * ±2& ■2Z. ■28 ,Ir蚩工n s: ∙ inJTDS1ΘB2D <TEXT>, ∙GND ∙ ∙2・ U2。
DS18B20温度采集电路及程序
#include <reg52.h>#include <intrins.h>typedef unsigned char uint8;#define uint unsigned int#define uchar unsigned charsbit DQ = P3^3; // 定义DQ引脚为P3.3uchar code Bw[10]= {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//百位编码uchar code Xsw[16]={0x30,0x31,0x31,0x32,0x33,0x33,0x34,0x34,0x35,0x36,0x36,0x37,0x38,0x38,0x39,0x 39};//小数位编码sbit RS = P2^0 ;sbit RW = P2^1 ;sbit EN = P2^2 ;sbit BUSY = P0^7;uchar wendu;uchar temp_g,temp_d;unsigned char code word1[]={"Temperature:"};void delay(uint xms){uint i,j;for(i=xms;i>0;--i)for(j=110;j>0;--j);}void Delayus(int t) //在11.059MHz的晶振条件下调用本函数需要24μs ,然后每次计数需16μs{int s;for (s=0; s<t;s++);}void wait(void){P0 = 0xFF;do{RS = 0;RW = 1;EN = 0;EN = 1;}while (BUSY == 1);EN = 0;}void w_dat(uint8 dat){wait();EN = 0;P0 = dat;RS = 1;RW = 0;EN = 1;EN = 0;}void w_cmd(uint8 cmd){wait();EN = 0;P0 = cmd;RS = 0;RW = 0;EN = 1;EN = 0;}//LCDvoid w_string(uint8 addr_start, uint8 *p){w_cmd(addr_start);while (*p != '\0'){w_dat(*p++);}}//1602void Init_LCD1602(void){w_cmd(0x38); // 16*2显示,5*7点阵,8位数据接口w_cmd(0x0c); // 显示器开、光标开、光标允许闪烁w_cmd(0x06); // 文字不动,光标自动右移w_cmd(0x01); // 清屏}uchar Reset()//完成单总线的复位操作。
DS18B20温度测量程序(汇编)
;单片机内存分配申明!TEMPER_L EQU 29H;用于保存读出温度的低8位TEMPER_H EQU 28H;用于保存读出温度的高8位FLAG1 EQU 38H;是否检测到DS18B20标志位a_bit equ 20h ;数码管个位数存放内存位置b_bit equ 21h ;数码管十位数存放内存位置;进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度;显示范围00到99度,显示精度为1度;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度;这个转化温度的方法非常简洁无需乘于0.0625系数MAIN: LCALL GET_TEMPER;调用读温度子程序MOV A,29HMOV C,40H;将28H中的最低位移入CRRC AMOV C,41HRRC AMOV C,42HRRC AMOV C,43HRRC AMOV 29H,ALCALL DISPLAY;调用数码管显示子程序JNB FLAG1,MM1CLR P1.0MM1: SETB P1.0SJMP MAININIT_1820: SETB P2.2 ; 这是DS18B20复位初始化子程序NOPCLR P2.2MOV R1,#3 ;主机发出延时537微秒的复位低脉冲TSR1: MOV R0,#107DJNZ R0,$DJNZ R1,TSR1SETB P2.2 ;然后拉高数据线NOPNOPNOPMOV R0,#25HTSR2: JNB P2.2,TSR3 ;等待DS18B20回应DJNZ R0,TSR2LJMP TSR4 ; 延时TSR3: SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4: CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5: MOV R0,#70TSR6: DJNZ R0,TSR6 ; 时序要求延时一段时间TSR7: SETB P2.2RETGET_TEMPER: SETB P2.2 ; 读出转换后的温度值LCALL INIT_1820;先复位DS18B20JB FLAG1,TSS2RET ; 判断DS1820是否存在?若DS18B20不存在则返回TSS2: MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL DISPLAY ;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒LCALL INIT_1820;准备读温度前先复位MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200; 将读出的温度数据保存到35H/36HRETWRITE_1820: MOV R2,#8;写DS18B20的子程序(有具体的时序要求),一共8位数据CLR CWR1: CLR P2.2MOV R3,#5DJNZ R3,$RRC AMOV P2.2,CMOV R3,#21DJNZ R3,$SETB P2.2NOPDJNZ R2,WR1SETB P2.2RETREAD_18200: MOV R4,#2 ; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据,将温度高位和低位从DS18B20中读出MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)RE00: MOV R2,#8;数据一共有8位RE01: CLR CSETB P2.2NOPNOPCLR P2.2NOPNOPNOPSETB P2.2MOV R3,#8RE10: DJNZ R3,RE10MOV C,P2.2MOV R3,#21RE20: DJNZ R3,RE20RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RETdisplay: mov a,29H;显示子程序将29H中的十六进制数转换成10进制mov b,#10 ;10进制/10=10进制div abmov b_bit,a ;十位在amov a_bit,b ;个位在bmov dptr,#numtab ;指定查表启始地址mov r0,#4dpl1: mov r1,#250 ;显示1000次dplop: mov a,a_bit ;取个位数MOVC A,@A+DPTR ;查个位数的7段代码mov p0,a ;送出个位的7段代码clr p2.6 ;开个位显示acall d1ms ;显示1mssetb p2.6mov a,b_bit ;取十位数MOVC A,@A+DPTR ;查十位数的7段代码mov p0,a ;送出十位的7段代码clr p2.7 ;开十位显示acall d1ms ;显示1mssetb p2.7djnz r1,dplop ;100次没完循环djnz r0,dpl1 ;4个100次没完循环retD1MS: MOV R7,#80 ;1MS延时DJNZ R7,$RETnumtab: DB 0C0H,0F9H,0A4H,0B0H, 099H, 092H, 082H,0F8H 080H, 090H ;实验板上的7段数码管0~9数字的共阴显示代码end。
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多路温度采集程序
本程序为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,0 x8e},{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码}。
DS18B20温度计完整单片机程序(汇编语言)
end
sjmp dis1
dis :
movc a,@a+dptr
CLR P2.2
clr P2.1 ;低位灭
mov p0,a
call delay3
dis1:
mov a,b
movc a,@a+dptr
setb P2.2
clr P2.1 ;高位灭
mov p0,a
call delay3
djnz r1,write_bit
ret
;*****************************************
;读一个字节(内容放在在A中)
read_byte:
mov r2,#8
read_bit:
clr p1.7
nop
nop
nop
nop
setb p1.7 ;释放总线的目的是为了读18b20发出的数据,低电平是不能读的。
sjmp f1
f:clr 20h.0 ;初始化失败置0
f1:
ret
;*****************************************
;写一个字节(内容在A中)
write_byte:
mov r1,#8
;写一位
write_bit:
rrc a ;先写低位
clr 20h.0
mov a, #0cch ;跳过序列号
call write_byte
mov a,#0BEH ;送入读内部ram命令
call write_byte
call read_byte
mov r6,a
call read_byte
DS18B20读取温度并显示-汇编程序
DS18B20读取温度并显示-汇编程序*程序效果:通过DS18B20 读取温度值,显示对应的温度值程序重在理解时序,及延时时间*/DS18DQ EQU P1.3 //P1.3 与DS18DQ 等同,便于理解SPEAKER EQU P2.0 //驱动蜂鸣器TEMPH EQU 29H //保存读出温度的低8 位TEMPL EQU 28H //保存读出温度的高8 位DS18FLAG EQU 40H //设置标志ORG 0000H LJMP START ORG 0030HSTART: MOV 30H,#00 //设置初始值MOV 31H,#00 MOV 32H,#00 START1: LCALL DS18_GF //设置DS18B20 的工作方式LCALL CONVERT_TEMPERATURE //输出转换温度命令LCALL DELAY750MS //延时750ms LCALL GET_TEMPERATURE //获?温度数据LCALL CAL_TEMPERATURE //计算温度数值LCALL DISPLAY //调用显示,防止掉显LJMP START1 //无限循环//初始化子程序DS18_START: PUSH 07H //保存R7 的值,防止改变R7 的数值SETB DS18DQ //将数据线拉高NOP //延时1us CLR DS18DQ //将数据线拉低MOV R7,#0 //延时大约512us DJNZ R7,$ SETB DS18DQ //将数据线拉高MOV R7,#40DS18_START1: //延时大约160us JNB DS18DQ,DS18_START2 //检查DS18B20 是否工作正常DJNZ R7,DS18_START1 SETB DS18FLAG //工作不正常CLR SPEAKER //驱动蜂鸣器,报警DS18_START2: CLR DS18FLAG MOV R7,#100 //延时月200us DJNZ R7,$ POP 07H //恢复R7 的值RET//设置DS18B20 工作方式DS18_GF:CLR DS18FLAG //清除标志LCALL DS18_START //调用初始化子程序MOV A,#0CCH //跳跃ROM 指令LCALL DS18_SEND // MOV A,#4EH //向RAM 写数据LCALL DS18_SEND MOV A,#75 LCALL DS18_SEND MOV A,#0 LCALL DS18_SEND MOV A,#7FH //设置工作方式LCALL DS18_SEND。
DS18B20温度控制数码管显示(汇编非常详细)
D S18B20温度控制数码管显示(汇编非常详细)-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN; DS18B20温度控制数码管显示(汇编非常详细)*;* 1、= → 进入设定温度报警值 TL 状态: *;* L--20 *;* 2、→ 进入设定温度报警值 TH 状态: *;* H--28 *;* 3、→ 返回 *;* 4、设定过程:→加键(UP),→减键(DOWN),可快速调。
* ;* **TIMER_L DATA 23HTIMER_H DATA 24HTIMER_COUN DATA 25HTEMPL DATA 26HTEMPH DATA 27HTEMP_TH DATA 28HTEMP_TL DATA 29HTEMPHC DATA 2AHTEMPLC DATA 2BHTEMP_ZH DATA 2CHBEEP EQUDATA_LINE EQURELAY EQUFLAG1 EQUFLAG2 EQU;-------------------------------------------------K1 EQUK2 EQUK3 EQUK4 EQU;=================================================ORG 0000HJMP MAINORG 000BHAJMP INT_T0;--------------------------------------------------MAIN: MOV SP,#30HMOV TMOD,#01H ;T0,方式1MOV TIMER_L,#00H ;50ms定时值MOV TIMER_H,#4CHMOV TIMER_COUN,#00H ;中断计数MOV IE,#82H ;EA=1,ET0=1LCALL READ_E2;LCALL RE_18B20MOV 20H,#00HSETB BEEPSETB RELAYMOV 7FH,#0AH ;熄灭符CALL RESET ;复位与检测DS18B20JNB FLAG1,MAIN1 ;FLAG1=0,DS18B20不存在JMP STARTMAIN1: CALL RESETJB FLAG1,STARTLCALL BEEP_BL ;DS18B20错误,报警JMP MAIN1START:MOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#044H ; 发出温度转换命令CALL WRITECALL RESETMOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#0BEH ; 发出读温度命令CALL WRITECALL READ ;读温度数据CALL CONVTEMPCALL DISPBCDCALL DISP1CALL SCANKEYLCALL TEMP_COMPJMP MAIN1;===================================================== ;DS18B20 复位与检测子程序;FLAG1=1 OK, FLAG1=0 ERROR;====================================================== RESET:SETB DATA_LINENOPCLR DATA_LINEMOV R0,#64H ;主机发出延时600微秒的复位低脉冲MOV R1,#03HRESET1: DJNZ R0,$MOV R0,#64HDJNZ R1,RESET1SETB DATA_LINE ;然后拉高数据线NOPMOV R0,#25HRESET2: JNB DATA_LINE,RESET3 ;等待DS18B20回应DJNZ R0,RESET2JMP RESET4 ; 延时RESET3: SETB FLAG1 ; 置标志位,表示DS1820存在JMP RESET5RESET4: CLR FLAG1 ; 清标志位,表示DS1820不存在JMP RESET6RESET5: MOV R0,#064HDJNZ R0,$ ; 时序要求延时一段时间RESET6: SETB DATA_LINERET;=========================================================== ;;=========================================================== WRITE: MOV R2,#8 ;一共8位数据CLR CYWR1:CLR DATA_LINE ;开始写入DS18B20总线要处于复位(低)状态 MOV R3,#09DJNZ R3,$ ;总线复位保持18微妙以上RRC A ;把一个字节DATA 分成8个BIT环移给CMOV DATA_LINE,C ;写入一个BITMOV R3,#23DJNZ R3,$ ;等待46微妙SETB DATA_LINE ;重新释放总线NOPDJNZ R2,WR1 ;写入下一个BITSETB DATA_LINERET;============================================================ ;从DS18B20中读出温度低位、高位和报警值TH、TL;存入26H、27H、28H、29H;============================================================ READ: MOV R4,#4 ; 将温度高位和低位从DS18B20中读出MOV R1,#26H ; 存入26H、27H、28H、29HRE00: MOV R2,#8RE01: CLR CSETB DATA_LINENOPNOPCLR DATA_LINE ;读前总线保持为低NOPNOPNOPSETB DATA_LINE ;开始读总线释放MOV R3,#09 ;延时18微妙DJNZ R3,$MOV C,DATA_LINE ;从DS18B20总线读得一个BITMOV R3,#23DJNZ R3,$ ;等待46微妙RRC A ;把读得的位值环移给ADJNZ R2,RE01 ;读下一个BITMOV @R1,AINC R1DJNZ R4,RE00RET;--------------------------------------------;200ms对闪动标记取反一次;--------------------------------------------INT_T0:PUSH ACCPUSH PSWMOV TL0,TIMER_LMOV TH0,TIMER_HINC TIMER_COUNMOV A,TIMER_COUNCJNE A,#04H,INT_ENDMOV TIMER_COUN,#00HCPL FLAG2INT_END:POP PSWPOP ACCRETI;========================================================== ;重新对 DS18B20 初始化;将设定的温度报警值写入 DS18B20;========================================================== RE_18B20:JB FLAG1,RE_18B20ARETRE_18B20A:CALL RESETMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#4EH ;写暂存寄存器LCALL WRITEMOV A,TEMP_TH ;TH(报警上限)LCALL WRITEMOV A,TEMP_TL ;TL(报警下限)LCALL WRITEMOV A,#7FH ;12位精确度LCALL WRITERET;====================================================;功能键扫描子程序;==================================================== SCANKEY:MOV P1,#0F0HJB K1,SCAN_K2CALL BEEP_BLSCAN_K1: CALL ALERT_TLCALL ALERT_PLAYJB K1,SCAN_K1CALL BEEP_BLSCAN_K11: CALL ALERT_THCALL ALERT_PLAYJB K1,SCAN_K11CALL BEEP_BLSCAN_K2: JB K2,SCAN_K3CALL BEEP_BLSCAN_K3: JB K3,SCAN_K4CALL BEEP_BLLCALL RESET_ALERTLCALL RE_18B20LCALL WRITE_E2SCAN_K4: JB K4,SCAN_ENDCALL BEEP_BLSCAN_END: RET;================================================ ;设置温度报警值;================================================ RESET_ALERT:CALL ALERT_TLCALL ALERT_PLAYJNB K3,$ ;K3为位移键SETB TR0RESET_TL:CALL ALERT_PLAYJNB FLAG2,R_TL01mov 75H,7fh ;送入熄灭符mov 76H,7fhCALL ALERT_PLAYJMP R_TL02R_TL01: CALL ALERT_TLmov 75h,7Eh ;送设定值mov 76h,7DhCALL ALERT_PLAY ;显示设定值R_TL02: JNB K1,K011AJNB K2,K011BJNB K3,RESET_THJMP RESET_TLK011A:INC TEMP_TLMOV A,TEMP_TLCJNE A,#120,K012A ;没有到设定上限值,转MOV TEMP_TL,#0K012A: CALL TL_DELJMP RESET_TLK011B:DEC TEMP_TLMOV A,TEMP_TLCJNE A,#00H,K012B ;没有到设定下限值,转MOV TEMP_TL,#119K012B: CALL TL_DELJMP RESET_TL;-------------------------------------------------------RESET_TH:CALL BEEP_BLJNB K3,$RESET_TH1:CALL ALERT_PLAYJNB FLAG2,R_TH01mov 75H,7fh ;送入熄灭符mov 76H,7fhCALL ALERT_PLAYJMP R_TH02R_TH01: CALL ALERT_THmov 75h,7Eh ;mov 76h,7DhCALL ALERT_PLAYR_TH02: JNB K1,K021AJNB K2,K021BJNB K3,K002JMP RESET_TH1K021A:INC TEMP_THMOV A,TEMP_THCJNE A,#120,K022A ;没有到设定上限值,转 MOV TEMP_TH,#0K022A: CALL TH_DELJMP RESET_TH1K021B:DEC TEMP_TH ;减1MOV A,TEMP_THCJNE A,#00H,K022B ;没有到设定下限值,转 MOV TEMP_TH,#119K022B: CALL TH_DELJMP RESET_TH1K002: CALL BEEP_BLCLR TR0 ;关闭中断RET;-----------------------------------------------------;键延时子程序;多次调用报警值显示程序来延时;-----------------------------------------------------TL_DEL: ;报警低值延时MOV R2,#0AHTL_DEL1: CALL ALERT_TLCALL ALERT_PLAYDJNZ R2,TL_DEL1RETTH_DEL: ;报警高值延时MOV R2,#0AHTH_DEL1: CALL ALERT_THCALL ALERT_PLAYDJNZ R2,TH_DEL1RET;==================================================== ;实时温度值与设定报警温度值 TH、TL 比较子程序;当实际温度大于 TH 的设定值时,显示“H”,继电器关闭。
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(含程序)
数字温度传感器DS18B20摘要DS-18B20 数字温度传感器具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
应用范围广泛,适用于冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温和控制领域,轴瓦,缸体,纺机,空调,等狭小空间工业设备测温和控制和汽车空调、冰箱、冷柜、以及中低温干燥箱等。
一、引脚图DS18B20引脚定义:(1)DQ为数字信号输入/输出端;(2)GND为电源地;(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)二、DS18B20的主要特性1.1、电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电1.2、DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯1.3、多个DS18B20可以并联在唯一的三线上,实现组网多点测温1.4、DS18B20在使用中不需要任何外围元件1.5、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃1.6、可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温1.7、在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快1.8、测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力1.9、负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。
三、DS18B20的外形和内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM 、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DS18B20内部结构图四、DS18B20工作原理DS18B20的温度转换时的延时时间由2s 减为750ms。
DS18B20测温原理如图3所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DS18B20温度采集程序[PIC16F877A+汇编语言];六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE<P16F877A.INC>#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_W DT_OFF&_HS_OSC;调试模式关闭,写保护,一半ROM可在线改写,EEPROM加密,低压编程关闭,掉电检测关闭,上电延时开,看门狗关,4M晶振HS振荡CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000us DQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序*******************************MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源 BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放 MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1 GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
MOVLW 8H ;一次读8位数据MOVWF COUNTREAD_18B20_1BANKSEL TRISABCF TRISA,0 ;数据线先设为输出BCF STATUS,RP0BCF DQ ;先拉低数据线MOVLW 1HMOVWF COUNT1DECFSZ COUNT1,1 ;拉低总线3usGOTO $-1BSF DQ ;释放总线BANKSEL TRISABSF TRISA,0 ;数据线设为输入BCF STATUS,RP0MOVLW 2HMOVWF COUNT1DECFSZ COUNT1,1 ;延时6msGOTO $-1BSF STATUS,CBTFSS DQ ;判断数据线状态BCF STATUS,CRRF TEMP,1 ;移位到TEMP中MOVLW 12HMOVWF COUNT1DECFSZ COUNT1,1GOTO $-1 ;读一位数据至少需要60us DECFSZ COUNT,1 ;是否读完8位GOTO READ_18B20_1RETURN。