如图9-58所示, 由运算放大器进行电流→电压转换,使用内部反馈电阻。输出电压值VOUT和输入数字量D的关系:
VOUT = - VREF ×D/256
D = 0~255, VOUT = 0 ~ - VREF ×255/256
VREF = -5V, VOUT =0~5×(255/256)V
VREF = +5V, VOUT = 0 ~ -5×(255/256)V 如果实际应用系统中要求输出模拟电压为双极性,则需要用转换电路实现。如图9-59所示。
其中 R2=R3=2R1
VOUT= 2×VREF×D/256 -VREF= (2D/256-1)VREF
D = 0, VOUT= -VREF;
D = 128, VOUT= 0;
D = 255, VOUT= (2×255/256-1)×VREF= (254/255)VREF
即:输入数字为0~255时,输出电压在- VREF ~+ VREF之间变化。
1. 运算放大器
运算放大器有三个特点:
⑴开环放大倍数非常高,一般为几千,甚至可高达10万。在正常情况下,运算放大器所需要的输入电压非常小。
⑵输入阻抗非常大。运算放大器工作时,输入端相当于一个很小的电压加在一个很大的输入阻抗上,所需要的输入电流也极小。
⑶输出阻抗很小,所以,它的驱动能力非常大。
2.由电阻网络和运算放大器构成的D/A转换器
利用运算放大器各输入电流相加的原理,可以构成如图10.7所示的、由电阻网络和运算放大器组成的、最简单的4位D/A转换器。图中,V0是一个有足够精度的标准电源。运算放大器输入端的各支路对应待转换资料的D0,D1,…,Dn-1位。各输入支路中的开关由对应的数字元值控制,如果数字元为1,则对应的开关闭合;如果数字为0,则对应的开关断开。各输入支路中的电阻分别为R,2R,4R,…这些电阻称为权电阻。
假设,输入端有4条支路。4条支路的开关从全部断开到全部闭合,运算放大器可以得到16种不同的电流输入。这就是说,通过电阻网络,可以把0000B~1111B转换成大小不等的电流,从而可以在运算放大器的输出端得到相应大小不同的电压。如果数字0000B每次增1,一直变化到1111B,那么,在输出端就可得到一个0~V0电压幅度的阶梯波形。
3.采用T型电阻网络的D/A转换器
从图10.7可以看出,在D/A转换中采用独立的权电阻网络,对于一个8位二进制数的D/A转换器,就需要R,2R,4R,…,128R共8个不等的电阻,最大电阻阻值是最小电阻阻值的128倍,而且对这些电阻的精度要求比较高。如果这样的话,从工艺上实现起来是很困难的。所以,n个如此独立输入支路的方案是不实用的。
在DAC电路结构中,最简单而实用的是采用T型电阻网络来代替单一的权电阻网络,整个电阻网络只需要R和2R两种电阻。在集成电路中,由于所有的组件都做在同一芯片上,电阻的特性可以做得很相近,而且精度与误差问题也可以得到解决。
图10.8是采用T型电阻网络的4位D/A转换器。4位元待转换资料分别控制4条支路中开关的倒向。在每一条支路中,如果(资料为0)开头倒向左边,支路中的电阻就接到地;如果(资料为1)开关倒向右边,电阻就接到虚地。所以,不管开关倒向哪一边,都可以认为是接“地”。不过,只有开关倒向右边时,才能给运算放大器输入端提供电流。
T型电阻网络中,节点A的左边为两个2R的电阻并联,它们的等效电阻为R,节点B的左边也是两个2R的电阻并联,它们的等效电阻也是R,…,依次类推,最后在D点等效于一个数值为R的电阻接在参考电压VREF上。这样,就很容易算出,C点、B点、A点的电位分别为-VREF/2,-VREF/4,-VREF/8。
在清楚了电阻网络的特点和各节点的电压之后,再来分析一下各支路的电流值。开关S3,S2,S1,S0分别代表对应的1位二进制数。任一资料位Di=1,表示开关Si倒向右边;Di=0,表示开关Si倒向左边,接虚地,无电流。当右边第一条支路的开关S3倒向右边时,运算放大器得到的输入电流为-VREF/(2R),同理,开关S2,S1,S0倒向右边时,输入电流分别为-VREF/(4R),-VREF/(8R),-VREF/(16R)。
如果一个二进制数据为1111,运算放大器的输入电流
I=-VREF/(2R)-VREF/(4R)-VREF/(8R)-VREF/(16R)
=-VREF/(2R)(20+2-1+2-2+2-3)
=-VREF/(24R)(23+22+21+20)
相应的输出电压
V0=IR0=-VREFR0(24R)(23+22+21+20)
将资料推广到n位,输出模拟量与输入数字量之间关系的一般表达式为:
V0=-VREFR0/(2nR)(Dn-12n-1+Dn-2 2n-2+…+D121+D020) (Di=1或0)
上式表明,输出电压V0除了和待转换的二进制数成比例外,还和网络电阻R、运算放大器反馈电阻R0、标准参考电压VREF有关。
2. D/A转换器性能参数
在实现D/A转换时,主要涉及下面几个性能参数。
⑴分辨率。分辨率是指最小输出电压(对应于输入数字量最低位增1所引起的输出电压增量)和最大输出电压(对应于输入数字量所有有效位全为1时的输出电压)之比,
例如,4位DAC的分辨率为1/(16-1)=1/15=6.67%(分辨率也常用百分比来表示)。8位DAC的分辨率为1/255=0.39%。显然,位数越多,分辨率越高。
⑵转换精度。如果不考虑D/A转换的误差,DAC转换精度就是分辨率的大小,因此,要获得高精度的D/A转换结果,首先要选择有足够高分辨率的DAC。
D/A转换精度分为绝对和相对转换精度,一般是用误差大小表示。DAC的转换误差包括零点误差、漂移误差、增益误差、噪声和线性误差、微分线性误差等综合误差。
绝对转换精度是指满刻度数字量输入时,模拟量输出接近理论值的程度。它和标准电源的精度、权电阻的精度有关。相对转换精度指在满刻度已经校准的前提下,整个刻度范围内,对应任一模拟量的输出与它的理论值之差。它反映了DAC的线性度。通常,相对转换精度比绝对转换精度更有实用性。
相对转换精度一般用绝对转换精度相对于满量程输出的百分数来表示,有时也用最低位(LSB)的几分之几表示。例如,设VFS为满量程输出电压5V,n位DAC的相对转换精度为±0.1%,则最大误差为±0.1%VFS=±5mV;若相对转换精度为±1/2LSB,LSB=1/2n,则最大相对误差为±1/2n+1VFS。
⑶非线性误差。D/A转换器的非线性误差定义为实际转换特性曲线与理想特性曲线之间的最大偏差,并以该偏差相对于满量程的百分数度量。转换器电路设计一般要求非线性误差不大于±1/2LSB。
⑷转换速率/建立时间。转换速率实际是由建立时间来反映的。建立时间是指数字量为满刻度值(各位全为1)时,DAC的模拟输出电压达到某个规定值(比如,90%满量程或±1/2LSB满量程)时所需要的时间。
建立时间是D/A转换速率快慢的一个重要参数。很显然,建立时间越大,转换速率越低。不同型号DAC的建立时间一般从几个毫微秒到几个微秒不等。若输出形式是电流,DAC的建立时间是很短的;若输出形式是电压,DAC的建立时间主要是输出运算放大器所需要的响应时间。
10.3.3 DAC0832及接口电路
DAC0832是美国资料公司研制的8位双缓冲器D/A转换器。芯片内带有资料锁存器,可与数据总线直接相连。电路有极好的温度跟随性,使用了COMS电流开关和控制逻辑而获得低功耗、低输出的泄漏电流误差。芯片采用R-2RT型电阻网络,对参考电流进行分流完成D/A转换。转换结果以一组差动电流IOUT1和IOUT2输出。
1.DAC0832的内部结构
DAC0832中有两级锁存器,第一级锁存器称为输入寄存器,它的锁存信号为ILE;第二级锁存器称为DAC寄存器,它的锁存信号为传输控制信号 。因为有两级锁存器,DAC0832可以工作在双缓冲器方式,即在输出模拟信号的同时采集下一个数字量,这样能有效地提高转换速度。此外,两级锁存器还可以在多个D/A转换器同时工作时,利用第二级锁存信号来实现多个转换器同步输出。
ILE为高电平、WR1 和 CS为低电平时, LE1为高电平,输入寄存器的输出跟随输入而变化;此后,当WR1 由低变高时, LE1为低电平,资料被锁存到输入寄存器中,这时的输入寄存器的输出端不再跟随输入资料的变化而变化。对第二级锁存器来说, WR2和XFER 同时为低电平时, LE2为高电平,DAC寄存器的输出跟随其输入而变化;此后,当WR2 由低变高时, LE2变为低电平,将输入寄存器的资料锁存到DAC寄存器中。
2. DAC0832的引脚特性
DAC0832是20引脚的双列直插式芯片。各引脚的特性如下:
CS——片选信号,和允许锁存信号ILE组合来决定 是否起作用,低有效。
ILE——允许锁存信号,高有效。
WR1——写信号1,作为第一级锁存信号,将输入资料锁存到输入寄存器(此时, 必须和 、ILE同时有效),低有效。
WR2——写信号2,将锁存在输入寄存器中的资料送到DAC寄存器中进行锁存(此时,传输控制信号 必须有效)低有效。
XFER——传输控制信号,低有效。
DI7~DI0——8位数据输入端。
IOUT1——模拟电流输出端1。当DAC寄存器中全为1时,输出电流最大,当DAC寄存器中全为0时,输出电流为0。
IOUT2——模拟电流输出端2。IOUT1+IOUT2=常数。
Rfb——反馈电阻引出端。DAC0832内部已经有反馈电阻,所以,RFB端可以直接接到外部运算放大器的输出端。相当于将反馈电阻接在运算放大器的输入端和输出端之间。
VREF——参考电压输入端。可接电压范围为±10V。外部标准电压通过VREF与T型电阻网络相连。
VCC——芯片供电电压端。范围为+5V~+15V,最佳工作状态是+15V。
AGND——模拟地,即模拟电路接地端。
DGND——数字地,即数字电路接地端。
3.DAC0832的工作方式
DAC0832进行D/A转换,可以采用两种方法对数据进行锁存。
第一种方法是使输入寄存器工作在锁存状态,而DAC寄存器工作在直通状态。具体地说,就是使 和 都为低电平,DAC寄存器的锁存选通端得不到有效电平而直通;此外,使输入寄存器的控制信号ILE处于高电平、 处于低电平,这样,当 端来一个负脉冲时,就可以完成1次转换。
第二种方法是使输入寄存器工作在直通状态,而DAC寄存器工作在锁存状态。就是使 和 为低电平,ILE为高电平,这样,输入寄存器的锁存选通信号处于无效状态而直通;当WR2 和XFER 端输入1个负脉冲时,使得DAC寄存器工作在锁存状态,提供锁存数据进行转换。
根据上述对DAC0832的输入寄存器和DAC寄存器不同的控制方法,DAC0832有如下3种工作方式:
⑴单缓冲方式。单缓冲方式是控制输入寄存器和DAC寄存器同时接收资料,或者只用输入寄存器而把DAC寄存器接成直通方式。此方式适用只有一路模拟量输出或几路模拟量异步输出的情形。
⑵双缓冲方式。双缓冲方式是先使输入寄存器接收资料,再控制输入寄存器的输出资料到DAC寄存器,即分两次锁存输入资料。此方式适用于多个D/A转换同步输出的情节。
⑶直通方式。直通方式是资料不经两级锁存器锁存,即 CS*,XFER* ,WR1* ,WR2* 均接地,ILE接高电平。此方式适用于连续反馈控制线路和不带微机的控制系统,不过在使用时,必须通过另加I/O接口与CPU连接,以匹配CPU与D/A转换。
4. DAC0832的应用举例
⑴DAC0832实现一次D/A转换,可以采用下面程序段。设定要转换的数据放在1000H单元中。
MOV BX,100H
MOV AL,[BX] 取转换资料
OUT DX,AL
⑵在实际应用中,经常需要用到一个线性增长的电压去控制某一个检测过程,或者作为扫描电压去控制一个电子束的移动。执行下面的程序段,利用D/A转换器产生一个锯齿波电压,实现此类控制作用。
MOV DX,PORTA PORTA为D/A转换器端口地址
MOV AL,OFFH 置初值
ROTAT:INC AL
OUT DX,AL 往D/A转换器输出资料
CALL DELP 调用延迟子程序
JMP ROTAT
DELY: MOV CX, DATA 置延迟常数DATA
DELY1: LOOP DELY1
RET
如果需要一个负向的锯齿波,只要将指令INC AL改成DEC AL就可以了。
⑶从两个不相关的文件中输出一批X-Y资料,驱动X-Y记录仪,或者控制加工复杂零件的走刀(X轴)和进刀(Y轴)。这些在控制过程中是很有用的。下面程序驱动X-Y记录仪的100点输出,并用软件驱动记录仪的抬笔和放笔控制。
MOV SI, XDATA X轴资料指针→SI
MOV DI, YDATA Y轴资料指针→DI
MOV CX, 100
WE0: MOV AL,[SI]
OUT PORTX, AL 往X轴的D/A转换器输出资料
MOV AL,[DI]
OUT PORTY,AL往Y轴的D/A转换器输出资料
CALL DELY1 调延迟子程序1,等待笔移动
MOV AL,01H
OUT PORTM,AL输出升脉冲,控制笔放下
CALL DELY2 调延迟子程序2,等待完成
MOV AL,00H
OUT PORTM,AL输出降脉冲,控制笔抬起
CALL DELY2 调延迟子程序2,等待完成
INC SI
INC DI
LOOP WE0
HLT
DELY1:┇
RET
DELY2:┇
RET
XDATA DB…
YDATA DB…
(4).利用C语言编程:
#pragma db oe sb
#i nclude<reg51.h>
#i nclude<absacc.h>
#define DAC0832 XBYTE[0x7fff] /* 定义DAC0832端口地址 */
#define uchar unsigned char
void delay(uchar t) { /* 延时函数 */
while(t--)
}
void saw(void) { /* 锯齿波发生函数 */
uchar i
for (i=0i<255i++) {
DAC0832=i
}
}
void square(void) { /* 方波发生函数 */
DAC0832=0x00
delay(0x10)
DAC0832=0xff
delay(0x10)
}
void main(void) {
uchar i,j
i=j=0xff
while(i--) {
saw()/* 产生一段锯齿波 */
}
while(j--) {
square()/* 产生一段方波 */
}
}
DS18B20一线总线数字式传感器的原理与使用________________________________________
DS18B20、 DS1822 “一线总线”数字化温度传感器是DALLAS最新单线数字温度传感器, 同DS1820一样,DS18B20也 支持“一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为± 2°C 。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。而且新一代产品更便宜,体积更小。
DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS18B20的性能是新一代产品中最好的!性能价格比也非常出色! DS1822与 DS18B20软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。 继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。
DS18B20的内部结构
DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列如下:
15元/只
DQ为数字信号输入/输出端;GND为电源地;VDD为外接供电电源输入端(在寄生电源接线方式时接地)。
光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。
这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H。
DS18B20温度传感器的存储器
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的E2RAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。
暂存存储器包含了8个连续字节,前两个字节是测得的温度信息,第一个字节的内容是温度的低八位,第二个字节是温度的高八位。第三个和第四个字节是TH、TL的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。第六、七、八个字节用于内部计算。第九个字节是冗余检验字节。
该字节各位的意义如下:
TM R1 R0 1 1 1 1 1
低五位一直都是1 ,TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用户不要去改动。R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)
分辨率设置表:
R1 R0 分辨率 温度最大转换时间
0 0 9位 93.75ms
0 1 10位 187.5ms
1 0 11位 375ms
1 1 12位 750ms
根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
DS1820使用中注意事项
DS1820虽然具有测温系统简单、测温精度高、连接方便、占用口线少等优点,但在实际应用中也应注意以下几方面的问题:
(1)较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理器间采用串行数据传送,因此,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。在使用PL/M、C等高级语言进行系统程序设计时,对DS1820操作部分最好采用汇编语言实现。
(2)在DS1820的有关资料中均未提及单总线上所挂DS1820数量问题,容易使人误认为可以挂任意多个DS1820,在实际应用中并非如此。当单总线上所挂DS1820超过8个时,就需要解决微处理器的总线驱动问题,这一点在进行多点测温系统设计时要加以注意。
(3)连接DS1820的总线电缆是有长度限制的。试验中,当采用普通信号电缆传输长度超过50m时,读取的测温数据将发生错误。当将总线电缆改为双绞线带屏蔽电缆时,正常通讯距离可达150m,当采用每米绞合次数更多的双绞线带屏蔽电缆时,正常通讯距离进一步加长。这种情况主要是由总线分布电容使信号波形产生畸变造成的。因此,在用DS1820进行长距离测温系统设计时要充分考虑总线分布电容和阻抗匹配问题。
(4)在DS1820测温程序设计中,向DS1820发出温度转换命令后,程序总要等待DS1820的返回信号,一旦某个DS1820接触不好或断线,当程序读该DS1820时,将没有返回信号,程序进入死循环。这一点在进行DS1820硬件连接和软件设计时也要给予一定的重视。
测温电缆线建议采用屏蔽4芯双绞线,其中一对线接地线与信号线,另一组接VCC和地线,屏蔽层在源端单点接地。
本站实验板实验程序:
这是关于DS18B20的读写程序,数据脚P2.2,晶振12MHZ
温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒
可以将检测到的温度直接显示到AT89C51开发实验板的两个数码管上
显示温度00到99度,很准确哦~~无需校正!
ORG 0000H
单片机内存分配申明!
TEMPER_L EQU 29H用于保存读出温度的低8位
TEMPER_H EQU 28H用于保存读出温度的高8位
FLAG1 EQU 38H是否检测到DS18B20标志位
a_bit equ 20h 数码管个位数存放内存位置
b_bit equ 21h 数码管十位数存放内存位置
MAIN:
LCALL GET_TEMPER调用读温度子程序
进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度
显示范围00到99度,显示精度为1度
因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
MOV A,29H
MOV C,40H将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
LCALL DISPLAY调用数码管显示子程序
CPL P1.0
AJMP MAIN
这是DS18B20复位初始化子程序
INIT_1820:
SETB P3.5
NOP
CLR P3.5
主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P3.5然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P3.5,TSR3等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 延时
TSR3:
SETB FLAG1 置标志位,表示DS1820存在
CLR P1.7检查到DS18B20就点亮P1.7LED
LJMP TSR5
TSR4:
CLR FLAG1 清标志位,表示DS1820不存在
CLR P1.1点亮P1。1脚LED表示温度传感器通信失败
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 时序要求延时一段时间
TSR7:
SETB P3.5
RET
读出转换后的温度值
GET_TEMPER:
SETB P3.5
LCALL INIT_1820先复位DS18B20
JB FLAG1,TSS2
CLR P1.2
RET 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
CLR P1.3DS18B20已经被检测到!!!!!!!!!!!!!!!!!!
MOV A,#0CCH 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H 发出温度转换命令
LCALL WRITE_1820
这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL DISPLAY
LCALL INIT_1820准备读温度前先复位
MOV A,#0CCH 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200将读出的温度数据保存到35H/36H
CLR P1.4
RET
写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8一共8位数据
CLR C
WR1:
CLR P3.5
MOV R3,#6
DJNZ R3,$
RRC A
MOV P3.5,C
MOV R3,#23
DJNZ R3,$
SETB P3.5
NOP
DJNZ R2,WR1
SETB P3.5
RET
读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 将温度高位和低位从DS18B20中读出
MOV R1,#29H 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8数据一共有8位
RE01:
CLR C
SETB P3.5
NOP
NOP
CLR P3.5
NOP
NOP
NOP
SETB P3.5
MOV R3,#9
RE10:
DJNZ R3,RE10
MOV C,P3.5
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
显示子程序
display: mov a,29H将29H中的十六进制数转换成10进制
mov b,#10 10进制/10=10进制
div ab
mov b_bit,a 十位在a
mov a_bit,b 个位在b
mov dptr,#numtab 指定查表启始地址
mov r0,#4
dpl1: mov r1,#250 显示1000次
dplop: mov a,a_bit 取个位数
MOVC A,@A+DPTR 查个位数的7段代码
mov p0,a 送出个位的7段代码
clr p2.0 开个位显示
acall d1ms 显示1ms
setb p2.0
mov a,b_bit 取十位数
MOVC A,@A+DPTR 查十位数的7段代码
mov p0,a 送出十位的7段代码
clr p2.1 开十位显示
acall d1ms 显示1ms
setb p2.1
djnz r1,dplop 100次没完循环
djnz r0,dpl1 4个100次没完循环
ret
1MS延时(按12MHZ算)
D1MS: MOV R7,#80
DJNZ R7,$
RET
实验板上的7段数码管0~9数字的共阴显示代码
numtab: DB 0F3H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
end
以下是第二种采集和处理程序供网友参考
温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒
将温度数据通过串口发送出去,波特率2400
本程序专为AT89C51实验开发板编写.适合12晶振
本程序经过验证,可以显示温度+/-和两位整数温度和两位小数温度数据
DOT EQU 30H
ZHENGSHU EQU 31H
FLAG1 EQU 38H 是否检测到DS18B20的标志位
定义温度数据
DIS_1 EQU 32H 符号
DIS_2 EQU 33H 十位
DIS_3 EQU 34H 个位
DIS_4 EQU 35H 小数点后第一位
DIS_5 EQU 36H 小数点后第二位
WDDATA BIT P2.2 定义DS18B20的数据脚为P2.2端口
ORG 0000H
以下为主程序进行CPU中断方式设置
CLR EA 关闭总中断
MOV SCON,#50H 设置成串口1方式
MOV TMOD,#20H 波特率发生器T1工作在模式2上
MOV TH1,#0F3H 预置初值(按照波特率2400BPS预置初值)
MOV TL1,#0F3H 预置初值(按照波特率2400BPS预置初值)
SETB TR1 启动定时器T1
以上完成串口2400通讯初始化设置
-------------------------
主程序
-------------------------
MAIN:
LCALL INIT_1820 调用复位DS18B20子程序
MAIN1:
LCALL GET_TEMPER调用读温度子程序
LCALL FORMULA 通过公式计算,小数点后显示两位
LCALL BCD
LCALL DISPLAY 调用串口显示子程序
LCALL DELAY500 延时0.5秒
LCALL DELAY500 延时0.5秒
LCALL DELAY500 延时0.5秒
AJMP MAIN1
-------------------------
DS18B20复位初始化程序
-------------------------
INIT_1820:
SETB WDDATA
NOP
CLR WDDATA
主机发出延时540微秒的复位低脉冲
MOV R0,#36
LCALL DELAY
SETB WDDATA然后拉高数据线
NOP
NOP
MOV R0,#36
TSR2:
JNB WDDATA,TSR3等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 延时
TSR3:
SETB FLAG1 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#06BH
TSR6:
DJNZ R0,TSR6 复位成功!时序要求延时一段时间
TSR7:
SETB WDDATA
RET
-------------------
读出转换后的温度值
-------------------
GET_TEMPER:
SETB WDDATA 定时入口
LCALL INIT_1820 先复位DS18B20
JB FLAG1,TSS2
RET 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H 发出温度转换命令
LCALL WRITE_1820
MOV R0,#50 等待AD转换结束,12位的话750微秒.
LCALL DELAY
LCALL INIT_1820 准备读温度前先复位
MOV A,#0CCH 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200将读出的九个字节数据保存到60H-68H
RET
----------------------------------
写DS18B20的子程序(有具体的时序要求)
----------------------------------
WRITE_1820:
MOV R2,#8 一共8位数据
CLR C
WR1:
CLR WDDATA
MOV R3,#6
DJNZ R3,$
RRC A
MOV WDDATA,C
MOV R3,#24
DJNZ R3,$
SETB WDDATA
NOP
DJNZ R2,WR1
SETB WDDATA
RET
--------------------------------------------------
读DS18B20的程序,从DS18B20中读出九个字节的数据
--------------------------------------------------
READ_18200:
MOV R4,#9
MOV R1,#60H 存入60H开始的九个单元
RE00:
MOV R2,#8
RE01:
CLR C
SETB WDDATA
NOP
NOP
CLR WDDATA
NOP
NOP
NOP
SETB WDDATA
MOV R3,#09
RE10:
DJNZ R3,RE10
MOV C,WDDATA
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
------------------------
温度计算子程序
------------------------
FORMULA: 按公式:T实际=(T整数-0.25)+( M每度-M剩余)/ M每度
计算出实际温度,整数部分和小数部分分别存于ZHENGSHU单元和DOT单元
将61H中的低4位移入60H中的高4位,得到温度的整数部分,并存于ZHENGSHU单元
MOV 29H,61H
MOV A,60H
MOV C,48H
RRC A
MOV C,49H
RRC A
MOV C,4AH
RRC A
MOV C,4BH
RRC A
MOV ZHENGSHU,A
( M每度-M剩余)/ M每度,小数值存于A中
MOV A,67h
SUBB A,66h
MOV B,#64H
MUL AB
MOV R4,B
MOV R5,A
MOV R7,67H
LCALL DIV457
MOV A,R3
再减去0.25,实际应用中减去25
SUBB A,#19H
MOV DOT,A 小数部分存于DOT中
MOV A,ZHENGSHU
SUBB A,#00H 整数部分减去来自小数部分的借位
MOV ZHENGSHU,A
MOV C,4BH
JNC ZHENG 是否为负数
CPL A
INC A
MOV DIS_1,#2DH 零度以下时,第一位显示"-"号
MOV ZHENGSHU,A
ZHENG:
MOV DIS_1,#2BH 零度以上时,第一位显示"+"号
RET
------------------------
双字节除以单字节子程序
------------------------
DIV457: CLR C
MOV A,R4
SUBB A,R7
JC DV50
SETB OV 商溢出
RET
DV50: MOV R6,#8 求平均值(R4R5/R7-→R3)
DV51: MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV F0,C
CLR C
SUBB A,R7
ANL C,/F0
JC DV52
MOV R4,A
DV52: CPL C
MOV A,R3
RLC A
MOV R3,A
DJNZ R6,DV51
MOV A,R4 四舍五入
ADD A,R4
JC DV53
SUBB A,R7
JC DV54
DV53: INC R3
DV54: CLR OV
RET
---------------------
转换成非压缩的BCD码
---------------------
BCD: MOV A,ZHENGSHU
MOV B,#0AH
DIV AB
ORL A,#00110000B 转换成ASCII码
MOV DIS_2,A
MOV DIS_3,B
MOV A,DIS_3
ORL A,#00110000B 转换成ASCII码
mov DIS_3,A
MOV A,DOT
MOV B,#0AH
DIV AB
ORL A,#00110000B 转换成ASCII码
MOV DIS_4,A
MOV DIS_5,B
MOV A,DIS_5
ORL A,#00110000B 转换成ASCII码
mov DIS_5,A
RET
----------------------
串口显示数据子程序
----------------------
DISPLAY:
CLR TI
MOV A,DIS_1
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示+/-
CLR TI
MOV A,DIS_2
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示整数第一位
CLR TI
MOV A,DIS_3
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示整数第二位
CLR TI
MOV A,#2EH
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示小数点
CLR TI
MOV A,DIS_4
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示小数第一位
CLR TI
MOV A,DIS_5
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示小数第一位
CLR TI
MOV A,#0DH换行
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示
CLR TI
MOV A,#0AH换行
MOV SBUF,A
JNB TI,$ 发送给PC,通过串口调试助手显示
RET
----------------------
延时子程序
----------------------
为保证DS18B20的严格I/O时序,需要做较精确的延时
在DS18B20操作中,用到的延时有15 μs,90 μs,270 μs,540 μs
因这些延时均为15 μs的整数倍,因此可编写一个DELAY15(n)函数
DELAY: 11.05962M晶振
LOOP: MOV R1,#06H
LOOP1: DJNZ R1,LOOP1
DJNZ R0,LOOP
RET
500毫秒延时子程序,占用R4、R5
DELAY500:MOV R4,#248
DA222:MOV R5,#248
DJNZ R5,$
DJNZ R4,DA222
RET
END
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)