cQQ742971636
/***********************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 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!