如何制作数字温度计
现在您对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子例程判断读数的正负,然后以摄氏度为单位,在液晶显示屏上正确显示读数。 摄氏度到华氏度的单位换算如下:
这样,我们就完成了一个非常昂贵的温度计的制作。 它有些什么用途呢? 这有一个好主意。 例如你在一家制药公司工作,需要在全国范围内运输药品,药品运输全程温度要保持恒定,否则药品会失效。 你可以用 Stamp 制作一台温度数据记录仪。 Jameco公司(部件号143811)和Parallax公司(部件号27960)都出售称为“RAM 封装模块”的元件。 它包含具备串行接口的低功耗8千字节(也可以选择32千字节)RAM芯片。 可以给你的Stamp配上该元件(或相似产品),编写代码,每分钟将读取的温度数值保存在随机存取存储器中。 然后,你可以将 Stamp随药品一起打包,在运输过程结束时取回Stamp。 RAM模块会包含整个运输过程的温度历史记录,通过记录你可以知道药品是否解冻过。
掌握微控制器的工作原理之后,你可以借助Stamp制作出大量类似这样的小巧实用的设备。 |