基于FPGA的DS18B20控制程序设计及其Verilog实现(汇编)
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;说明:使用前,必须先对液晶显示模块进行初始化。
基于FPGA温度传感器DS18B20的Verilog设计
基于FPGA温度传感器DS18B20的Verilog设计赖青松(江西师范大学南昌电子信息工程)摘要: 本文利用数字温度传感器DS18B20 的数据接口和特点,阐述了一种基于现场可编程门阵列( FPGA)控制DS18B20的方法。
使用FPGA 作为控制器,严格控制DS18B20 的时序,在单总线上实现读写功能,完成测量数字温度的功能。
将测量的二进制数转换为BCD 码,并通过数码管显示。
系统设计使用Verilog 语言。
由于DS18B20 是采用一根I/ O 总线读写数据,因此DS18B20 对读写数据位有严格的时序要求。
DS18B20 遵循相应的通信协议从而保证数据传输的正确性和完整性。
该通信协议定义了多种信号时序:初始化时序、写时序、读时序1、初始化时序:During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480us. The bus master then releases the bus and goes into receive mode (RX). When the bus is released, the 5k pullup resistor pulls the 1-Wire bus high.When the DS18B20 detects this rising edge, it waits 15us to 60us and then transmits a presence pulse by pulling the 1-Wire bus low for 60us to 240us.初始化时序中,控制器发送一个480us-960us的低电平的复位信号,然后释放总线,也就是总线为高电平,此时,控制器准备接收DS18B20的反应信号,当总线释放后,如果存在DS18B20,那么DS18B20将在15-60us内发送一个持续60-240us的反应信号。
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字节。
18b20程序详解
#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit ds=P1^4; // 数据采集定义管脚code uchar table[]={ // 共阳数码管,段选0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,};code uchar table2[]={ //位选0x01,0x02,0x04} ;uint temp;float f_temp;void delay(uint time) //小的延时{while(time--){_nop_();_nop_();};}void delayms(uchar time){uchar i,j;for(i=0;i<time;i++)for(j=0;j<110;j++);}void close(){P2=0xa0; //关闭蜂鸣器P0=0x80;P2=0;P2=0x80; //关闭LEDP0=0xff;P2=0;void reset() //复位函数{ds=1;delay(8); //特别注意时间,比较严格ds=0;delay(80); //特别注意时间,比较严格ds=1;delay(15); //特别注意时间,比较严格}void writebyte(uchar dat) //写函数,从低位向高位开始写{uchar i;for(i=0;i<8;i++){ds=0;ds=dat&0x01;delay(5);ds=1;dat>>=1;}}uchar readbyte() //读函数,从低位向高位开始读{uchar i,dat;for(i=0;i<8;i++){ds=0;dat>>=1;ds=1;if(ds){dat|=0x80;}delay(5); //时间延时太长时数字闪烁}return dat;}void display(uchar add,uchar dat) //显示函数P2=0xc0;P0=table2[add];P2=0;P2=0xe0;P0=table[dat];P2=0;delayms(10);}void tempchange(){reset();writebyte(0xcc); //控制指令,跳过ROM,直接向18B20发送转换命令,适用于总线上只接一个18B20writebyte(0x44); //控制指令,温度转换,结果存入内部9字节的RAM中}uint get_temp(){uchar a,b;reset();writebyte(0xcc); //控制指令,跳过ROM,直接向18B20发送转换命令,适用于总线上只接一个18B20writebyte(0xbe); //控制指令,读暂存器,读内部RAM中九字节的温度数据a=readbyte(); //先读地位b=readbyte();temp=b;temp<<=8;temp|=a; //将char类型变量为int型变量f_temp=temp*0.0625;temp=f_temp*10+0.5;f_temp+=0.05; //温度转换return temp;}void main(){reset(); //复位close(); //关闭蜂鸣器和继电器,这个可以不要while(1) //不用也可以显示,但是有时候数字闪烁{tempchange(); //开始读取温度,必须放在while中,否则变换缓慢,而且胡乱显示display(0,get_temp()/100); //在数码管上显示display(1,get_temp()%100/10+10);display(2,get_temp()%10);}}心得体会:要严格控制时间,否则读不出数据,尤其是复位时间。
ds18b20汇编设计报告计划附电路图及程序
鉴于 AT89C51 单片机和 DS18B20 的数字温度计1课题说明跟着现代信息技术的飞快发展和传统工业改造的逐渐实现,能够独立工作的温度检测和显示系统应用于诸多领域。
传统的温度检测以热敏电阻为温度敏感元件。
热敏电阻的成本低,但需后续信号办理电路,并且靠谱性相对较差,测温正确度低,检测系统也有必定的偏差。
这里设计的数字温度计拥有读数方便,测温范围广,测温精准,数字显示,合用范围宽等特色。
本设计采纳 AT89C51型单片机作为主控制器件, DS18B20作为测温传感器 ,经过 LCD1602实现温度显示。
经过DS18B20直接读取被测温度值,进行数据变换,该器件的物理化学性能稳固,线性度较好,在 0℃~ 100℃最大线性偏差小于℃。
该器件可直接向单片机传输数字信号,便于单片机办理及控制。
此外,该温度计还可以直接采纳测温器件丈量温度,从而简化数据传输与办理过程。
2实现方法采纳数字温度芯片DS18B20 丈量温度,输出信号全数字化。
采纳了单总线的数据传输,由数字温度计 DS18B20和 AT89C51 单片机构成的温度丈量装置 ,它直接输出温度的数字信号 ,也可直接与计算机连结。
采纳 AT89C51单片机控制,软件编程的自由度大,可经过编程实现各种各种的算术算法和逻辑控制,并且体积小,硬件实现简单,安装方便。
该系统利用AT89S51芯片控制温度传感器 DS18B20进行及时温度检测并显示,能够实现迅速丈量环境温度,并能够依据需要设定上下限温度。
该系统扩展性特别强。
该测温系统电路简单、精准度较高、实现方便、软件设计也比较简单。
系统框图如图 1 所示。
电源电路LED 显示复位电路AT89C51DS18B20温度传感器时钟振荡电路图 1 DS18B20 温度测温系统框图3硬件设计单片机最小系统设计3.1.1 电源电路13VCCVin LM7805+5VVCC+12VD+5VNGR+ C12+ C34 70 uFC2 4 70 uFC2 1 K0.1u F0.1u FLEDGND图 2 电源电路3.1.2 振荡电路与复位电路XTAL1C1 30pF晶振12MHzAT89C51C2 30pFXTAL2图 3 振荡电路DS18B20与单片机的接口电路VCCR1AT89C51DS18B201 23VCCVccRESETR1C120022uFRST AT89C51R2 1KVss图 4 复位电路图 5DS18B20 与单片机的接口电路PROTEUS 仿真电路图图 6 PROTEUS仿真电路图4软件设计系统程序主要包含主程序、读取温度子程序、数据变换子程序、显示数据子程序等。
DS18B20汇编程序(完整版)
DS18B20汇编程序(完整版)DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分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&_WDT_OFF&_HS _OSC CBLOCK 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内读区数据线上的状态。
DS18B20汇编程序
FLAG BIT 00H;DS18B20存在标志位DQ BIT P3.7WD_L EQU 28HWD_H EQU 29H************程序起始********************ORG 0000HAJMP STARTORG 0030H**************主程序开始************START:MOV SP,#70HLCALL INIT_18B20LCALL RE_CONFIGLCALL GET_WDAJMP CHANGE**********DS18B20复位程序*****************INIT_18B20:SETB DQNOPCLR DQMOV R0,#0FBHDJNZ R0,$;延时SETB DQMOV R0,#25HDJNZ R0,$JNB DQ,TSR1AJMP TSR2TSR1:SETB FLAG;置标志位,表明DS18B20存在AJMP TSR3TSR2:CLR FLAG;清标志位,表明DS18B20不存在AJMP TSR4TSR3:MOV R0,#6BHDJNZ R0,$TSR4:SETB DQ;拉高总线RET********************设定DS18B20暂存器设定值************** RE_CONFIG:JB FLAG,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,#1FH;选择九位温度分辨率LCALL WRITE_18B20RET*****************读转换后的温度值****************GET_WD:SETB DQLCALL INIT_18B20JB FLAG,TSS1RET;若不存在则返回TSS1: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,#2MOV R1,#28H;低位存在28H,高位存在29H RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,AINC R1DJNZ R4,RE00RET************读出的温度进行数据转换************** CHANGE:MOV A,28HMOV C,29H.0;将29H中的最低位移入CRRC AMOV C,29H.1RRC AMOV C,29H.2RRC AMOV C,29H.3RRC AMOV 28H,ALCALL DISPLAY;调用数码管显示子程序LJMP MAIN*******************DISPLAY******DISPLAY:MOV A,28H;将28H中的十六进制数转换成10进制MOV B,#10;10进制/10=10进制DIV ABMOV SHI,A;十位在SHIMOV GW,B;个位在GWMOV DPTR,#TAB ;指定查表启始地址 MOV A,GW ;取个位数MOVC A,@A+DPTR ;查个位数的7段代码MOV 34H,A;送出个位的7段代码MOV A,SHI;取十位数MOVC A,@A+DPTR ;查十位数的7段代码MOV 35H,A;送出十位的7段代码RET。
数字温度传感器DS18B20汇编程序例子
;DS18B20温度传感器和7个LED数码显示程序(原创程序,请支持)ORG 0000H;LED数码管采用动态,P0口接八个数据口,P2.0-P2.2采用3-8译码器控制七个LED TX BIT P2.3 ;DS18B20数据口接P2.3FLAG BIT 10HTEMH EQU 50H ;整数部分TEML EQU 51H ;小数部分MOV SP,#60HCLR EAAJMP MAINORG 0200HMAIN:;MOV R0,#10LCALL TMP;温度传感器设置LCALL CHANG;温度转换为十进制STR:LCALL DISPLAY;温度显示;DJNZ R0,STRAJMP MAIN;//////////////////////////TMP:;温度传感器DS18B20LCALL RESERTMOV A,#0CCHLCALL WRITEMOV A,#44HLCALL WRITE;LCALL DELAY750;延时750MsLCALL RESERTMOV A,#0CCHLCALL WRITEMOV A,#0BEHLCALL WRITELCALL READMOV 30H,ALCALL READMOV 31H,ARETDELAY750:;750USDELAYSETB RS0MOV R0,#20MS2:MOV R1,#20MS1:MOV R2,#20DJNZ R2,$DJNZ R1,MS1DJNZ R0,MS2CLR RS0RET;////////////////////////////CHANG:;温度转换为十进制PUSH APUSH BMOV A,31HANL A,#07HSWAP AMOV B,AMOV A,30HANL A,#0F0HSWAP AADD A,BMOV TEMH,AMOV A,30HANL A,#0FHMOV TEML,AMOV A,31HJNB ACC.3,POSI;区分正负温度;//////////////负温度转化MOV A,TEMLSWAP ACPL AANL A,#0F0HADD A,#10HSWAP AMOV 1FH,CMOV TEML,AMOV A,TEMHCPL ASUBB A,#80HMOV C,1FHADDC A,#0MOV 70H,#20AJMP NEGPOSI:MOV A,TEMHMOV B,#100DIV ABMOV 70H,AMOV A,BNEG:MOV B,#10DIV ABMOV 71H,AMOV A,BADD A,#10MOV 72H,A;整数部分分离MOV A,TEMLMOV B,#5MUL ABMOV B,#10DIV ABMOV 76H,BMOV 75H,AMOV A,TEMLMOV B,#2MUL ABADD A,75HMOV B,#10DIV ABMOV 75H,BMOV 74H,AMOV A,TEMLMOV B,#6MUL ABADDC A,74HMOV B,#10DIV ABMOV 74H,BMOV 73H,A;小数部分分离POP BPOP ARET;//////////////////////DISPLAY:;温度显示70H---76H XXX.XXXX;采用默认的12位,精度0.0625,-55~~+125 SETB RS0MOV R0,#70HMOV R1,#7MOV R2,#0MOV DPTR,#TABLE DIS:MOV A,@R0MOVC A,@A+DPTR MOV P2,R2MOV P0,AINC R2INC R0LCALL DELAY1MS DJNZ R1,DISCLR RS0RET;/////////////////////////DELAY1MS:SETB RS1MOV R0,#100MS:MOV R1,#20DJNZ R1,$DJNZ R0,MSCLR RS1RET;//////////////////// RESERT:;DS18B20初始化;SETB RS0SETB TXNOPCLR TXMOV R0,#240;RST:CLR TXDJNZ R0,$;DELAY480US SETB TXMOV R1,#30;DELAY 60US DJNZ R1,$JNB TX,RE1CLR FLAGSETB TXRETRE1:SETB FLAGMOV R2,#200DJNZ R2,$ ;DELAY 400us SETB TXRET;///////////WRITE:;DS18B20写字节;SETB RS0CLR CMOV R0,#8WW:MOV R1,#6MOV R2,#23RRC ACLR TXDJNZ R1,$;DELAY 12USMOV TX,CDJNZ R2,$;DELAY 46USSETB TXNOPDJNZ R0,WWSETB TX;CLR RS0RET;///////////READ:;DS18B20读字节;SETB RS0CLR CMOV R0,#8;八位RE:SETB TXMOV R1,#10;延时20usMOV R2,#15 ;延时30usCLR TXNOPSETB TX;此句最重要,读取数据的时候一定要释放总线,否则读不出暂存器数据DJNZ R1,$MOV C,TXDJNZ R2,$RRC ADJNZ R0,RESETB TX;CLR RS0RET;//////////////TABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;0-9 需要加点应用ADD 80H即可DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH;0.-9.DB 40H ;-END。
DS18B20汇编程序编写实例
多路温度采集显示系统设计与总结报告参赛选手:摘要:在传统的模拟信号远距离温度测量系统中,需要很好的解决引线误差补偿问题、多点测量切换误差问题和放大电路零点漂移误差问题等技术问题,才能够达到较高的测量精度。
另外一般监控现场的电磁环境都非常恶劣,各种干扰信号较强,模拟温度信号容易受到干扰而产生测量误差,影响测量精度。
因此,在温度测量系统中,采用抗干扰能力强的新型数字温度传感器是解决这些问题的最有效方案,新型数字温度传感器DS18B20具有体积更小、精度更高、适用电压更宽、采用一线总线、可组网等优点,在实际应用中取得了良好的测温效果。
关键词:数字温度传感器,单总线Abstract: In the traditional analog signal long-distance temperaturemeasuring system, need good solve fuses error compensation problem, multi-point measurement error and amplifying circuit switching zero drift error problem and some other technical problems, only then can achieve high measuring accuracy. Also general monitoring site of the electromagnetic environment is very bad, all kinds of jam,affect precision,Therefore, in temperature measuring system, using anti-jamming ability of the new digital temperature sensor is to solve these problems, the most effective solution new digital temperature sensor DS18B20 have smaller, higher accuracy, voltage applied to wider and adopt 1-wire bus, etc, and networking in practical application made .Key word:Digital temperature sensor,1-wire bus目录1 系统方法选择和论证 (1)1.1 题目要求 (1)1.1.1 基本要求 (1)1.1.2 说明 (1)1.2 系统基本方案 (1)1.2.1 各模块方案选择和论证 (1)1.2.2 系统各模块的最终方案 (3)2.系统的硬件设计与实现 (3)2.1 系统的硬件基本组成部分 (3)2.2主要单元电路的设计 (4)2.2.1 传感器部分电路 (4)2.2.2七段数码管 (4)3.系统程序设计 (4)3.1系统的软件设计 (4)3.2 温度转换设计 (4)3.3 系统主程序流程图 (5)4.系统测试 (6)4.1 测试仪器 (6)4.2 指标测试 (6)4.2.1动态显示的测试 (6)4.2.2多路温度采集的测试 (6)4.2.3系统实现的功能 (6)4.3 结论 (6)5.总结 (6)参考文献 (6)附录1:元器件清单 (6)附录2:系统电路图 (7)附录3:程序清单 (8)附录4:DS18B20的通讯协议及读写复位等程序 (10)附录5:其他子程序的设计 (16)附录6:系统使用说明书........................................................... 错误!未定义书签。
基于FPGA的ds18b20温度传感器设计程序
module temper(input clk,input rst_n,inout one_wire,output [15:0] temperature);// 分频器20MHz->1MHz 开始reg [3:0] cnt;reg clk_1us;always @ (posedge clk, negedge rst_n)if (!rst_n)cnt <= 0;elseif (cnt == 9)begin cnt <= 0;clk_1us<= ~ clk_1us;endelsecnt <= cnt + 4'd1;// 1MHz 时钟//延时模块的使用reg [19:0] cnt_1us;reg cnt_1us_clear;always @ (posedge clk_1us)if (cnt_1us_clear)cnt_1us <= 0;elsecnt_1us <= cnt_1us + 1'b1;// DS18B20状态机开始// 格雷码parameter S00 = 5'h00;parameter S0 = 5'h01;parameter S1 = 5'h03;parameter S2 = 5'h02;parameter S3 = 5'h06;parameter S4 = 5'h07;parameter S5 = 5'h05;parameter S6 = 5'h04;parameter S7 = 5'h0C;parameter WRITE0 = 5'h0D;parameter WRITE1 = 5'h0F;parameter WRITE00 = 5'h0E;parameter WRITE01 = 5'h0A;parameter READ0 = 5'h0B;parameter READ1 = 5'h09;parameter READ2 = 5'h08;parameter READ3 = 5'h18;reg [4:0] state; // 状态寄存器//-------------------------------------reg one_wire_buf; // One-Wire总线缓存寄存器reg [15:0] temperature_buf; // 采集到的温度值缓存器reg [5:0] step; // 子状态寄存器0~50reg [3:0] bit_valid; // 有效位always @(posedge clk_1us, negedge rst_n)beginif (!rst_n)beginone_wire_buf <= 1'bZ;step <= 0;state <= S00;endelsebegincase (state)S00 : begintemperature_buf <= 16'h001F;state <= S0;endS0 : begin // 初始化cnt_1us_clear <= 1;one_wire_buf <= 0;state <= S1;endS1 : begincnt_1us_clear <= 0;if (cnt_1us == 500) // 延时500usbegincnt_1us_clear <= 1;one_wire_buf <= 1'bZ; // 释放总线state <= S2;endendS2 : begincnt_1us_clear <= 0;if (cnt_1us == 100) // 等待100usbegincnt_1us_clear <= 1;state <= S3;endendS3 : if (~one_wire) // 若18b20拉低总线,初始化成功state <= S4;else if (one_wire) // 否则,初始化不成功,返回S0state <= S0;S4 : begincnt_1us_clear <= 0;if (cnt_1us == 400) // 再延时400usbegincnt_1us_clear <= 1;state <= S5;endendS5 : begin // 写数据if (step == 0) // 0xCCbeginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 1)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 2)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 3)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 4)beginstep <= step + 1'b1;endelse if (step == 5)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 6)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 7)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 8) // 0x44 beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 9)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 10)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 11)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 12)beginstep <= step + 1'b1;endelse if (step == 13)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 14)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01;endelse if (step == 15)beginstep <= step + 1'b1;state <= WRITE0;end// 第一次写完,750ms后,跳回S0 else if (step == 16)beginone_wire_buf <= 1'bZ;step <= step + 1'b1; state <= S6;endelse if (step == 17) // 0xCC beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 18)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 19)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endbeginstep <= step + 1'b1;state <= WRITE01;one_wire_buf <= 0;endelse if (step == 21)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 22)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 23)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 24)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 25) // 0xBE beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 26)beginone_wire_buf <= 0;step <= step + 1'b1; state <= WRITE01; endelse if (step == 27)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 28)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 29)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 30)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;endelse if (step == 31)beginstep <= step + 1'b1;state <= WRITE0;endelse if (step == 32)beginone_wire_buf <= 0;step <= step + 1'b1;state <= WRITE01;end// 第二次写完,跳到S7,直接开始读数据else if (step == 33)beginstep <= step + 1'b1;state <= S7;endendS6 : begincnt_1us_clear <= 0;if (cnt_1us == 750000 | one_wire) // 延时750msbegincnt_1us_clear <= 1;state <= S0; // 跳回S0,再次初始化endendS7 : begin // 读数据if (step == 34)beginbit_valid <= 0;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 35)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 36)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 37)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 38)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 39)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 40)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 41)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 42)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 43)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 44)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 45)beginbit_valid <= bit_valid + 1'b1; one_wire_buf <= 0;step <= step + 1'b1; state <= READ0;endelse if (step == 46)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 47)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 48)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 49)beginbit_valid <= bit_valid + 1'b1;one_wire_buf <= 0;step <= step + 1'b1;state <= READ0;endelse if (step == 50)beginstep <= 0;state <= S0;endend// 写0.1WRITE0 :begincnt_1us_clear <= 0;one_wire_buf <= 0; // 输出0if (cnt_1us == 80) // 延时80usbeginone_wire_buf <= 1'bZ; // 释放总线,自动拉高state <= WRITE00;endendWRITE00 : // 空状态state <= S5;WRITE01 : // 空状态state <= WRITE1;WRITE1 :begincnt_1us_clear <= 0;one_wire_buf <= 1'bZ; // 输出1 释放总线,自动拉高if (cnt_1us == 80) // 延时80usbegincnt_1us_clear <= 1;state <= S5;endend// 读0READ0 : state <= READ1; // 空延时状态READ1 :begincnt_1us_clear <= 0;one_wire_buf <= 1'bZ; // 释放总线if (cnt_1us == 10) // 再延时10usbegincnt_1us_clear <= 1;state <= READ2;endendREAD2 : // 读取数据begintemperature_buf[bit_valid] <= one_wire;state <= READ3;endREAD3 :begincnt_1us_clear <= 0;if (cnt_1us == 55) // 再延时55usbegincnt_1us_clear <= 1;endend// 读状态机default : state <= S00;endcaseendendassign one_wire = one_wire_buf; // 注意双向口的使用(cichuzhuyaoyongyushurushuju)// DS18B20状态机结束// 对采集到的温度进行处理开始wire [15:0] t_buf = temperature_buf & 16'h07FF;assign temperature[3:0] = (t_buf[3:0] * 10) >> 4; // 小数点后一位assign temperature[7:4] = (t_buf[7:4] >= 10) ? (t_buf[7:4] - 10) : t_buf[7:4]; // 个位assign temperature[11:8] = (t_buf[7:4] >= 10) ? (t_buf[11:8] + 1) : t_buf[11:8]; // 十位endmodule。
基于FPGA的温度传感器DS18B20读写代码
1: begin dq <= 1'bz ; if (cnt == 17'd4) begin READ_BIT_CNT <= 2 ; cnt <= 17'd0 ; end else begin cnt <= cnt + 1'b1 ; end end
2: begin dq <= 1'bz ; tmp_bit <= dq ; if (cnt == 17'd1) begin READ_BIT_CNT <= 3 ; cnt <= 17'd0 ; end
WRITE_HIGH_CNT <= 2 ; end else begin
cnt <= cnt + 1'b1 ; end end 2: begin STATE <= WRITE_BYTE ; WRITE_HIGH_CNT <= 0 ; end default : begin WRITE_HIGH_CNT <= 0 ; end endcase end CMD_44 : begin write_temp <= 8'b01000100 ; STATE <= WRITE_BYTE ;
else begin
cnt <= cnt + 1'b1 ; end end 3: begin dq <= 1'bz ; if (cnt == 17'd55) begin
cnt <= 17'd0 ; READ_BIT_CNT <= 0 ; STATE <= GET_TMP ; end else begin cnt <= cnt + 1'b1 ; end end default : begin READ_BIT_CNT <= 0 ;
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温度控制数码管显示(汇编非常详细)
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介绍和汇编度温度程序-16页文档资料
基于proteus的51单片机仿真实例六十七、单总线温度传感器DS18B20读写实例标签: proteus 温度传感器单片机单总线实例2019-02-20 01:031、I2C总线器件与单片机之间的通信需要两根线,而单总线器件与单片机间的数据通信只要一根线。
单总线适用于单主机系统,能够控制一个或多个从机设备。
主机通常是单片机,从机可以是单总线器件,他们之间通过一条信号线进行数据交换,单总线上同样允许挂接多个单总线器件,因此,每隔单总线器件必须有各自固定的地址,但总线器件通常需要接一个4.7k左右的上拉电阻,这样,当总线空闲时,状态为高电平。
2、单总线器件的数据操作过程1)初始化单总线上的所有处理均从初始化开始,单片机先发送一个复位脉冲,当单总线其间接收到复位脉冲后,先单片机发出应答信号,以便通知单片机:该器件已经准备好等待下一步操作2)识别单总线器件总线上允许挂接多个但总线器件,为便于单片机识别,每个单总线器件在出厂前都分配好了64为序列号以作为地址序列码。
所以单片机能够根据该序列号来识别和判断对那一个单总线器件进行操作3)数据交换单片机与单总线器件之间的数据交换必须遵循严格的通信协议。
单总线协议定义了复位信号,应答信号,写/读0,写/读1的集中信号类型,所有的单总线命令都是由这些基本的信号类型组成的,除了应答信号外,其余信号都由单片机发出,并且发送的所有命令和数据都是低位在前,高位在后。
3、DS18B20的工作时序1)初始化单片机将数据线拉低480-960us后释放,等待15-60us,单总线器件即可输出一个持续时间为60-240us的低电平(应答信号),单片机受到此应答后即可进行后续操作2)写时序当主机将数据线的电平从高拉到低时,形成写时序,有写0和写1两种时序。
写时序开始后,DS18B20在15-60us期间从数据线上采样,如果采样到低电平,则向DS18B20写0,否则写1,两个独立的时序之间至少需要1us的回复时间按(拉高总线电平)3)读时序当主机从DS18B20读取数据时,产生读时序,此时,主机将数据线的电平从高拉到低使读时序被初始化。
基于FPGA的数字温度计电路的设计与实现
摘要本论文介绍了一个基于FPGA的数字温度计电路的设计与实现。
该电路采纳数字温度传感器DS18B20搜集外界环境温度,同时结合该传感器的数据接口和特点,利用FPGA作为操纵器,严格操纵DS18B20 的时序 ,在单总线上实现读写功能,完成测量数字温度的功能。
再将搜集的二进制数转换为BCD码 ,并通过数码管显示。
该系统软件设计通过 Verilog HDL 语言进行编译。
这次设计相较于传统的数字温度计具有结构简单,抗干扰能力强,功耗小,靠得住性高,反映时刻短等优势。
关键词:数字温度计;FPGA ;Verilog HDL ;DS18B20ABSTRACTThis paper expounds a design and implementation of a digital thermometer circuit based on FPGA. The circuit adopts the digital temperature sensor DS18B20 collecting the environment temperature, combining with the characteristics of the sensor data interface, using FPGA as the controller, strict control over the timing of DS18B20, read and write functions on 1-wire, complete the function of digital temperature measurement. Then measure the binary number into BCD code, and display it on the digital tube. The program design of the system is compiled by Verilog HDL language. Compared to the traditional digital thermometer, it has many advantages such as simpler structure, strong anti-interference ability, low consumption, high reliability, short reaction time.Keywords:Digital thermometer, FPGA, Verilog HDL, DS18B20目录1绪论 .................................................................. 错误!未定义书签。
DS18B20-51单片机汇编程序
DS18B20程序,51单片机汇编程序,仅需修改前几行即可。
晶振大小12M,转换完全正确。
DQ BIT P1.3 ;温度传感器接口TEMP_L EQU 29H ;用于保存读出温度的低字节TEMP_H EQU 28H ;用于保存读出温度的高字节TEMP_XIAO EQU 27H ;用于保存温度的小数部分TEMP_GE EQU 26H ;用于保存温度的个位部分TEMP_SHI EQU 25H ;用于保存温度的十位部分DQ_DELAY EQU 40H/*****************************************DS18B20温度转换程序,包括转换成小数、个位、十位*****************************************/// lOOP:// ACALL DS_GET_TEMP ;读取DS18B20温度// ACALL DOFOR_TEMP ;转换为十进制的十位、各位和小树部分// AJMP lOOPDS_RST: ;DS18B20复位函数SETB DQNOPCLR DQMOV DQ_DELAY,#66 ;延时约660usACALL DELAYSETB DQMOV DQ_DELAY,#6 ;延时约60usACALL DELAYMOV C,DQJC DS_RSTMOV DQ_DELAY , #24 ;延时约240usACALL DELAYSETB DQRETDS_WR_BYTE: ;写指令函数SETB DQMOV R4,#8CLR CDS_WR_LOOP:CLR DQMOV DQ_DELAY , #1 ;延时10us,短一些较好ACALL DELAYRRC AMOV DQ , CMOV DQ_DELAY , #5 ;延时50us,因为采样有效期为15-45usACALL DELAYSETB DQNOPDJNZ R4,DS_WR_LOOPRETDS_RD_BYTE: ;读指令函数MOV R4,#8DS_RD_LOOP:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV DQ_DELAY,#1 ;延时约10usACALL DELAYMOV C,DQMOV DQ_DELAY,#5 ;延时50usACALL DELAYRRC ADJNZ R4,DS_RD_LOOPMOV @R1,ARETDS_GET_TEMP: ;读取温度函数CLR EA ;由于DS18B20对时序要求较严格,所以采样期间关中断SETB DQACALL DS_RST ;执行指令之前,必须复位MOV A,#0CCH ;忽略64位ROM地址,直接发送存储器指令ACALL DS_WR_BYTEMOV A,#044H ;发送开始转换指令ACALL DS_WR_BYTESETB EA ;转换期间可以开中断MOV DQ_DELAY,#200 ;转换时间最长750ms,延时了800ms。
基于FPGA的DS18B20控制程序设计及其Verilog实现
基于FPGA的DS18B20控制程序设计及其Verilog实现一,总体介绍DS18B20是一个1-wire总线,12bit的数字温度传感器,其详细的参数这里不做具体的介绍,只讨论其基于Verilog的控制程序的设计。
实际上,对DS18B20的控制,主要是实现1-wire总线的初始化,读,写等操作,然后再根据DS18B20的控制要求,实现对其控制的verilog逻辑。
在1-Wire总线上,有一个master,可以有1个或者多个slave。
而对于FPGA+DS18B20的温度测试设计来讲,需要在FPGA上实现一个1-Wire总线的master。
DS18B20作为1-wire 总线的slave设备存在,可以有一个或者多个,不过为了简化程序,例程里假定只存在一个DS18B2020。
1-Wire总线的操作形式上相对简单,但操作本身相对却又比较复杂。
用Verilog做控制程序设计时,可以采用多层次嵌套的状态机来实现。
二,FPGA + DS18B20的硬件设计硬件的设计非常简单,只需要将DS18B20的DQ与FPGA的一个IO连接,并加4.7K左右的上拉电阻就可以了。
VDD和VPU可以为3.0~5.0V。
这里我们参照FPGA本身的IO电压,选择3.3V。
另外要注意的一点是,由于DQ的数据是双向的,所以FPGA的该IO要设定为inout类型。
三,1-Wire总线的基本操作及Verilog实现。
根据1-Wire总线的特点,可以把1-Wire总线的操作归结为初始化,单bit读操作,单bit写操作等最基础的几种。
下面分别是几种基本操作的介绍和verilog实现。
由于DS18B20的时序操作的最小单位基本上是1us,所以在该设计中,全部采用1MHz的时钟。
1. 初始化初始化实际上就是1-wire总线上的Reset操作。
由master发出一定长度的初始化信号。
Slave 看到该初始化信号后,在一定时间内发出规定长度的响应信号,然后初始化操作就结束了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于FPGA的DS18B20控制程序设计及其Verilog实现一,总体介绍DS18B20是一个1-wire总线,12bit的数字温度传感器,其详细的参数这里不做具体的介绍,只讨论其基于Verilog的控制程序的设计。
实际上,对DS18B20的控制,主要是实现1-wire总线的初始化,读,写等操作,然后再根据DS18B20的控制要求,实现对其控制的verilog逻辑。
在1-Wire总线上,有一个master,可以有1个或者多个slave。
而对于FPGA+DS18B20的温度测试设计来讲,需要在FPGA上实现一个1-Wire总线的master。
DS18B20作为1-wire 总线的slave设备存在,可以有一个或者多个,不过为了简化程序,例程里假定只存在一个DS18B2020。
1-Wire总线的操作形式上相对简单,但操作本身相对却又比较复杂。
用Verilog做控制程序设计时,可以采用多层次嵌套的状态机来实现。
二,FPGA + DS18B20的硬件设计硬件的设计非常简单,只需要将DS18B20的DQ与FPGA的一个IO连接,并加4.7K左右的上拉电阻就可以了。
VDD和VPU可以为3.0~5.0V。
这里我们参照FPGA本身的IO电压,选择3.3V。
另外要注意的一点是,由于DQ的数据是双向的,所以FPGA的该IO要设定为inout类型。
三,1-Wire总线的基本操作及Verilog实现。
根据1-Wire总线的特点,可以把1-Wire总线的操作归结为初始化,单bit读操作,单bit写操作等最基础的几种。
下面分别是几种基本操作的介绍和verilog实现。
由于DS18B20的时序操作的最小单位基本上是1us,所以在该设计中,全部采用1MHz的时钟。
1. 初始化初始化实际上就是1-wire总线上的Reset操作。
由master发出一定长度的初始化信号。
Slave 看到该初始化信号后,在一定时间内发出规定长度的响应信号,然后初始化操作就结束了。
下图是DS18B20的datasheet上给出的初始化的时序要求图示。
我们用一个简单的状态机来实现对DS18B20初始化的操作。
根据初始化的时序要求,设计一个有3个状态的简单的状态机,这三个状态分别是RST_IDLE,RST_MINIT和RST_SINIT。
系统初始化时,处于RST_IDLE状态,当RST_EN信号有效时,进入RST_MINIT状态,由master发出初始化信号。
当master的初始化信号发出一定时间以后,直接进入RST_SINIT 状态。
在RST_SINIT状态时,master去观察slave是否输出了正确的状态:如果slave没有输出正确的状态,则状态机重新回到RST_MINIT状态,由master重新发出初始化信号;如果slave输出了正确的状态,则意味着初始化正确完成,状态机回到RST_IDLE状态,整个初始化过程完成(这个文章里涉及到比较多的状态机,但状态机的转换都很简单,所以不会给出状态机的状态转换图,仅仅会用文字做简单叙述,有疑问的地方,可以仔细阅读相关代码)。
wire RST_EN;wire RST_OVER;parameter RST_IDLE = 3'b001, //IDLE 状态RST_MINIT = 3'b010, //master 初始化操作RST_SINIT = 3'b100; //slave 初始化应答reg [2:0] RSTSM, RSTSMNXT;wire PHASE_RST_IDLE = RSTSM[0];wire PHASE_RST_MINIT = RSTSM[1];wire PHASE_RST_SINIT = RSTSM[2];wire PHASENXT_RST_IDLE = RSTSMNXT[0];always @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)RSTSM <= RST_IDLE;elseRSTSM <= RSTSMNXT;endreg [9:0] MASTER_CNT; //用来控制master发出初始化信号的长度always @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)MASTER_CNT <= 10'b0;else if(~PHASE_RST_MINIT)MASTER_CNT <= 10'b0;elseMASTER_CNT <= MASTER_CNT + 10'b1;endreg [9:0] SLAVE_CNT; //用来判断slave是否在恰当时间返回初始化结束的信号always @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)SLAVE_CNT <= 10'b0;else if(~PHASE_RST_SINIT)SLAVE_CNT <= 10'b0;elseSLAVE_CNT <= SLAVE_CNT + 10'b1;endreg SLAVE_IS_INIT; //采集并保存slave发出的初始化结束信号always @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)SLAVE_IS_INIT <= 1'b1;else if(SLAVE_CNT == 10'd70)SLAVE_IS_INIT <= DQ_IN;else if(PHASE_RST_MINIT)SLAVE_IS_INIT <= 1'b1;elseSLAVE_IS_INIT <= SLAVE_IS_INIT;endalways @(RSTSM or RST_EN or MASTER_CNT or SLAVE_CNT or SLAVE_IS_INIT ) begin case(RSTSM)RST_IDLE:if(RST_EN)RSTSMNXT = RST_MINIT;elseRSTSMNXT = RST_IDLE;RST_MINIT:if(MASTER_CNT == 10'd500)RSTSMNXT = RST_SINIT;elseRSTSMNXT = RST_MINIT;RST_SINIT:if( (SLAVE_CNT == 10'd500) & ~SLAVE_IS_INIT)RSTSMNXT = RST_IDLE;else if((SLAVE_CNT == 10'd500) & SLAVE_IS_INIT)RSTSMNXT = RST_MINIT;elseRSTSMNXT = RST_SINIT;default:RSTSMNXT = RST_IDLE;endcaseendassign RST_OVER = PHASE_RST_SINIT & PHASENXT_RST_IDLE; //初始化完成标志信号下图是用示波器抓出的初始化过程DQ信号的波形(红色)。
2. 单bit读操作在1-wire总线上,读数据的操作实际上是按bit来完成的。
每次master可以从slave读回一个bit的数据。
读回的数据可能是1或者0。
下图是DS18B20的datasheet上给出的单bit读操作的时序要求图示。
需要注意的是,对于master来讲,无论读回来的数据是1还是0,其本身的操作及时序都是一样的,没有差异。
仍然用一个简单的状态机来实现对DS18B20的单bit读操作。
设计一个有5个状态的简单的状态机,这五个状态分别是RD_IDLE,RD_MPL,RD_MSAP,RD_WAIT和RD_OVER。
系统初始化时,处于RD_IDLE状态,当RDBEGIN信号有效时,进入RD_MPL状态,由master发出读信号。
3us以后,进入RD_MSAP状态(master在该状态结束的前一个us读取DQ上的值作为读bit的结果),在11us以后,进入RD_WAIT状态,而在读bit开始后的59us,系统进入RD_OVER状态,意味着读bit操作结束。
RD_OVER状态是为了符合1-Wire总线的操作规范(在每个操作之间至少有1us的总线空闲时间)而存在的。
wire RDBEGIN ;parameter RD_IDLE = 5'b00001, //resister pullup, larger than 1usRD_MPL = 5'b00010, //master pull low, larger than 1usRD_MSAP = 5'b00100, //ds18b20 pull low(read 0) or resister pullup(read 1), master sample data, near 15usRD_WAIT = 5'b01000, //ds18b20 pull low(read 0) or resister pullup(read 1)RD_OVER = 5'b10000; //resister pullup, larger than 1usreg [4:0] RDSM, RDSMNXT;wire PHASE_RD_IDLE = RDSM[0];wire PHASE_RD_MPL = RDSM[1];wire PHASE_RD_MSAP = RDSM[2];wire PHASE_RD_OVER = RDSM[4];reg [5:0] RD_CNT;always @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)RD_CNT <= 6'b0;else if(~PHASE_RD_IDLE)RD_CNT <= RD_CNT + 6'b1;elseRD_CNT <= 6'b0;endalways @(posedge CLK1MHZ or negedge RESET)beginif(~RESET)RDSM <= RD_IDLE;elseRDSM <= RDSMNXT;endalways @(RDSM or RDBEGIN or RD_CNT) begincase(RDSM)RD_IDLE:if(RDBEGIN)RDSMNXT = RD_MPL;elseRDSMNXT = RD_IDLE;RD_MPL:if(RD_CNT == 6'd3)RDSMNXT = RD_MSAP;elseRDSMNXT = RD_MPL;RD_MSAP:if(RD_CNT == 6'd14)RDSMNXT = RD_WAIT;elseRDSMNXT = RD_MSAP;RD_WAIT:if(RD_CNT == 6'd59)RDSMNXT = RD_OVER;elseRDSMNXT = RD_WAIT;RD_OVER:if(RD_CNT == 6'd61)RDSMNXT = RD_IDLE;elseRDSMNXT = RD_OVER;default:RDSMNXT = RD_IDLE;endcaseendreg RD_BIT_DATA; //读bit操作获得的数据always @(posedge CLK1MHZ or negedge RESET) beginif(~RESET)RD_BIT_DATA <= 1'b0;else if( PHASE_RD_MSAP & (RD_CNT == 6'd13) )RD_BIT_DATA <= DQ;else if(PHASE_RD_IDLE)RD_BIT_DATA <= 1'b0;elseRD_BIT_DATA <= RD_BIT_DATA;end3. 单bit写操作在1-Wire总线上,写数据的操作也是按bit来完成的。