
c展开代码QQ742971636
/***********************1ms延时函数*****************************/
void delay_1ms( uint q )
{
 uint i, j;
 for ( i = 0; i < q; i++ )
  for ( j = 0; j < 120; j++ )
   ;
}
/***********************小延时函数*****************************/
void delay_uint( uint q )
{
 while ( q-- )
  ;
}
/***********************数码显示函数*****************************/
void display()
{
 static uchar i;
 i++;
 if ( i >= 4 )
  i = 0;
 P1 = 0xff;         /* 消隐 */
 P3 = smg_we[i];    /* 位选 */
 P1 = dis_smg[i];   /* 段选 */
}
/***********************18b20初始化函数*****************************/
void init_18b20()
{
 bit q;
 dq = 1; /* 把总线拿高 */
 delay_uint( 1 );
 dq = 0; /* 给复位脉冲 */
 delay_uint( 80 );
 dq = 1; /* 把总线拿高 等待 */
 delay_uint( 10 );
 q = dq; /* 读取18b20初始化信号 */
 delay_uint( 20 );
 dq = 1; /* 把总线拿高 释放总线 */
}
/*************写18b20内的数据***************/
void write_18b20( uchar dat )
{
 uchar i;
 for ( i = 0; i < 8; i++ )
 {                               /* 写数据是低位开始 */
  dq = 0;            /* 把总线拿低写时间隙开始 */
  dq = dat & 0x01;   /* 向18b20总线写数据了 */
  delay_uint( 5 );
  dq = 1;            /* 释放总线 */
  dat >>= 1;
 }
}
/*************读取18b20内的数据***************/
uchar read_18b20()
{
 uchar i, value;
 for ( i = 0; i < 8; i++ )
 {
  dq = 0;    /* 把总线拿低读时间隙开始 */
  value >>= 1;  /* 读数据是低位开始 */
  dq = 1;    /* 释放总线 */
  if ( dq == 1 )  /* 开始读写数据 */
   value |= 0x80;
  delay_uint( 5 );
 }
 return(value);          /* 返回数据 */
}
/*************读取温度的值 读出来的是小数***************/
uint read_temp()
{
 uint value;
 uchar low;                                            /* 在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序 */
 init_18b20();                                           /* 初始化18b20 */
 write_18b20( 0xcc );                                    /* 跳过64位ROM */
 write_18b20( 0x44 );                                    /* 启动一次温度转换命令 */
 delay_uint( 50 );
 init_18b20();                                           /* 初始化18b20 */
 write_18b20( 0xcc );                                    /* 跳过64位ROM */
 write_18b20( 0xbe );                                    /* 发出读取暂存器命令 */
 EA = 0;
 low = read_18b20();                                 /* 读温度低字节 */
 value = read_18b20();                                 /* 读温度高字节 */
 EA = 1;
 value <<= 8;                                          /* 把温度的高位左移8位 */
 value |= low;                                         /* 把读出的温度低位放到value的低八位中 */
 value *= 0.625;                                       /* 转换到温度值 小数 */
 return(value);                                          /* 返回读出的温度 带小数 */
}
/*************定时器0初始化程序***************/
void time_init()
{
 EA = 1;                                            /* 开总中断 */
 TMOD = 0X01;                                         /* 定时器0、定时器1工作方式1 */
 ET0 = 1;                                            /* 开定时器0中断 */
 TR0 = 1;                                            /* 允许定时器0定时 */
}
/********************独立按键程序*****************/
uchar key_can;                                                  /*按键值 */
void key()                                                      /* 独立按键程序 */
{
 static uchar key_new;
 key_can = 0;                                            /*按键值还原 */
 P2 |= 0x07;
 if ( (P2 & 0x07) != 0x07 )                              /*按键按下 */
 {
  if ( key_500ms == 1 )                           /* 连加 */
  {
   key_500ms = 0;
   key_new  = 1;
  }
  delay_1ms( 1 );                                 /*按键消抖动 */
  if ( ( (P2 & 0x07) != 0x07) && (key_new == 1) )
  {                                               /* 确认是按键按下 */
   key_new = 0;
   switch ( P2 & 0x07 )
   {
   case 0x06: key_can = 3; break;     /* 得到k2键值 */
   case 0x05: key_can = 2; break;     /* 得到k3键值 */
   case 0x03: key_can = 1; break;     /* 得到k4键值 */
   }
   flag_lj_en = 1;                         /* 连加使能 */
  }
 }else  {
  key_new  = 1;
  flag_lj_en = 0;                            /* 关闭连加使能 */
  flag_lj_3_en = 0;                            /* 关闭3秒后使能 */
  key_value = 0;                            /* 清零 */
  key_time = 0;
  key_500ms = 0;
 }
}
/****************按键处理数码管显示函数***************/
void key_with()
{
 if ( key_can == 1 ) /* 设置键 */
 {
  menu_1++;
  if ( menu_1 >= 3 )
  {
   menu_1 = 0;
  }
 }
 if ( menu_1 == 1 )                                              /* 设置高温报警 */
 {
  if ( key_can == 2 )
  {
   if ( flag_lj_3_en == 0 )
    t_high++;                               /*按键按下未松开自动加三次 */
   else
    t_high += 10;                           /*按键按下未松开自动加三次之后每次自动加10 */
   if ( t_high > 990 )
    t_high = 990;
  }
  if ( key_can == 3 )
  {
   if ( flag_lj_3_en == 0 )
    t_high--;                               /*按键按下未松开自动减三次 */
   else
    t_high -= 10;                           /*按键按下未松开自动减三次之后每次自动减10 */
   if ( t_high <= t_low )
    t_high = t_low + 1;
  }
  dis_smg[0] = smg_du[t_high % 10];                  /* 取小数显示 */
  dis_smg[1] = smg_du[t_high / 10 % 10] & 0xdf;      /* 取个位显示 */
  dis_smg[2] = smg_du[t_high / 100 % 10];            /* 取十位显示 */
  dis_smg[3] = 0x64;                                 /* H */
 }
 if ( menu_1 == 2 )                                              /* 设置低温报警 */
 {
  if ( key_can == 2 )
  {
   if ( flag_lj_3_en == 0 )
    t_low++;                                /*按键按下未松开自动加三次 */
   else
    t_low += 10;                            /*按键按下未松开自动加三次之后每次自动加10 */
   if ( t_low >= t_high )
    t_low = t_high - 1;
  }
  if ( key_can == 3 )
  {
   if ( flag_lj_3_en == 0 )
    t_low--;                                /*按键按下未松开自动减三次 */
   else
    t_low -= 10;                            /*按键按下未松开自动加三次之后每次自动加10 */
   if ( t_low <= 10 )
    t_low = 10;
  }
  dis_smg[0] = smg_du[t_low % 10];                   /* 取小数显示 */
  dis_smg[1] = smg_du[t_low / 10 % 10] & 0xdf;       /* 取个位显示 */
  dis_smg[2] = smg_du[t_low / 100 % 10];             /* 取十位显示 */
  dis_smg[3] = 0x3D;                                 /* L */
 }
}
/****************报警函数***************/
void clock_h_l()
{
 if ( (temperature <= t_low) || (temperature >= t_high) )
 {
  beep = ~beep; /* 蜂鸣器报警 */
 }else   {
  beep = 1;
 }
}
/****************主函数***************/
void main()
{
 beep = 0;                                                                       /* 开机叫一声 */
 delay_1ms( 150 );
 P0  = P1 = P2 = P3 = 0xff;
 temperature = read_temp();                                                  /* 先读出温度的值 */
 delay_1ms( 750 );
 temperature = read_temp();                                                  /* 先读出温度的值 */
 dis_smg[0] = smg_du[temperature % 10];                                     /* 取温度的小数显示 */
 dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf;                         /* 取温度的个位显示 */
 dis_smg[2] = smg_du[temperature / 100 % 10];                               /* 取温度的十位显示 */
 dis_smg[3] = 0xFF;
 time_init();                                                                    /* 初始化定时器 */
 while ( 1 )
 {
  key();                                                                  /*按键程序 */
  if ( key_can != 0 )
  {
   key_with();                                                     /* 设置报警温度 */
  }
  if ( flag_300ms == 1 )                                                  /* 300ms 处理一次温度程序 */
  {
   flag_300ms = 0;
   temperature = read_temp();                                  /* 先读出温度的值 */
   clock_h_l();                                                    /* 报警函数 */
   if ( menu_1 == 0 )
   {
    dis_smg[0] = smg_du[temperature % 10];             /* 取温度的小数显示 */
    dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; /* 取温度的个位显示 */
    dis_smg[2] = smg_du[temperature / 100 % 10];       /* 取温度的十位显示 */
    dis_smg[3] = 0xFF;
   }
  }
 }
}
/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{
 static uchar value;                             /* 定时2ms中断一次 */
 TH0 = 0xf8;
 TL0 = 0x30;                                 /* 2ms */
 display();                                      /* 数码管显示函数 */
 value++;
 if ( value >= 150 )
 {
  value  = 0;
  flag_300ms = 1;
 }
 if ( flag_lj_en == 1 )                          /*按下按键使能 */
 {
  key_time++;
  if ( key_time >= 250 )                  /* 500ms */
  {
   key_time = 0;
   key_500ms = 1;            /* 500ms */
   key_value++;
   if ( key_value > 3 )
   {
    key_value = 10;
    flag_lj_3_en = 1;    /* 3次后1.5秒连加大些 */
   }
  }
 }
}
只有一个上限的情况:

c展开代码#include <reg52.h>                              /* 包含单片机寄存器的头文件 */
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define dula P0                              /* 段选信号的锁存器控制 */
uint   temp;                   /* variable of temperature */
uint   WENDU;                  /* WENDU */
uint   BAOJINGLINJIE = 300;  /* 报警数值 30摄氏度  */
unsigned char code table[]  = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
         0x07,        0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e,0x79,0x71 };
unsigned char  BUFFER[3] = { 0, 1, 2 };
sbit DS = P2 ^ 2;                       /* define interfac */
sbit sound = P2 ^ 3;                       /* 蜂鸣器 */
sbit wei1 = P2 ^ 4;
sbit wei2 = P2 ^ 5;
sbit wei3 = P2 ^ 6;
sbit wei4 = P2 ^ 7;
sbit key_01 = P3 ^ 4;
sbit key_02 = P3 ^ 5;
sbit key_03 = P3 ^ 6;
sbit key_04 = P3 ^ 7;
/* 延时函数 */
void delay_ms_key( unsigned char t ) /* 延时xms */
{
 unsigned char ttt;
 while ( t-- )
 {
  for ( ttt = 0; ttt < 125; ttt++ )
   ;
 }
}
/*
 * 四个按键的检测函数
 * 按键则返回1 2 3 4
 * 无按键则返回0xff
 */
unsigned char KeySscan( void )
{
 unsigned char keyvaluee = 0;
 if ( key_01 == 0 )
 {
  delay_ms_key( 2 );
  if ( key_01 == 0 )
  {
   while ( key_01 == 0 )
    ;
   return(1);
  }
 }
 if ( key_02 == 0 )
 {
  delay_ms_key( 2 );
  if ( key_02 == 0 )
  {
   while ( key_02 == 0 )
    ;
   return(2);
  }
 }
 if ( key_03 == 0 )
 {
  delay_ms_key( 2 );
  if ( key_03 == 0 )
  {
   while ( key_03 == 0 )
    ;
   return(3);
  }
 }
 if ( key_04 == 0 )
 {
  delay_ms_key( 2 );
  if ( key_04 == 0 )
  {
   while ( key_04 == 0 )
    ;
   return(4);
  }
 }
 return(0);
}
void delay( uint count )      /* delay */
{
 uint i;
 while ( count )
 {
  i = 200;
  while ( i > 0 )
   i--;
  count--;
 }
}
void dsreset( void )            /* send reset and initialization command */
{
 uint i;
 DS = 0;
 i = 103;          /* 将总线拉低480us~960us */
 while ( i > 0 )
  i--;
 DS = 1;            /* 然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低 */
 i = 4;            /* 15us~60us等待 */
 while ( i > 0 )
  i--;
 /* while(DS); */
}
bit tmpreadbit( void )          /* read a bit */
{
 uint i;
 bit dat;
 DS = 0; i++;       /* i++ for delay */
 DS = 1; i++; i++;
 dat = DS;
 i = 8; while ( i > 0 )
  i--;
 return(dat);
}
uchar tmpread( void )                                   /* read a byte date */
{
 uchar i, j, dat;
 dat = 0;
 for ( i = 1; i <= 8; i++ )
 {
  j = tmpreadbit();
  dat = (j << 7) | (dat >> 1);        /* 读出的数据最低位在最前面,这样刚好一个字节在DAT里 */
 }
 return(dat);
}
void tmpwritebyte( uchar dat )                          /* write a byte to ds18b20 */
{
 uint i;
 uchar j;
 bit testb;
 for ( j = 1; j <= 8; j++ )
 {
  testb = dat & 0x01;
  dat = dat >> 1;
  if ( testb ) /* write 1 */
  {
   DS = 0;
   i++; i++;
   DS = 1;
   i = 8; while ( i > 0 )
    i--;
  }else  {
   DS = 0; /* write 0 */
   i = 8; while ( i > 0 )
    i--;
   DS = 1;
   i++; i++;
  }
 }
}
void tmpchange( void )          /* DS18B20 begin change */
{
 dsreset();
 delay( 1 );
 tmpwritebyte( 0xcc );   /* address all drivers on bus */
 tmpwritebyte( 0x44 );   /*  initiates a single temperature conversion */
 /* delay(100); */
}
uint tmp()                      /* get the temperature */
{
 float tt;
 uchar a, b;
 dsreset();
 delay( 1 );
 tmpwritebyte( 0xcc );
 tmpwritebyte( 0xbe );
 a = tmpread();            /* 低八位 */
 b = tmpread();            /* 高八位 */
 temp = b;
 temp <<= 8;                  /* two byte  compose a int variable */
 temp = temp | a;
 tt = temp * 0.0625;        /* 算出来的是测到的温度,数值可到小数点后两位 */
 temp = tt * 10 + 0.5;        /* 为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数 */
 return(temp);
}
/*  ******************************************    */
/*  ********   定时器初始化函数  用了定时器1 */
/*  ******************************************    */
void init_timer( void )
{
 TMOD = 0x01;
 TH0 = (65536 - 4000) / 256;
 TL0 = (65536 - 4000) % 256;
 ET0 = 1;
 TR0 = 1;
 EA = 1;
}
/*------------------------------------------------
 *                   主函数
 *  ------------------------------------------------*/
main()
{
 unsigned char keyvalue = 0;
 char  xiugai  = 0;
 init_timer();
 while ( 1 )
 {
  /* 温度高了就报警 */
  if ( WENDU > BAOJINGLINJIE )
  {
   sound = 0;
   P1=0X00;
  }else{
   sound = 1;
   P1=0XFF;
  }
  /* 根据当前模式显示出数值 */
  if ( xiugai == 0 )
  {
   BUFFER[0] = WENDU / 100;
   BUFFER[1] = WENDU % 100 / 10;
   BUFFER[2] = WENDU % 10;
  }else{
   BUFFER[0] = BAOJINGLINJIE / 100;
   BUFFER[1] = BAOJINGLINJIE % 100 / 10;
   BUFFER[2] = BAOJINGLINJIE % 10;
  }
  /* 检测按键 */
  keyvalue = KeySscan();
  if ( keyvalue != 0 )
  {
   if ( keyvalue == 1 )
   {
    xiugai = !xiugai; /* 模式 */
   }else if ( keyvalue == 3 )
   {
    BAOJINGLINJIE += 1;
    if ( BAOJINGLINJIE > 490 )
     BAOJINGLINJIE = 490;
   }else if ( keyvalue == 4 )
   {
    BAOJINGLINJIE -= 1;
    if ( BAOJINGLINJIE < 10 )
     BAOJINGLINJIE = 10;
   }
  }
  delay( 10 );
 }
}
char jishua  = 0;
uint timecount = 0;
void T0_time()
interrupt 1
{
 TH0 = (65536 - 5000) / 256;
 TL0 = (65536 - 5000) % 256;
 jishua = (jishua + 1) % 4;
 timecount++;
 if ( timecount == 200 )
 {
  timecount = 0;
  tmpchange();    /* 让18b20开始转换温度 */
  tmp();          /* 读取温度数值 */
  WENDU = (uint) (temp); 
 }
 P0 = 0x00;
 if ( jishua == 0 )
 {
  wei1 = 1;    /* 显示百位 */
  wei2 = 0;
  wei3 = 0;
  wei4 = 0;
  P0 = table[BUFFER[0]];
 }else if ( jishua == 1 )
 {
  wei1 = 0;    /* 显示十位 */
  wei2 = 1;
  wei3 = 0;
  wei4 = 0;
  P0 = table[BUFFER[1]] | 0x80;
 }else if ( jishua == 2 )
 {
  wei1 = 0;    /* 显示个位 */
  wei2 = 0;
  wei3 = 1;
  wei4 = 0;
  P0 = table[BUFFER[2]];
 }else if ( jishua == 3 )
 {
  wei1 = 0;    /* 显示个位 */
  wei2 = 0;
  wei3 = 0;
  wei4 = 1;
  P0 = 0x39;
 }
}


本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!