恒温箱温度计算机控制系统
一、 设备介绍
本次设计的温度传感器采用DS18B20温度传感器;单片机则采用的是AVR系列的Atmega8。下面分别简单介绍他们的特点:
DS18B20是美国DALLAS公司推出的一款单线数字温度传感器。它具有:体积小,功耗低,精度高,可靠性好,易于单片机接口等优点,每片DS18B20都有唯一的一个可读出的序列号。DS18B20传感器共有三个引脚,分别为电源引脚、数据引脚和接地引脚。由于DS18B20是一款单线式的数字温度传感器,只有一个引脚为数据的输入输出引脚。所以,根据DS18B20的通信协议,主机控制DS18B20完成一次温度转换必须经过3个步骤: 一)、每次读写之前都要对DS18B20进行复位操作 二)、复位成功后发送一条ROM指令
三)、最后发送RAM指令,这样才能够对DS18B20进行正确的操作。
复位:复位要求主机将数据线拉低最少480us,然后释放,当DS18B20受到信号后,等待15-60us,然后把总线拉低60-240us,主机接收到此信号表示复位成功。ROM指令:ROM指令表明了主机寻址一个或多个DS18B20中的某个或某几个,或者是读取某个DS18B20的64位序列号。RAM指令:RAM指令用于主机对DS18B20内部RAM的操作(如启动温度转换、读取温度等)。
DS18B20的特点主要包括:
(1)DSl8B20采用DALLAS公司独特的“单线(1-Wire)总线”专有技术,通过串行通信接口(I/O)直接输出被测温度值(9位二进制数据,含符号位)。
(2)在测温范围是-55~+125℃时,测量误差不超过±2℃,在-10~+85℃范围内,可确保测量误差不超过±0.5℃。温度/数字量转换时间的典型值仅需93.75ms,比DS1820有很大的提高.
(3)内含64位经过激光修正的只读存储器ROM,扣除8位产品系列号和8位循环冗余校验码CRC之后,产品序号占48位。出厂前就作为DSl8B20惟一的产品序号,存入其ROM中。在构成大型温控系统时,允许在单线总线上挂接多片DSl8B20。
ATmega8 是ATMEL公司在2002年第一季度推出的一款新型AVR高档单片机。它的芯片内部集成了较大 容量的存储器和丰富强大的硬件接口电路。ATmega系列单片机属于AVR中的高档产品,它承袭了AT90所具有的特点,并在AT90(如 AT9058515、AT9058535)的基础上,增加了更多的接口功能,而且在省电性能。稳定性、抗干扰性以及灵活性方面考虑得更加周全和完善。 ATmega8 是一款采用低功耗CMOS工艺生产的基于AVR RISC结构的8位单片机。AVR单片机的核心是将32个工作寄存器和丰富的指令集联结在一起,所有的工作寄存器都与ALU(算术逻辑单元)直接相连,实 现了在一个时钟周期内执行的一条指令同时访问(读写)两
1
个独立寄存器的操作。这种结构提高了代码效率,使得大部分指令的执行时间仅为一个时钟周期。因此, ATmega8可以达到接近1MIPS/MHz的性能,运行速度比普通CISC单片机高出10倍。
ATmega8的主要性能包括:低功耗的8位AVR微控制器,先进的RISC精简指令集结构130条功能强大的指令,大多数为单时钟周期指令,32个8位通用工作寄存器工作在16MHz时,具有16MIPS的性能片内集成硬件乘法器(执行速度为2个时钟周期),片内集成了较大容量的非易失性程序和数据存储器以及工作存储器,8K字节的Flash程序存储器,擦写次数:大于10000次等。
二、 详细设计步骤
首先是编写DS18B20的驱动程序,由于DS18B20采用的是单线式的设计,所以要成功读取其中的温度值,就必须遵循其中的通信协议。读取温度的过程如图1所示:
初始化传感器 跳过读序号列号 高位左移8位 跳过读序号列号 读取温度寄存器 (前两个寄存器值为温度) 高位与低位相或 组合成温度值 启动温度转换 读取低位 初始化传感器 读取高位
图1 温度传感器读写过程
返回检测温度值 每次对DS18B20进行读写操作时都必须对其进行复位操作,其复位程序如下:
#define CLR_DIR_1WIRE DDRD&=~(1<<0) #define SET_DIR_1WIRE DDRD|=(1<<0) #define CLR_OP_1WIRE PORTD&=~(1<<0) #define SET_OP_1WIRE PORTD|=(1<<0)
#define CHECK_IP_1WIRE (PIND & 0x01) //检测 unsigned char wmh,wml,w5; void init_1820() {
SET_DIR_1WIRE; //设置PC2 为输出 SET_OP_1WIRE; CLR_OP_1WIRE;
delay_nus(480); //480us以上 SET_OP_1WIRE;
2
CLR_DIR_1WIRE;
delay_nus(20); //15~60us while(CHECK_IP_1WIRE); SET_DIR_1WIRE; SET_OP_1WIRE;
delay_nus(140); //60~240us }
按照DS18B20说明文档,通过不断的拉低或提高数据引脚的电压即可实现对DS18B20的初始化。值得注意的是,DS18B20对引脚电压拉低或抬高的时间比较的敏感。对于不同的晶振,延时程序应有相应的变化。接下来的程序unsigned char read_1820() write_1820(unsigned char x) 实现的是对DS18B20的读写操作:
void write_1820(unsigned char x) {
unsigned char m; for(m=0;m<8;m++) {
CLR_OP_1WIRE;
if(x&(1< {CLR_OP_1WIRE;} delay_nus(40); //15~60us SET_OP_1WIRE; } SET_OP_1WIRE; } unsigned char read_1820() { unsigned char temp,k,n; temp=0; for(n=0;n<8;n++) { CLR_OP_1WIRE; SET_OP_1WIRE; CLR_DIR_1WIRE; k=(CHECK_IP_1WIRE); //读数据,从低位开始 if(k) temp|=(1< temp&=~(1< delay_nus(50); //60~120us SET_DIR_1WIRE; } return (temp); 3 和void } 完成了读写操作的程序后就可以按照图1所示的工作流程对DS18B20温度的读写。完整的调用初始化及读写的程序如下: void gettemp() //读取温度值 { unsigned char temh,teml,wm0,wm1,wm2,wm3,w4; init_1820(); //复位18b20 write_1820(0xcc); // 发出转换命令 write_1820(0x44); init_1820(); write_1820(0xcc); //发出读命令 write_1820(0xbe); teml=read_1820(); //读数据 temh=read_1820(); wm0=teml>>4; //只要高8位的低四位和低8位的高四位 wm1=temh<<4; wm2=wm1+wm0; //16进制转10进制 wm3=wm2/100; wmh=(wm20)/10; // wmh是显示的高位,wml使显示的低位 wml=(wm20); w4=teml<<4; w5=w4*0.0625; } 完成了对DS18B20的读写后,需要将我们所得到的温度值显示到单片机开发板的数码管上。主函数的流程图如下所示: 开始 对系统进行初始化 读取传感器温度值 显示温度的整数位 显示温度的小数位 图2 主程序流程图 4 由图2编写主函数的程序,在编写时每次读取DS18B20后都要求对传感器进行一次复位操作,在前面的DS18B20已有体现,编写显示程序时,要特别注意开发板上的数码管是共阴还是共阳的,这样才能准确显示数据。主函数只需要调用温度传感器驱动和显示程序即可。主函数及显示程序如下: #include PORTB = 0x00;//将单片机的B端口值0 DDRB = 0x00;//方向寄存器定义为0,表示为输入 PORTC = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; } void init_devices(void) { CLI(); //关中断 port_init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x00; SEI();//开中断 } void delay_us(int time) { do { time--; } while (time > 1); } 显示程序如下所示: const unsigned char num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void show_2_digit(unsigned char digi) { 5