嵌入式实验报告

嵌入式系统设计报告

设计课题:水压水温的检测

专业:11级通信工程

学号:1103609084

姓名:高世通

指导老师:张彦波

一、设计背景

热水供暖系统需要时刻对热水进行水温和水压的实时监控,才能保证供暖的有效性和稳定性。这就需要有一个可靠地水温、水压数据采集的监控系统来实现这样的需求。

二、系统功能的流程图:


如图所示:

三、系统的硬件设计

1、单片机AT89C51

单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。设计用到的AT89C51是一种带4K字节FLASH存储器的低电压、高性能CMOS 8位微处理器,其主要特性有:128×8位内部RAM、32可编程I/O线、两个16位定时器/计数器、5个中断源、可编程串行通道、低功耗的闲置和掉电模
式、片内振荡器和时钟电路。

图1 51单片机引脚接线图

本设计用到定时器/计数器的功能,在时间计数设置时,用定时器/计数器0的计数功能,外部以脉冲形式输入作为计数器的计数脉冲,这里外部脉冲间隔约为1s,计数实现时间计数功能。

2、数字温度传感器ds18b20

数字温度传感器就是能把温度物理量,通过温度敏感元件和相应电路转换成方便计算机、plc、智能仪表等数据采集设备直接读取得数字量的传感器。设计用到的ds18b20数字温度传感器耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

其主要性能描述:

1.独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯;

2.测温范围 -55℃~+125℃,固有测温分辨率0.5℃;

3.支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温;

4.工作电源: 3~5V/DC;          

5.在使用中不需要任何外围元件;

6.测量结果以9~12位数字量方式串行传送。

本设计中,用ds18b20来采集供暖水的水温数据,以单线串口形式将数据输送给单片机处理。

图2 ds18b20引脚图

3、压力传感器mpx4250

压力传感器是工业实践中最为常用的一种传感器,而我们通常使用的压力传感器主要是利用压电效应制造而成的,这样的传感器也称为压电传感器。压电传感器结构简单、体积小、质量累世、功耗小、寿命长,特别是它具有良好的动态特性,因此适合有很宽频带的周期作用力和高速变化的冲击力。

mpx4250的主要性能指标:

1.工作压力0 ~ 36.3 PSI;

2.输出0.2 ~ 4.9V;

3.精确度±1.4%;

4.电源电压4.85 V ~ 5.35 V;

5.工作温度-40°C ~ 125°C。

图3 mpx4250引脚功能图

本设计中,用mpx4250来采集供暖水压数据,1端口输出采集的水压数据到adc0808模数转换芯片。

4、模数转换芯片adc0808

ADC0808是美国国家半导体公司生产的CMOS工艺8通道,8位逐次逼近式A/D模数转换器。其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D转换。

adc0808主要特性:

1. 8路输入通道,8位A/D转换器,即分辨率为8位;

2.具有转换起停控制端;

3.转换时间为100μs(时钟为640kHz时),130μs(时钟为500kHz时);

4.单个+5V电源供电;

5.模拟输入电压范围0~+5V,无需零点和满刻度校准;

6.工作温度范围为-40~+85摄氏度;                           图4 adc0808引脚接线图

7.低功耗,约15mW

本设计中,adc0808模数芯片用于压力传感器mpx4250的水压模拟量串口输入的数据转化为数字量并口输出给单片机P0口的数据。

5、8个8段数码管与数码管显示驱动芯片max7219

led数码管是由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。led数码管根据LED的接法不同分为共阴和共阳两类。8段led数码管分为8个显示段,分别是:a、b、c、d、e、f、g、dp,dp是小数点位段。

根据数码管的驱动方式的不同,可以分为静态式和动态式两类。                                 图5 数码管引脚定义

静态驱动显示也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。

动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。

MAX7221是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。

MAX7221显示驱动芯片的主要功能特点:

1. 10MHz 连续串行口;

2. 独立的LED 段控制;

3. 高电压中断显示;

4. 共阴极LED 显示驱动;


5. 限制回转电流的段驱动来减少EMI。

图6 max7221的典型应用电路

本设计中,8个8段共阴极数码管与max7221显示芯片配合驱动显示数据。显示方式为动态显示。前4个数码管显示水温数据,精确到0.1℃。后4个数码管显示水压数据,精确到0.1kpa。同时可以切换显示计数的时间,即系统开启后运行时间的计时。

6、继电器

继电器是一种电控制器件。它具有控制系统(又称输入回路)和被控制系统(又称输出回路)之间的互动关系。通常应用于自动化的控制电路中,它实际上是用小电流去控制大电流运作的一种“自动开关”。当输入量达到规定值时,继电器使被控制的输出电路导通或断开。继电器具有动作快、工作稳定、使用寿命长、体积小等优点。广泛应用于电力保护、自动化、运动、遥控、测量和通信等装置中。


本设计中,用了两个电磁继电器对报警灯回路进行接通或断开操作。

图7 本设计中的继电器和报警灯的电路图

四、软件程序设计

1、系统硬件控制描述

1.控制器用at89c51,12M晶振;

2.采集的水压数据输入—P0口;

3.采集的水温数据输入—P2.7;

4.数码管、max7221显示驱动—P2.0~P2.2;

5.adc0808模数芯片的控制—P2.3~P2.5;

6.切换数码管显示的按钮端—P2.6;

7.继电器控制端—P3.0、P3.1。

2、c程序语言设计

自定义的h文件:

#ifndef _MAIN_H_

#define _MAIN_H_

#include<regx51.h>

#include<intrins.h>

#include<absacc.h>

#define uchar unsigned char

#define uint unsigned int

#define addo (260.0/255.0)

sbit DIN = P2^0;

sbit CS = P2^1;

sbit CLK = P2^2;

sbit START = P2^3;

sbit EOC = P2^4;

sbit OE = P2^5;

sbit KEY = P2^6;

sbit DQ = P2^7;

sbit NPN1 = P3^0;

sbit NPN2 = P3^1;

#endif

#ifndef _DISPLAY_H_

#define _DISPLAY_H_

#include"main.h"

extern uchar table[8];

extern uchar table1[8];

extern uchar table2[8];

void WriteByte(uchar dat);

void MAX7221_WRITE(uchar addr,uchar dat);

void MAX7221_Initial(void);

void Display(uchar *str);

void HEXTOBCD_One(void);

void HEXTOBCD_Two(void);

#endif

#ifndef _DELAY_H_

#define _DELAY_H_

#include"main.h"

void delay_us(uchar n);

void delay_ms(uint n);

#endif

#ifndef _ADC0808_H_

#define _ADC0808_H_

#include"main.h"

uchar ADC0808_READ(void);

#endif

#ifndef _DS18B20_H_

#define _DS18B20_H_

#include"main.h"

extern uchar flag;

void DS18B20_RST(void);

uchar DS18B20_READ(void);

void DS18B20_WRITE(uchar dat);

uint DS18B20_ReadTemp(void);

#endif

#ifndef _TIME0_H_

#define _TIME0_H_

#include"main.h"

extern uchar secs;

extern uchar minutes;

extern uchar hours;

void Time0_Initial(void);

#endif

程序正文:

#include"main.h"

#include"delay.h"

#include"display.h"

#include"adc0808.h"

#include"ds18b20.h"

#include"time0.h"

uchar ADC0808_READ(void)

{

   uchar temp;

   START = 0;

   START = 1;

   START = 0;

   while(EOC==0);

   OE = 1;

   temp = P0;

   return temp;

}

void delay_us(uchar n)

{

   while(n--);

}

void delay_ms(uint n)

{

   uchar i;

   while(n--)

   {

      for(i=0;i<100;i++);

   }

}

uchar table[9] = {15,15,15,15,15,15,15,15};

uchar table1[8] = {1,2,3,4,5,6,7,8};

uchar table2[8] = {1,2,3,4,5,6,7,8};

void WriteByte(uchar dat)

{

   uchar i;

   for(i=0;i<8;i++)

   {

      DIN = ((dat<<i)&0x80)?1:0;

      CLK = 0;

      _nop_();

      CLK = 1;

      _nop_();

   }

}

void MAX7221_WRITE(uchar addr,uchar dat)

{

   CS = 0;

   WriteByte(addr);

   WriteByte(dat);

   CS = 1;

}

void MAX7221_Initial(void)

{

   MAX7221_WRITE(0x0A,0x07);

   MAX7221_WRITE(0x0B,0x07);

   MAX7221_WRITE(0x0C,0x01);

   MAX7221_WRITE(0x0F,0x00);

   MAX7221_WRITE(0x09,0xFF);

}

void Display(uchar *str)

{

   uchar i;

   for(i=0;i<8;i++)

   {

      MAX7221_WRITE(i+1,str[i]);

   }

}

void HEXTOBCD_One(void)

{

   table1[0] = hours/10;

   table1[1] = hours%10;

   table1[2] = 10;

   table1[3] = minutes/10;

   table1[4] = minutes%10;

   table1[5] = 10;

   table1[6] = secs/10;

   table1[7] = secs%10;

}

void HEXTOBCD_Two(void)

{

   uint temp1,temp2;

   temp1 = DS18B20_ReadTemp();

   temp2 = (int)(ADC0808_READ()*addo*10);

   if(temp1>1000)

   {

      NPN1 = 1;

   }

   else

   {

      NPN1 = 0;

   }

   if(temp2>1600)

   {

      NPN2 = 1;

   }

   else

   {

      NPN2 = 0;

   }

   if(flag==0)

   {

      table2[0] = temp1/1000;

   }

   else

   {

      table2[0] = 10;

   }

   table2[1] = temp1%1000/100;

   table2[2] = (temp1%100/10)|0x80;

   table2[3] = temp1%10;

   table2[4] = temp2/1000;

   table2[5] = temp2%1000/100;

   table2[6] = (temp2%100/10)|0x80;

   table2[7] = temp2%10;

}

uchar flag = 0;

void DS18B20_RST(void)

{

   DQ = 1;

   delay_us(4);

   DQ = 0;

   delay_us(100);

   DQ = 1;

   delay_us(40);

}

uchar DS18B20_READ(void)

{

   uchar i,temp = 0;

   for(i=0;i<8;i++)

   {

      DQ = 0;

      temp >>= 1;

      DQ = 1;

      if(DQ)

      {

         temp |= 0x80;

      }

      delay_us(10);

   }

   return temp;

}

void DS18B20_WRITE(uchar dat)

{

   uchar i;

   for(i=0;i<8;i++)

   {

      DQ = 0;

      DQ = (dat&0x01)?1:0;

      delay_us(10);

      DQ = 1;

      dat >>= 1;

   }

}

uint DS18B20_ReadTemp(void)

{

   uchar  temp_h,temp_l;

   uint temp = 0;

   DS18B20_RST();

   DS18B20_WRITE(0xcc);

   DS18B20_WRITE(0x44);

      DS18B20_RST();

   DS18B20_WRITE(0xcc);

   DS18B20_WRITE(0xbe);

   temp_h = DS18B20_READ();

   temp_l = DS18B20_READ();

   temp = temp_l;

   temp <<= 8;

   temp |= temp_h;

   if(temp<0x0fff)

   {

      flag = 0;

   }

   else

   {

      flag = 1;

      temp = ~temp+1;

   }

   temp = temp*(0.625);

   return temp;

}

uchar secs = 0;

uchar minutes = 0;

uchar hours = 0;

void Time0_Initial(void)

{

   TMOD = 0x01;

   TH0 = 0x15;

   TL0 = 0x9f;

   ET0 = 1;

   TR0 = 1;

   EA = 1;

}

volatile unsigned char cnt = 0;

void Time0_Interrupt(void) interrupt 1

{

   TH0 = 0x15;

   TL0 = 0x9f;

   cnt ++;

   if(cnt==10)

   {

      cnt = 0;

      secs ++;

   }

   if(secs==60)

   {

      secs = 0;

      minutes ++;

   }

   if(minutes==60)

   {

      minutes = 0;

      hours++;

   }

   if(hours==24)

   {

      hours = 0;

   }

}

void main()

{

   uchar ready = 0;

   NPN1 = 0,NPN2 = 0;

   MAX7221_Initial();

   delay_us(10);

   Time0_Initial();

   delay_us(10);

   while(1)

   {

      if(KEY==0)

      {

         delay_ms(5);

         if(KEY==0)

         {

            ready ++;

         }

         while(KEY==0);

         delay_ms(5);

      }

      switch(ready)

      {

         case 0:

         {

            Display(table);

            delay_ms(10);

            break;

         }

         case 1:

         {

            HEXTOBCD_One();

            Display(table1);

            delay_ms(10);

            break;

         }

         case 2:

         {

            HEXTOBCD_Two();

            Display(table2);

            delay_ms(10);

            break;

         }

         case 3:

         {

            Display(table);

            delay_ms(10);

            ready = 0;

            break;

         }

         default:

         {

            break;

         }

      }

      delay_ms(500);

   }

}

相关推荐