基于FPGA的DS18B20控制程序设计及其Verilog实现(汇编)

合集下载

DS18B20汇编程序

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设计

基于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温度传感器数字温度传感器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程序详解

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汇编设计报告计划附电路图及程序

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汇编程序;实验目的:熟悉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汇编程序

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汇编程序例子

;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。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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来完成的。

相关文档
最新文档