找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2192|回复: 0
打印 上一主题 下一主题
收起左侧

单片机+Proteus仿真压力温度心跳报警仿真程序

[复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
#include <reg52.h>  
#include <intrins.h>
#define uchar unsigned char   //宏定义
#define uint unsigned int     //宏定义

#define High 1
#define Low        0
#define _nop {}
#define PAGEADD 0xb8
#define TIERADD 0x40
#define DIS_STARADD 0xc0

sbit DI=P3^7;
sbit E=P3^5;
sbit CS1=P3^1;
sbit CS2=P3^4;
sbit RW=P3^6;
sbit ST=P3^0;  //位定义
sbit OE=P1^1;  //位定义
sbit EOC=P1^0;  //位定义
sbit CLK=P3^3;  //位定义
sbit DQ = P1^7;//温度传感器
sbit BEEP = P1^2;//蜂鸣器

void init1820();
void write1820(uchar a);
unsigned char read1820(void);
uchar gettemp();
void ShowTem();
unsigned char idata flag;
unsigned char temp;
uint Tem;
uchar show[4] = {1,2,3,4};
uint key_value;         //按键数值
/*****************************
    字符表
******************************/
uchar code table1[]={
0x00,0x3e,0x51,0x49,0x45,0x3e,0x00,0x00,//0(0)
0x00,0x00,0x42,0x7f,0x40,0x00,0x00,0x00,//1
0x00,0x42,0x61,0x51,0x49,0x46,0x00,0x00,//2
0x00,0x21,0x41,0x45,0x4b,0x31,0x00,0x00,//3
0x00,0x18,0x14,0x12,0x7f,0x10,0x00,0x00,//4
0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00,//5
0x00,0x3c,0x4a,0x49,0x49,0x30,0x00,0x00,//6
0x00,0x01,0x01,0x79,0x05,0x03,0x00,0x00,//7
0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,//8
0x00,0x06,0x49,0x49,0x29,0x1e,0x00,0x00,//9
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// (10)
0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x00,//!
0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00,//%
0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00,//&
0x00,0x14,0x08,0x3e,0x08,0x14,0x00,0x00,//*
0x00,0x08,0x08,0x3e,0x08,0x08,0x00,0x00,//+
0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,//-
0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,//.
0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00,///
0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,//:(19)
0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00,//=
0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00,//?
0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00,//@(22)
0x00,0x7e,0x11,0x11,0x11,0x7f,0x00,0x00,//A
0x00,0x41,0x7f,0x49,0x49,0x36,0x00,0x00,//B
0x00,0x3e,0x41,0x41,0x41,0x22,0x00,0x00,//C
0x00,0x41,0x7f,0x41,0x41,0x3e,0x00,0x00,//D
0x00,0x7f,0x49,0x49,0x49,0x49,0x00,0x00,//E
0x00,0x7f,0x09,0x09,0x09,0x01,0x00,0x00,//F
0x00,0x3e,0x41,0x41,0x49,0x7a,0x00,0x00,//G(29)
0x00,0x7f,0x08,0x08,0x08,0x7f,0x00,0x00,//H
0x00,0x00,0x41,0x7f,0x41,0x00,0x00,0x00,//I
0x20,0x40,0x41,0x3f,0x01,0x01,0x00,0x00,//J
0x00,0x7f,0x08,0x14,0x22,0x41,0x00,0x00,//K
0x00,0x7f,0x40,0x40,0x40,0x40,0x00,0x00,//L
0x00,0x7f,0x02,0x0c,0x02,0x7f,0x00,0x00,//M
0x00,0x7f,0x06,0x08,0x30,0x7f,0x00,0x00,//N
0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00,//O
0x00,0x7f,0x09,0x09,0x09,0x06,0x00,0x00,//P
0x00,0x3e,0x41,0x51,0x21,0x5e,0x00,0x00,//Q(39)
0x00,0x7f,0x09,0x19,0x29,0x46,0x00,0x00,//R
0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00,//S
0x00,0x01,0x01,0x7f,0x01,0x01,0x00,0x00,//T
0x00,0x3f,0x40,0x40,0x40,0x3f,0x00,0x00,//U
0x00,0x1f,0x20,0x41,0x20,0x1f,0x00,0x00,//V
0x00,0x7f,0x20,0x80,0x20,0x7f,0x00,0x00,//W
0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00,//X
0x00,0x07,0x08,0x70,0x08,0x07,0x00,0x00,//Y
0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00,//Z
0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00,//a(49)
0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00,//b
0x00,0x38,0x44,0x44,0x44,0x28,0x00,0x00,//c
0x00,0x38,0x44,0x44,0x48,0x7f,0x00,0x00,//d        
0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00,//e
0x00,0x00,0x08,0x7e,0x09,0x02,0x00,0x00,//f
0x00,0x0c,0x52,0x52,0x4c,0x3e,0x00,0x00,//g
0x00,0x7f,0x08,0x04,0x04,0x78,0x00,0x00,//h
0x00,0x00,0x44,0x7d,0x40,0x00,0x00,0x00,//i
0x00,0x20,0x40,0x44,0x3d,0x00,0x00,0x00,//j
0x00,0x00,0x7f,0x10,0x28,0x44,0x00,0x00,//k(59)
0x00,0x00,0x41,0x7f,0x40,0x00,0x00,0x00,//l
0x00,0x7c,0x04,0x78,0x04,0x78,0x00,0x00,//m
0x00,0x7c,0x08,0x04,0x04,0x78,0x00,0x00,//n
0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00,//o
0x00,0x7e,0x0c,0x12,0x12,0x0c,0x00,0x00,//p
0x00,0x0c,0x12,0x12,0x0c,0x7e,0x00,0x00,//q
0x00,0x7C,0x08,0x04,0x04,0x08,0x00,0x00,//r
0x00,0x58,0x54,0x54,0x54,0x64,0x00,0x00,//s
0x00,0x04,0x3f,0x44,0x40,0x20,0x00,0x00,//t
0x00,0x3c,0x40,0x40,0x3c,0x40,0x00,0x00,//u(69)
0x00,0x1c,0x20,0x40,0x20,0x1c,0x00,0x00,//v
0x00,0x3c,0x40,0x30,0x40,0x3c,0x00,0x00,//w
0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00,//x
0x00,0x1c,0xa0,0xa0,0x90,0x7c,0x00,0x00,//y
0x00,0x44,0x64,0x54,0x4c,0x44,0x00,0x00,//z(74)
};
/****************************
中文汉字表
*****************************/
uchar code table2[]={
0x10,0x10,0x14,0xD4,0x54,0x54,0x54,0xFC,
0x52,0x52,0x52,0xD3,0x12,0x10,0x10,0x00,
0x40,0x40,0x50,0x57,0x55,0x55,0x55,0x7F,
0x55,0x55,0x55,0x57,0x50,0x40,0x40,0x00,//重(0)

};

/********************************
    延时  ms  大小由n决定
*********************************/


void Delay_nms(uchar n)
{ uchar a;
   for(;n>0;n--)
      {
           for(a=0;a<100;a++)
              {
                   _nop;
                   _nop;
                   _nop;
                   _nop;
                   };
           };
  }


/*****************************************
    DEM12864B状态检测
******************************************/


void LCD_Busy()
{
  uchar busy;
  E=Low;
  DI=Low;
  RW=High;
  while(1)
  {
    E=High;
    _nop;
        _nop;
    busy=P2;//都状态标志寄存器
        _nop;
    E=Low;
    if((busy&0x90)==0)//读BF和RES  都为0可写入
    break;
  };
}

/*********************************
    写指令
**********************************/
void WRCommand_L(uchar command)
{
  CS1=High;
  CS2=Low;
  LCD_Busy();
  DI=Low;
  _nop;
  RW=Low;
  _nop;
  E=High;
  _nop;
  P2=command;
  _nop;
  E=Low;
  _nop;
}


void WRCommand_R(uchar command)
{
  CS1=Low;
  CS2=High;
  LCD_Busy();
  DI=Low;
  _nop;
  RW=Low;
  _nop;
  E=High;
  _nop;
  P2=command;
  _nop;
  E=Low;
  _nop;
}


/***********************************
     写一个字节的显示数据
************************************/
void WRdata_L(uchar ucdata)
  {
   CS1=High;
   CS2=Low;
   LCD_Busy();
   DI=High;
   _nop;
   RW=Low;
   _nop;
   E=High;
   _nop;
   P2=ucdata;
   _nop;
   E=Low;
   _nop;
  }


void WRdata_R(uchar ucdata)
  {
   CS1=Low;
   CS2=High;
   LCD_Busy();  
   DI=High;
   _nop;
   RW=Low;
   _nop;
   E=High;
   _nop;
   P2=ucdata;
   _nop;
   E=Low;
   _nop;
  }
/****************************************************
   字符为16*16显示  例如汉字
*****************************************************/
C_display_L(uchar C_Pagenum,uchar C_Tiernum,uchar C_Temp)
  {
   uchar k;
   C_Pagenum=PAGEADD|C_Pagenum;
   C_Tiernum=TIERADD|C_Tiernum;
   WRCommand_L(C_Pagenum);
   WRCommand_L(C_Tiernum);
   for(k=0;k<16;k++)
      {
       WRdata_L(table2[C_Temp*32+k]);
             };
   C_Pagenum=C_Pagenum+1;
   WRCommand_L(C_Pagenum);
   WRCommand_L(C_Tiernum);
   for(k=0;k<16;k++)
      {
       WRdata_L(table2[C_Temp*32+k+16]);
           };
   }

C_display_R(uchar C_Pagenum,uchar C_Tiernum,uchar C_Temp)
  {
   uchar k;
   C_Pagenum=PAGEADD|C_Pagenum;
   C_Tiernum=TIERADD|C_Tiernum;
   WRCommand_R(C_Pagenum);
   WRCommand_R(C_Tiernum);
   for(k=0;k<16;k++)
      {
       WRdata_R(table2[C_Temp*32+k]);
             };
   C_Pagenum=C_Pagenum+1;
   WRCommand_R(C_Pagenum);
   WRCommand_R(C_Tiernum);
   for(k=0;k<16;k++)
      {
       WRdata_R(table2[C_Temp*32+k+16]);
             };
  }

/****************************************
  写入西文字符
*****************************************/

E_Display_L(uchar E_Pagenum,uchar E_Tiernum,uchar E_Temp)
  {
   uchar k;
   WRCommand_L(PAGEADD|E_Pagenum);
   WRCommand_L(TIERADD|E_Tiernum);
   for(k=0;k<8;k++)
          {
           WRdata_L(table1[E_Temp*8+k]);
           };
   }   
E_Display_R(uchar E_Pagenum,uchar E_Tiernum,uchar E_Temp)
   {
   uchar k;
   WRCommand_R(PAGEADD|E_Pagenum);
   WRCommand_R(TIERADD|E_Tiernum);
   for(k=0;k<8;k++)
          {
           WRdata_R(table1[E_Temp*8+k]);
           };
           }

/*********************************
           清空显示RAM
**********************************/

CLR_DisplayRAM()
   {
    uchar C_page,i,k;
    for(i=0;i<8;i++)
           {
            C_page=PAGEADD|i;//起始页为0
            WRCommand_L(C_page);//清除起始页写入
                WRCommand_L(TIERADD);//清除起始行地址写入
                WRCommand_R(C_page);
                WRCommand_R(TIERADD);
                for(k=0;k<64;k++)
                   {                           
                        WRdata_L(0x00);
                        WRdata_R(0x00);//lcm?ram自+1  只润许循环64次  
                         };
                 };
    }

/*********************************
     初始化LCD
**********************************/
void Init_LCD(void)
   {
        CLR_DisplayRAM();//清除所有显示寄存器
        WRCommand_L(DIS_STARADD);
        WRCommand_R(DIS_STARADD);//设置显示起始地址
        WRCommand_L(0x3f);
        WRCommand_R(0x3f);//开显示
    }
               
uchar k; //按键值
void Getch (void)        //取键值函数
{
unsigned char X,Y,Z;
P1=0x0f; //先对P3 置数 行扫描
if(P1!=0x0f) //判断是否有键按下
        {
        Delay_nms(10); //延时,软件去干扰
        if(P1!=0x0f) //确认按键按下
                {
                X=P1; //保存行扫描时有键按下时状态
                P1=0xf0; //列扫描
                Y=P1;    //保存列扫描时有键按下时状态
                Z=X|Y; //取出键值
/*********************************************************************/
switch ( Z ) //判断键值(那一个键按下)
                        {
                                case 0xee: k=0; break; //对键值赋值
                                case 0xed: k=1; break;
                                case 0xeb: k=2; break;
                                case 0xe7: k=3; break;
                                case 0xde: k=4; break;
                                case 0xdd: k=5; break;
                                case 0xdb: k=6; break;
                                case 0xd7: k=7; break;
                                case 0xbe: k=8; break;
                                case 0xbd: k=9; break;
                                case 0xbb: k=10;break;
                                case 0xb7: k=11;break;
                                case 0x7e: k=12;break;
                                case 0x7d: k=13;break;
                                case 0x7b: k=14;break;
                                case 0x77: k=15;break;
                        }
                        while(P1!=0xf0);  //等待按键放开
                 }         
         }
}
unsigned char TempBuffer[6];  // 显示数组

unsigned char getdata;        //ADC数值
unsigned char kflag;
unsigned int count=0;  //计数器
unsigned int xintiao =0; //心跳
void main(void)
{
  long int temp2; //临时变量
        uchar a=0,temp1=0,b=0,number=0,pagenum=0;
  ST=0;
  OE=0;
  ET0=1; //打开定时器0中断允许
  ET1=1;  //打开定时器1中断允许
  EA=1;   //打开总中断
  TMOD=0x12;   //选择定时器工作方式
  TH0=216;    //装载初值
  TL0=216;     //装载初值
  TH1=(65536-5000)/256;   //装载初值
  TL1=(65536-5000)%256;    //装载初值
  TR1=1;  //打开定时器1
  TR0=1;  //打开定时器0
  ST=1;
  ST=0;
  Init_LCD();
  IT0=1;//跳变沿出发方式(下降沿)
  EX0=1;//打开INT0的中断允许
  EA=1;//打开总中断
  pagenum=1;//第1页
  E_Display_L(pagenum,0*8,47); //Y
  E_Display_L(pagenum,1*8,34); //L
  E_Display_L(pagenum,2*8,19); //:
    pagenum=3;//第5页
  E_Display_L(pagenum,0*8,46); //X
  E_Display_L(pagenum,1*8,42); //T
  E_Display_L(pagenum,2*8,19); //:
  pagenum=5;//第3页
  E_Display_L(pagenum,0*8,45); //W
  E_Display_L(pagenum,1*8,26); //D
  E_Display_L(pagenum,2*8,19); //:

   BEEP=0;
  while(1)
    {
         
        if(EOC==1)
        {
            OE=1;
            getdata=P0;
            OE=0;
                    temp2=getdata*196;  //ADC数值获取
                        if((temp2>=30000)||(xintiao>=150)||(Tem>=30) )         //检查是否报警
                  {
                        BEEP=1;
                   }
                   else
                   {
                   BEEP=0;
                   }
                        TempBuffer[0]=temp2/10000;  //转换成字符
                        TempBuffer[1]=17;  //转换成字符  小数点
                         temp2=temp2%10000;
                        TempBuffer[2]=temp2/1000;  //转换成字符                                    
                        temp2=temp2%10000;
                TempBuffer[3]=temp/1000;  //转换成字符
                     temp2=temp2%1000;
                        TempBuffer[4]=temp2/100;  //转换成字符
                        pagenum=1;//第1页
            for(a=4;a<8;a++)
            {
             E_Display_L(pagenum,a*8,TempBuffer[a-4]);
            }

            ST=1;
            ST=0;
               
               
            }      
                  pagenum=3;//第3页
                TempBuffer[0]=xintiao/1000;  //转换成字符
                TempBuffer[1]=xintiao%1000/100;  //转换成字符
                TempBuffer[2]=xintiao%100/10;  //转换成字符
                TempBuffer[3]=xintiao%10;  //转换成字符
        for(a=4;a<8;a++)
        {
          E_Display_L(pagenum,a*8,TempBuffer[a-4]);
        }
                ShowTem();
            pagenum=5;//第5页
                TempBuffer[0]=Tem%1000/100;  //转换成字符
                TempBuffer[1]=Tem%100/10;  //转换成字符
                TempBuffer[2]=Tem%10;  //转换成字符
        for(a=4;a<7;a++)
        {
          E_Display_L(pagenum,a*8,TempBuffer[a-4]);
        }
           Delay_nms(50);
    }
}

void t0(void) interrupt 1 using 0           //定时器0  中断服务
{
  CLK=~CLK;
}

void t1(void) interrupt 3 using 0          //定时器1  中断服务
{
  static  unsigned int timer=0;
  TH1=(65536-5000)/256;    //重新装载
  TL1=(65536-5000)%256;
  timer++ ;
  if(timer >=200)
  {
   xintiao=         count;
   timer=0;
   count=0;
  }
}
/*******************************************************************************
* 函 数 名         : Int0()        interrupt 0
* 函数功能                   : 外部中断0的中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Int0()        interrupt 0                //外部中断0的中断函数
{
  count++;
}
/***************
* 函 数:显示温度函数
* 参 数:无
* 返 回: 无
****************/
void ShowTem()
{
   Tem =gettemp();                  /* 读取18b20温度*/

}
//**************************延时程序,一个是1us的延时。一个是1ms的延时 **************
void delay_us(uchar a)//when crystal is 12M ,a*2+5 us  ,子程序调用要5us,while 就等于DJNZ指令
{
    while(--a);
}

//********************1820初始化,读和写的子程序,延时
//*******initial**********
void init1820()
{
DQ = 1; _nop_();
DQ = 0;      //拉低数据线,准备Reset OneWire Bus;
delay_us(125);  //延时510us,Reset One-Wire Bus.
delay_us(125);

DQ = 1;      //提升数据线;
delay_us(15);  //延时35us;

while(DQ)     //等待Slave 器件Ack 信号;
{ _nop_(); }
delay_us(60);  //延时125us;
DQ = 1;      //提升数据线,准备数据传输;
}

//******write********
void write1820(uchar a)
{
    uchar i;
for(i=0;i<8;i++)
{if(a & 0x01)  //低位在前;
   {DQ = 0;    //结束Recovery time;
    _nop_();_nop_();_nop_();
    DQ = 1;   } //发送数据;
  else
   DQ = 0;    //结束Rec time;
    _nop_();_nop_();_nop_();  
    //DQ = 0;  } //发送数据;
  delay_us(30);  //等待Slave Device采样;
  DQ = 1;      //Recovery;
  _nop_();      //Recovery Time Start;
  a >>= 1;
  }

}

//*******read************
unsigned char read1820(void)
{
unsigned char i;
unsigned char tmp=0;
DQ = 1;  _nop_();     //准备读;
for(i=0;i<8;i++)
{
  tmp >>= 1;    //低位先发;
  DQ = 0;      //Read init;
  _nop_();     //2ms;
  DQ = 1;      //必须写1,否则读出来的将是不预期的数据;
  delay_us(2);   //延时9us;
  _nop_();
  if(DQ)      //在12us处读取数据;
   tmp |= 0x80;
  delay_us(30);  //延时55us;
  DQ = 1;   _nop_();   //恢复One Wire Bus;
  }
return tmp; }

//**********************************************************
uchar gettemp()
{  unsigned int tp;
   init1820();
   write1820(0xcc);
//  delay_ms(2);
   write1820(0x44);
  // _nop_();
  // DQ=1;
  // delay_ms(250);        //多个1820时要延时,单个就不用,数据手册里看
  // delay_ms(250);
  // delay_ms(250);
   init1820();
   write1820(0xcc);
   write1820(0xbe);
   show[0]=read1820();
   show[1]=read1820();
   init1820();
   tp=show[1]*256+show[0];
   flag = show[1] >> 7;            //判断温度正负,正时flag = 0;负时flag = 1

   if(flag == 0)
   {
    temp=(tp&0x0f)*10/16;                 
           tp = tp >> 4;
   }
   if(flag == 1)
   {
    tp=~(tp-1);
    temp=(tp&0x0f)*10/16 + 1;         
           tp = tp >> 4;
   //        tp = 256 - tp;
   }
   return tp;
}

全部资料51hei下载地址:
压力心跳温度报警.rar (114.81 KB, 下载次数: 36)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表