mega16 DS18B20程序7.3728MHz

合集下载

DS18B20的工作原理

DS18B20的工作原理

DS18B20的工作原理DS18B20是一款数字温度传感器,它采用单总线接口进行通信,并且具有高精度、低功耗和可编程分辨率的特点。

在本文中,我将详细介绍DS18B20的工作原理,包括其硬件结构和通信协议。

1. 硬件结构DS18B20由温度传感器、控制逻辑和存储器组成。

温度传感器采用基于硅的温度传感器技术,能够测量环境温度并将其转换为数字信号。

控制逻辑负责控制传感器的工作模式和数据传输。

存储器用于存储温度传感器的惟一标识符和用户可编程的配置寄存器。

2. 工作原理DS18B20采用单总线接口进行通信,这意味着它只需要一个引脚来进行数据传输和控制。

传感器和主控设备之间的通信是通过发送和接收脉冲来实现的。

在通信开始之前,主控设备会发送复位脉冲,以确保传感器处于正确的工作状态。

接下来,主控设备发送指令给传感器,指令包括读取温度、写入配置等操作。

传感器根据指令执行相应的操作,并将结果发送回主控设备。

为了确保数据的准确性,DS18B20采用了一种叫做1-Wire协议的通信协议。

在这个协议中,数据是通过脉冲的持续时间来表示的。

逻辑“0”的脉冲持续时间较短,而逻辑“1”的脉冲持续时间较长。

主控设备和传感器之间的通信是通过发送和接收这些脉冲来实现的。

3. 数据传输DS18B20的数据传输包括三个阶段:复位、命令和数据。

在复位阶段,主控设备发送一个复位脉冲,以确保传感器处于正确的工作状态。

在命令阶段,主控设备发送指令给传感器。

指令包括读取温度、写入配置等操作。

传感器根据指令执行相应的操作,并将结果发送回主控设备。

在数据阶段,传感器将温度数据转换为数字信号,并通过单总线接口发送给主控设备。

主控设备接收到数据后,可以进行进一步的处理和显示。

4. 应用领域由于DS18B20具有高精度、低功耗和可编程分辨率的特点,它在许多领域得到了广泛应用。

在工业领域,DS18B20可用于温度监测和控制系统,如温度计、温度报警器等。

在农业领域,DS18B20可用于温室、畜牧场等环境温度的监测和控制。

ATmega16的DS18B20测温程序

ATmega16的DS18B20测温程序
//DS18B20初始化程序 uchar ds18b20_reset() {
unsigned char errTime=0;//用于循环计数
DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低
Delay_Us(500);//保持500us(最小为480us,最大为960us) DQ_IN;//1 _NOP(); while(DQ_R)//探测 IO 引上是上升沿 {
uchar i; for(i=0;i<8;i++)//1个字节有8位,1位1位的传输
{ DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低 Delay_Us(10);//按照写1时序,在15us 中完成所以延时10us if(value&0x01)//判断此时写入的值是1还是0 { DQ_SET;//如果是1,总线拉高,使得18B20能采样 } else DQ_CLR; Delay_Us(100);//如果是0(低电平)就不用管,继续延时(15+15+30=60us,100us 足够) DQ_SET;//释放总线 value=value>>1;//每次传输完后移位 } } uint ds18b20_read_byte(void)//18B20读一个字节的程序 { uint i,value;
for(i=0;i<8;i++) {
value=value>>1;//移位,最后一次读正好是最高位 DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低 Delay_Us(10);//>1us,<15us 控制器读1时序 DQ_SET;//总线释放准备采样 DQ_IN;//采样,设置成输入 if(DQ_R)//如果读到的值是1 { value|=0x80;//从低位开始读取 } Delay_Us(50);//>45us } return value; } //读取温度值先读取暂存器的值在进行温度转换否则会意外出错 unsigned int readTempDS18B20(void) {

实验 mega16 18B20程序8M晶振

实验 mega16 18B20程序8M晶振

#include <iom16v.h>#include <D:\A VR.H>/****************************************************************************** **位变量操作宏定义******************************************************************************* */#define BIT_SET(a,b) a|=BIT(b)#define BIT_CLR(a,b) a&=~BIT(b)#define BIT_INV(a,b) a^=BIT(b)#define BIT_STATUS(a,b) a&BIT(b)/****************************************************************************** **晶振频率:8MHZ DS18B20操作定义******************************************************************************* */#define CLR_DS18B20 BIT_CLR(PORTB,PB0) //数据线强制拉低#define SET_DS18B20 BIT_SET(PORTB,PB0) //数据线强制拉高,上拉#define HLD_DS18B20 BIT_SET(DDRB,PB0) //Mega16控制总线#define RLS_DS18B20 BIT_CLR(DDRB,PB0) //释放总线#define STU_DS18B20 BIT_STATUS(PINB,PB0) //数据线的状态#define DELAY_MIN 1100/********************************************************************** functionName: void delayUs(uchar temp)description :延时函数晶振频率:7.3728MHZdelayUs(1); //2.71usdelayUs(2); //3.53usdelayUs(4); //5.15usdelayUs(8); //8.41usdelayUs(16); //14.92usdelayUs(32); //27.94usdelayUs(64); //53.98usdelayUs(128); //106.07usdelayUs(255); //209.42usdelayUs(18); //16.55usdelayUs(34); //29.57usdelayUs(35); //30.38usdelayUs(100); //83.28_NOP(); //0.14us**********************************************************************/void delayUs(uchar temp){while(temp--);}void delay_1ms(void){uint i;for (i=0;i<DELAY_MIN;i++);//DR();}void delay_nms(uint n){uint i;for (i=0;i<n;i++)delay_1ms();}/********************************************************************** functionName: uchar resetDS18B20(void)description :DS18B20初始化**********************************************************************/uchar resetDS18B20(void){uchar errTime=0;RLS_DS18B20; //释放总线_NOP();HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低delayUs(277); //209.42usdelayUs(255); //209.42usdelayUs(108); //83.28us//以上的三个延时大于480usRLS_DS18B20; //释放总线,总线自动上拉_NOP();while(STU_DS18B20){delayUs(4); //5.15userrTime++;if(errTime>25)return(0x01); //如果等带大于约5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)}errTime=0;while(!(STU_DS18B20)){delayUs(4); //5.15userrTime++;if(errTime>50)return(0x02); //如果等带大于约5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)}return(0xff); //返回显示}/********************************************************************** functionName: uchar readByteDS18B20(void)description :读DS18B20一个字节**********************************************************************/uchar readByteDS18B20(void){uchar i;uchar retVal=0;RLS_DS18B20; //释放总线for(i=8;i>0;i--){retVal>>=1;HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();//延时大于1usRLS_DS18B20; //释放总线,DS18B20会将总线强制拉低NOP();NOP();NOP();if(STU_DS18B20)////读取总线上的电平retVal|=0x80;delayUs(17); //14.92usdelayUs(17); //14.92usRLS_DS18B20; //释放总线delayUs(37); //30.38us}delayUs(1); //2.71us(大于1us就行了)return(retVal);}/********************************************************************** functionName: uchar readByteDS18B20(void)description :写DS18B20一个字节**********************************************************************/ void writeByteDS18B20(uchar wb){uchar i;uchar temp;RLS_DS18B20; //释放总线for(i=0;i<8;i++){HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低delayUs(16); //14.92ustemp=wb>>i;temp&=0x01;if(temp)RLS_DS18B20; //释放总线elseCLR_DS18B20; //强制拉低delayUs(16); //14.92usdelayUs(35); //30.38usRLS_DS18B20; //释放总线delayUs(1); //2.71us(大于1us就行了)}}/********************************************************************** functionName: unsigned int readTempDS18B20(void)description :读DS18B20温度**********************************************************************/ unsigned int readTempDS18B20(void){uchar tempL,tempH;uint x;resetDS18B20();writeByteDS18B20(0xcc); //跳过ROMwriteByteDS18B20(0x44); //启动温度转换delayUs(1);resetDS18B20();writeByteDS18B20(0xcc); //跳过ROMwriteByteDS18B20(0xbe); //读数据tempL=readByteDS18B20();delayUs(20);tempH=readByteDS18B20();delayUs(20);x=(tempH<<8)|tempL;return(x);}。

温度传感器DS18B20检测程序说明

温度传感器DS18B20检测程序说明

DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。

编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。

对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。

接下来我先说一下这三个部分所对应的时序图的理解吧。

初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。

上面一图是写入数据的时序图。

写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。

下面一图是读取数据的时序图。

读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。

下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。

#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。

DS18B20工作过程及时序

DS18B20工作过程及时序

DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。

高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。

初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。

初始时,计数器1预置的是与-55℃DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。

高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。

初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。

初始时,计数器1预置的是与-55℃相对应的一个预置值。

以后计数器1每一个循环的预置数都由斜率累加器提供。

为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。

计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。

DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。

在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。

这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±,即0.25℃。

温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。

测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。

DS18B20内部数据结构

DS18B20内部数据结构

DS18B20内部数据结构DS18B20 是一种常用的数字式温度传感器,广泛应用于各种温度测量场景。

要深入理解 DS18B20 的工作原理和应用,了解其内部数据结构是非常重要的。

DS18B20 的内部数据主要包括配置寄存器、温度值寄存器以及其他一些相关的寄存器。

首先,配置寄存器用于设置传感器的工作模式和分辨率等参数。

通过对配置寄存器的正确设置,可以选择不同的温度分辨率,例如 9 位、10 位、11 位或 12 位。

不同的分辨率对应着不同的温度测量精度和转换时间。

在温度值寄存器中,存储着实际测量得到的温度数据。

温度值以补码的形式存储。

这意味着,当读取到温度值时,需要进行相应的转换计算才能得到实际的温度值。

以 12 位分辨率为例,温度值被分为符号位和数值位。

最高位为符号位,其余11 位为数值位。

如果符号位为0,表示温度为正值;如果符号位为 1,表示温度为负值。

对于正值的温度,将数值位直接转换为十进制数值,然后乘以分辨率,即可得到实际温度值。

而对于负值的温度,需要先将补码转换为原码,再进行上述的计算。

例如,如果读取到的温度值为 0x07D0(12位分辨率),首先判断最高位为 0,说明是正值。

将 0x07D0 转换为十进制为 2000。

因为 12 位分辨率下,每个计数代表 00625℃,所以实际温度为 2000×00625 = 1250℃。

DS18B20 内部还有一些其他的寄存器,用于存储诸如 CRC 校验值等信息,以确保数据传输的准确性。

CRC(循环冗余校验)是一种常用的数据校验方法,通过对传输的数据进行特定的计算,生成一个校验值。

接收方在接收到数据后,也进行相同的计算,并将计算得到的校验值与接收到的校验值进行比较,如果两者相同,则说明数据传输没有错误;如果不同,则说明数据在传输过程中出现了错误。

了解 DS18B20 的内部数据结构,对于正确读取和处理温度数据至关重要。

在实际应用中,我们需要根据具体的需求设置合适的分辨率,并通过正确的时序和通信协议读取温度值寄存器中的数据,然后进行相应的转换和处理。

基于DS18B20的Mega16单片机温度采集系统

基于DS18B20的Mega16单片机温度采集系统

基于DS18B20的Mega16单片机温度报警系统陆和亮(2010800631)袁彦凯(2011110144)滕木(2011110111)王锐英(2011110132)设计思想:这次设计的是基于DS18B20的数字温度计,它具有读数方便,测温范围广,测温精确,数字显示,适用范围宽等特点。

1.设计中选用Mega16型单片机作为主控制器件。

2.采用DS18B20数字温度传感器作为测温元件,通过4位共阳极LED数码显示管并行传送数据,实现温度显示。

3.ADC0808和一个LF351运放构成电压放大器,实现温度和电压的转换。

工作流程:Mega16通过DS18B20直接读取被测温度值,送入单片机进行数据处理,之后单片机进行判断和比较并且输出6位LED数码管,并且将读取到的温度值进行比例运算输出ADC0808和运算放大器结合输出合适的温度。

最终完成了数字温度计的总体设计。

其系统构成简单,信号采集效果好,数据处理速度快,便于实际检测使用。

设计内容简介:本设计的内容主要对系统硬件部分的设计,包括温度采集电路和显示电路;再次对系统软件部分的设计,应用C语言实现温度的采集与显示。

并且附上部分源代码。

设计要求:温度报警器设计,具体要求如下:1.将被测温度(0~100摄氏度)转换为电压值;2.小于10摄氏度或大于30摄氏度,光报警(LED亮);3.可采用电阻组成测量电桥、具体方案:1、根据设计要求,选用Mega16单片机为核心器件;2、温度检测器件采用DS18B20数字式温度传感器,利用单总线式连接方式与单片机的串行接口PORTD.2引脚相连;3、显示电路采用6个LED数码管显示器接口和PORTD,PORTC口相连并行显示温度值一.单片机外围电路设计Mega16单片机系统包括晶体振荡电路、复位开关和电源部分。

下图为Mega16单片机的最小系统。

二.温度测量模块温度测量传感器采用DALLAS公司DS18B20的单总线数字化温度传感器,测温范围为-55℃~125℃,可编程为9位~12位A/D转换精度,测温分辨率达到0.0625℃,采用寄生电源工作方式,CPU只需一根口线便能与DS18B20通信,占用CPU口线少,可节省大量引线和逻辑电路三.显示报警模块显示部分选用4位Led数码管。

DS18B20数字温度计的主程序

DS18B20数字温度计的主程序

主程序ORG 0000HLJMP STARTSTART: MOV DISBUF4,#00H ;开始,初始化MOV DISBUF5, #00HMAIN: ;主程序LCAAL KEY ;调按键预置数子程序CLR RS1CLR RS0LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配------0CCLCALL WRITE ;调DS18B20子程序MOV A,#44H ;发出温度转换命令LCALL WRITE ;调DS18B20子程序LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配LCALL WRITE ;调DS18B20子程序MOV A,#0BEH ;发出读取温度值命令LCALL WRITE ;调DS18B20子程序LCALL READ ;调DS18B20子程序MOV A, 3DHMOV 29H,ALCALL READMOV A, 3DHMOV 28H,AMOV R0, #34HMOV A, 28HRLC AMOV 47H,CJNB 47H, BTOD1 ;28H中的最高位是不是为1(温度<0);小于0的温度值不处置,大于0顺序执行BTOD1: MOV A, 28HRRC AMOV 40H,CRRC AMOV 41H,CRRC AMOV 42H,CRRC AMOV 43H,CMOV A, 29HMOV 27H, AMOV C,40H ;将28H中的最低位移入C,40H41H42H43H ;为28H中的位地址RRC A ;将28H中的低4位移到A的高4位MOV C, 41HRRC AMOV C, 42HRRC AMOV C, 43HRRC AMOV 29H,A ;将28H中的低4位放入29H中MOV A, 29H ;将29H中的十六进制数转换成10进制MOV B, #100DIV ABMOV @R0, A ;百位存于34HMOV @R0, #11H ;百位不显示DEC R0MOV A, #10XCH A, BDIV ABMOV @R0, A ;十位存于33HDEC R0MOV @R0, B ;个位存于32HDEC R0ANL 27H, #0FH ;小数点后一名进制转换MOV A, 27HMOV B, #06HMUL ABMOV B, #10DIV ABMOV @R0, A ;小数点后一名存于31HMOV DISBUF0,33H ;十位MOV DISBUF1,32H ;个位MOV DISBUF2,31H ;小数位MOV DISBUF3, #0H ;置0MOV DISBUF6, #0HMOV DISBUF7, #0HLCALL CMP ;调比较报警子程序LCALL DISPLAY ;调显示子程序LJMP MAIN ;转到MAINDS18B20复位子程序RESET: NOPL0: CLR ;拉低数据线MOV R2,#200 ;发出600us的复位脉冲L1: NOPDJNZ R2, L1SETB ;主机释放数据线MOV R2,#30 ;DS18B20等待60usL4: DJNZ R2, L4CLR CORL C, ;DS18B20数据变低(存在脉冲)吗?JC L3 ;DS18B20未预备好,从头初始化MOV R6, #80L5: ORL C,JC L3 ;DS18B20数据变高,初始化成功DJNZ R6,L5 ;数据线低电平可持续3us*80=240us SJMP L0 ;初始化失败,从头初始化L3: MOV R2, #250L2: DJNZ R2,L2 ;DS18B20应答500usRET读DS18B20子程序READ: MOV R6,#8 ;循环8次,读一个字节RE1: CLRMOV R4, #6NOPNOPSETBRE2: DJNZ R4,RE2 ;等待8USMOV C, ;读DS18B20的数据RRC A ;读取的数据移入AMOV R5, #30DJNZ R6,RE1 ;读完一个字节的数据MOV 3DH,A ;数据存入3DH中SETB ;把数据线拉高RET写DS18B20子程序;写DS18B20的子程序, 从DS18B20中写出一个字节的数据WRITE: MOV R3,#8 ;循环8次,写一个字节WR1: SETB ;拉高数据线MOV R4, #8RRC A ;写入位从A中移到CYCLRWR2: DJNZ R4,WR2 ;等待16USMOV ,C ;命令字按位依次送给DS18B20MOV R4, #20WR3: DJNZ R4,WR3 ;保证写进程持续40USDJNZ R3,WR1 ;未写完一个字节转WR1继续SETB ;写完一个字节,数据线置高RET比较报警子程序CMP: MOV A,DISBUF0 ;实际测量温度值放在DISBUF8中SWAP AMOV DISBUF8, AMOV A, DISBUF1ORL A, DISBUF8MOV DISBUF8, AMOV A,DISBUF4 ;预置温度值放在DISBUF9中SWAP AMOV DISBUF9, AMOV A, DISBUF5ORL A, DISBUF9MOV DISBUF9, ACLR CMOV A, DISBUF8SUBB A, DISBUF9JNC KK ;没有借位,即实际温度值大于;预置温度值转KKCLR ;有借位,即实际温度值小于预置温度值;置0,不发报警信号RETKK: SETB ;置1,即发出报警标志发光二极管亮RET按键子程序KEY: JNB , YZBWJNB , YZSWLJMP KEYRET YZBW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF4CJNE A, #10,KEYRETMOV DISBUF4, #0LJMP KEYRETYZSW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF5CJNE A, #10,KEYRETMOV DISBUF5, #0 KEYRET: RET显示子程序DISPLAY: MOV A, DISBUF0MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000001BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF1MOV DPTR, #SEGMOVC A, @A+DPTRORL A, #80HMOV P1, AMOV P2, #00000010BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF2MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000100BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF3MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00001000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF4MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00010000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF5MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00100000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF6MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF7MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BRET; (00) (01) (02) (03) (04)SEG: DB 03FH, 06H, 05BH, 04FH, 066H ; (05) (06) (07) (08) (09)DB 06DH, 07DH, 007H, 07FH, 06FH ;延时子程序DELAY1: MOV R1, #0A0HDEL11: NOPDJNZ R1, DEL11RETEND;工作内存概念:DISBUF0 EQU 10H DISBUF1 EQU 11H DISBUF2 EQU DISBUF1+1 DISBUF3 EQU DISBUF2+1 DISBUF4 EQU DISBUF3+1 DISBUF5 EQU DISBUF4+1 DISBUF6 EQU DISBUF5+1 DISBUF7 EQU DISBUF6+1 DISBUF8 EQU DISBUF7+1 DISBUF9 EQU DISBUF8+1。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <iom16v.h>#include <D:\A VR.H>/****************************************************************************** **位变量操作宏定义******************************************************************************* */#define BIT_SET(a,b) a|=BIT(b)#define BIT_CLR(a,b) a&=~BIT(b)#define BIT_INV(a,b) a^=BIT(b)#define BIT_STATUS(a,b) a&BIT(b)/****************************************************************************** **晶振频率:7.3728MHZ D S18B20操作定义******************************************************************************* */#define CLR_DS18B20 BIT_CLR(PORTB,PB0) //数据线强制拉低#define SET_DS18B20 BIT_SET(PORTB,PB0) //数据线强制拉高,上拉#define HLD_DS18B20 BIT_SET(DDRB,PB0) //Mega16控制总线#define RLS_DS18B20 BIT_CLR(DDRB,PB0) //释放总线#define STU_DS18B20 BIT_STATUS(PINB,PB0) //数据线的状态#define DELAY_MIN 1100/********************************************************************** functionName: void delayUs(uchar temp)description :延时函数晶振频率:7.3728MHZdelayUs(1); //2.71usdelayUs(2); //3.53usdelayUs(4); //5.15usdelayUs(8); //8.41usdelayUs(16); //14.92usdelayUs(32); //27.94usdelayUs(64); //53.98usdelayUs(128); //106.07usdelayUs(255); //209.42usdelayUs(18); //16.55usdelayUs(34); //29.57usdelayUs(35); //30.38usdelayUs(100); //83.28_NOP(); //0.14us**********************************************************************/void delayUs(uchar temp){while(temp--);}void delay_1ms(void){uint i;for (i=0;i<DELAY_MIN;i++);//DR();}void delay_nms(uint n){uint i;for (i=0;i<n;i++)delay_1ms();}/********************************************************************** functionName: uchar resetDS18B20(void)description :DS18B20初始化**********************************************************************/uchar resetDS18B20(void){uchar errTime=0;RLS_DS18B20; //释放总线_NOP();HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低delayUs(255); //209.42usdelayUs(255); //209.42usdelayUs(101); //83.28us//以上的三个延时大于480usRLS_DS18B20; //释放总线,总线自动上拉_NOP();while(STU_DS18B20){delayUs(4); //5.15userrTime++;if(errTime>25)return(0x01); //如果等带大于约5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)}errTime=0;while(!(STU_DS18B20)){delayUs(4); //5.15userrTime++;if(errTime>50)return(0x02); //如果等带大于约5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)}return(0xff); //返回显示}/********************************************************************** functionName: uchar readByteDS18B20(void)description :读DS18B20一个字节**********************************************************************/uchar readByteDS18B20(void){uchar i;uchar retVal=0;RLS_DS18B20; //释放总线for(i=8;i>0;i--){retVal>>=1;HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP(); //延时大于1usRLS_DS18B20; //释放总线,DS18B20会将总线强制拉低NOP();NOP();if(STU_DS18B20)////读取总线上的电平retVal|=0x80;delayUs(16); //14.92usdelayUs(16); //14.92usRLS_DS18B20; //释放总线delayUs(35); //30.38us}delayUs(1); //2.71us(大于1us就行了)return(retVal);}/********************************************************************** functionName: uchar readByteDS18B20(void)description :写DS18B20一个字节**********************************************************************/ void writeByteDS18B20(uchar wb){uchar i;uchar temp;RLS_DS18B20; //释放总线for(i=0;i<8;i++){HLD_DS18B20; //Maga16控制总线CLR_DS18B20; //强制拉低delayUs(16); //14.92ustemp=wb>>i;temp&=0x01;if(temp)RLS_DS18B20; //释放总线elseCLR_DS18B20; //强制拉低delayUs(16); //14.92usdelayUs(35); //30.38usRLS_DS18B20; //释放总线delayUs(1); //2.71us(大于1us就行了)}}/********************************************************************** functionName: unsigned int readTempDS18B20(void)description :读DS18B20温度**********************************************************************/ unsigned int readTempDS18B20(void){uchar tempL,tempH;uint x;resetDS18B20();writeByteDS18B20(0xcc); //跳过ROMwriteByteDS18B20(0x44); //启动温度转换delayUs(1);resetDS18B20();writeByteDS18B20(0xcc); //跳过ROMwriteByteDS18B20(0xbe); //读数据tempL=readByteDS18B20();delayUs(20);tempH=readByteDS18B20();delayUs(20);x=(tempH<<8)|tempL;return(x);}。

相关文档
最新文档