现在您对Stamp和液晶显示屏有了初步的了解,我们再加一个元件就可以制作一支数字温度计。 制作数字温度计需要用到芯片DS1620。 该芯片包含:
一个温度传感器
一个用于温度感应设备的模拟数字转换器
一个用于从模数转换器读取数据的移位寄存器
一个用于保存设置的小型电可擦除只读存储器
DS1620有两种工作模式: 一种作为独立的恒温芯片;另一种则是与计算机相连作温度计使用。 电可擦除只读存储器用来保存当前的工作模式和恒温模式设定值。
DS1620与Stamp的连接十分简单。 该芯片有8根引脚。从Stamp引出的5伏以上电源接入DS1620的8号引脚; 电源地线接DS1620的4号引脚。3根Stamp输入输出引脚驱动DS1620的以下三根引脚:
1 号引脚为数据线。 通过该引脚读写数据。
2 号引脚为时钟引脚。 为移位寄存器移入移出数据提供时钟。
3 号引脚为复位、片选信号。 该引脚置高电平,选通芯片。
例程代码中,假设:
数据线连接Stamp的2号输入输出引脚。
时钟引脚连接Stamp的1号输入输出引脚。
复位、片选信号由Stamp的0号输入输出引脚提供。
完整连线如下图所示:
DS1620可以从Jameco公司(部件号146456)或Parallax公司(部件号27917)的“应用工具包”中获得,这一工具包包括芯片、电容器、一些有用的文档和示例代码。 或者,你也可以从Jameco公司单独购买该芯片(部件号114382)。如果你是第一次使用此芯片,还是建议你购买“应用工具包”,里面的文档会非常有用。
你可以将DS1620芯片安装在Stamp的母板的实验建模区,也可以装在单独的面包板上。安装完毕,将液晶显示屏与Stamp的3号输入输出引脚相连,载入并运行下面的程序:
symbol RST = 0 ' 定义复位、选通1620芯片引脚编号
symbol CLK = 1 ' 定义连接1620芯片移位寄存器的时钟引脚编号
symbol DQ = 2 ' 定义连接1620芯片数据线的引脚编号
symbol DQ_PIN = pin2 ' 定义2号引脚为数据线
symbol LCD = 3 ' 定义液晶显示屏数据线引脚编号
begin:
low RST ' 不用时,不选通1620芯片
high CLK ' 1620芯片时钟引脚默认为高电平
pause 1000 ' 等待温度计与显示屏的引导启动
setup:
high RST ' 选通1620芯片
b0 = $0C ' $0c 是1620的命令字节
' 意思是“写入设定”
gosub shift_out ' 发送至1620芯片
b0 = %10 ' %10 是1620的命令字节
' 设定温度计工作模式
gosub shift_out ' 发送至1620芯片
low RST ' 不选通1620芯片
pause 50 ' 延时50毫秒,等待电可擦除只读存储器
start_convert:
b0 = $EE ' $EE 是1620的命令字节
' 启动模数转换
high RST ' 选通1620芯片
gosub shift_out ' 发送至1620芯片
low RST ' 不选通1620芯片
' 以下为主循环程序
' -- 每秒读取并显示温度
main_loop:
high RST ' 选通1620芯片
b0 = $AA ' $AA 为1620命令字节
' 温度信号采样
gosub shift_out ' 发送至1620芯片
gosub shift_in ' 从1620读取
' 温度数值
low RST ' 不选通DS1620。
gosub display ' 用摄氏度单位显示温度
pause 1000 ' 等待一秒
goto main_loop
' shift_out 子程序将b0字节中的内容
' 发送至 1620 芯片
shift_out:
output DQ ' 设置数据线为
' 输出模式
for b2 = 1 to 8
low CLK ' 准备1620发送数据所需的时钟
DQ_PIN = bit0 ' 发送数据位
high CLK ' 数据位送至1620
b0 = b0/2 ' 将所有位
' 朝bit0右移
next
return
' shift_in 子例程从 1620 中
' 得到 9 位的温度读数
shift_in:
input DQ ' 设置数据线设置为
' 输入模式
w0 = 0 ' 变量w0清零
for b5 = 1 to 9
w0 = w0/2 ' 输入数据右移。
low CLK ' 向1620请求下一位
bit8 = DQ_PIN ' 读取位
high CLK ' 时钟信号引脚切换为高电平
next
return
' 以摄氏度单位显示温度
display:
if bit8 = 0 then pos ' 如果bit8=1
' 温度为负值
b0 = b0 and/ b0 ' 通过对自身的与非操作
' 对b0取反
b0 = b0 + 1
pos:
serout LCD, n2400, (254, 1) ' 清除液晶显示屏
serout LCD, n2400, ("Temp = ") ' 在显示屏上
' 显示“Temp=”
bit9 = bit0 ' 保存0.5度
b0 = b0 / 2 ' 换算成度数
if bit8 = 1 then neg ' 判断温度是否为负值
serout LCD, n2400, (#b0) ' 显示正温度
goto half
neg:
serout LCD, n2400, ("-", #b0)' 显示负温度
half:
if bit9 = 0 then even
serout LCD, n2400, (".5 C") ' 显示 .5度
goto done
even:
serout LCD, n2400, (".0 C") ' 显示 .0度
done:
return
运行这个程序,你会发现这一温度计是以0.5度的精度,以摄氏度为单位显示温度。
DS1620芯片测量温度的精度为0.5摄氏度。这个芯片用9位2-补码二进制数表示华氏-110至250度(摄氏-55至125度)范围内的温度。把接收到的数值除以2就是实际温度的数值。2-补码是一种表示负值的便捷方法。下面列出了4位2-补码四位二进制数据所代表的数值:
0111 : 7
0110 : 6
0101 : 5
0100 : 4
0011 : 3
0010 : 2
0001 : 1
0000 : 0
1111 : -1
1110 : -2
1101 : -3
1100 : -4
1011 : -5
1010 : -6
1001 : -7
1000 : -8
通常用四位二进制数表示0到15的数值,而四位2-补码二进制数表示-8到7。最左边一位决定了数值的正负。如果数值为负,我们可以通过把其他各位取反加1的方法,得到其绝对值。
以下是上述数字温度计程序执行的操作:
使用symbol关键字设置若干常量,使程序更易于阅读(也更容易把芯片与其他不同的输入输出引脚相连)。
设定DS1620芯片的时钟和复位引脚信号为预期值。
通过向DS1620的电可擦除只读存储器写入命令字节,使其工作在“温度计模式”。你只需要进行一次这样的操作,严格地说你在运行过一次程序之后,就可以把这段代码删掉了(出于节省程序存储空间考虑),因为这种工作模式已经保存在电可擦除只读存储器中。
程序发送指令$EE(“$”表示十六进制数,$EE转换成十进制为238),启动温度计的模数转换。
之后,程序进入循环。 每秒向DS1620芯片发出指令获取目前温度信号,读取 DS1620返回的9位的数据,将其保存在变量w0中。Stamp通过切换时钟信号一次发送或接收一位数据信号,与DS1620通信。变量w0(16位)与b0/b1(8位)与 bit0/bit1/.../bit15(1位)占有相同的存储空间,当我们从bit8开始插入从DS1620 获取的位数据,并将w0变量除以2时,实际上我们就是在将数据右移,以便把从 DS1620获取的9位温度信号保存在变量w0中。 温度保存在w0中之后,display子例程判断读数的正负,然后以摄氏度为单位,在液晶显示屏上正确显示读数。 摄氏度到华氏度的单位换算如下:
dF=dC*9/5+32
这样,我们就完成了一个非常昂贵的温度计的制作。 它有些什么用途呢? 这有一个好主意。 例如你在一家制药公司工作,需要在全国范围内运输药品,药品运输全程温度要保持恒定,否则药品会失效。 你可以用 Stamp 制作一台温度数据记录仪。 Jameco公司(部件号143811)和Parallax公司(部件号27960)都出售称为“RAM 封装模块”的元件。 它包含具备串行接口的低功耗8千字节(也可以选择32千字节)RAM芯片。 可以给你的Stamp配上该元件(或相似产品),编写代码,每分钟将读取的温度数值保存在随机存取存储器中。 然后,你可以将 Stamp随药品一起打包,在运输过程结束时取回Stamp。 RAM模块会包含整个运输过程的温度历史记录,通过记录你可以知道药品是否解冻过。
掌握微控制器的工作原理之后,你可以借助Stamp制作出大量类似这样的小巧实用的设备。