• 基于51单片机的温度控制系统数码管显示蜂鸣器报警proteus仿真原理图PCB


    功能:
    0.本系统采用STC89C52作为单片机
    1.系统实时监测并显示当前温度,并通过四位数码管显示
    2.超过设定阈值,蜂鸣器将报警,同时控制相应继电器实现降温或者加热
    3.系统具备三个功能按键,可更改温度上限和下限
    4.采用DC002作为电源接口可直接输入5V给整个系统供电

    原理图:

    在这里插入图片描述

    PCB :
    在这里插入图片描述

    主程序:

    
    #include 			// 包含头文件
    #include 
    
    #define uchar unsigned char		// 以后unsigned char就可以用uchar代替
    #define uint  unsigned int		// 以后unsigned int 就可以用uint 代替
    
    sbit DQ = P1^1;						// DS18B20传感器的引脚定义
    sbit w1 = P2^4; 					// 数码管第1位的控制引脚
    sbit w2 = P2^5;						// 数码管第2位的控制引脚
    sbit w3 = P2^6;						// 数码管第3位的控制引脚
    sbit w4 = P2^7;			 			// 数码管第4位的控制引脚
    sbit Buzzer  = P1^0;			// 蜂鸣器引脚
    sbit JdqLow  = P2^0;			// 温度过低继电器控制(加热)
    sbit JdqHig  = P2^1;			// 温度过高继电器控制(降温)
    sbit LedLow  = P2^2;			// 温度低指示灯
    sbit LedHig  = P2^3;			// 温度高指示灯
    sbit KeySet  = P3^2;			// 设置按键
    sbit KeyDown = P3^3;			// 减按键
    sbit KeyUp   = P3^4;			// 加按键
    
    
    
    /*   数码管的显示值:  0    1    2    3    4    5     6   7    8    9    -   */
    uchar code Array1[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40 };
    
    /*                     0.   1.   2.   3.   4.   5.    6.  7.   8.   9.  */
    uchar code Array2[]={ 0xBf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef };
    
    
    uchar Buff[4];					// 显示缓冲区
    uchar ShowID=1;					// 当前显示的是哪一个数码管
    
    int AlarmLow=150;				// 默认报警的温度下限值是15度
    int AlarmHig=300;				// 默认报警的温度上限值是30度
    
    
    /*********************************************************/
    // 毫秒级的延时函数,time是要延时的毫秒数
    /*********************************************************/
    void DelayMs(uint time)
    {
    	uint i,j;
    	for(i=0;i<time;i++)
    		for(j=0;j<112;j++);
    }
    
    
    /*********************************************************/
    // 延时15微秒
    /*********************************************************/
    void Delay15us(void)
    {
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    	_nop_();
    }
    
    
    /*********************************************************/
    // 复位DS18B20(初始化)
    /*********************************************************/
    void DS18B20_ReSet(void)
    {
    	uchar i;
    	DQ=0;
    
    	i=240;
    	while(--i);
    
    	DQ=1;
    
    	i=30;
    	while(--i);
    
    	while(~DQ);
    
    	i=4;
    	while(--i);
    }
    
    
    /*********************************************************/
    // 向DS18B20写入一个字节
    /*********************************************************/
    void DS18B20_WriteByte(uchar dat)
    {
    	uchar j;
    	uchar btmp;
    	
    	for(j=0;j<8;j++)
    	{
    		btmp=0x01;
    		btmp=btmp<<j;
    		btmp=btmp&dat;
    		
    		if(btmp>0)		// 写1
    		{
    			DQ=0;
    			Delay15us();
    			DQ=1;
    			Delay15us();
    			Delay15us();
    			Delay15us();
    			Delay15us();
    		}
    		else			// 写0
    		{
    			DQ=0;
    			Delay15us();
    			Delay15us();
    			Delay15us();
    			Delay15us();
    			DQ=1;
    			Delay15us();
    		}
    	}
    }
    
    
    /*********************************************************/
    // 读取温度值
    /*********************************************************/
    int DS18B20_ReadTemp(void)
    {
    	uchar j;
    	int b,temp=0;	
    
    	DS18B20_ReSet();							// 产生复位脉
    	DS18B20_WriteByte(0xcc);			// 忽略ROM指令
    	DS18B20_WriteByte(0x44);			// 启动温度转换指令
    
    	DS18B20_ReSet();							// 产生复位脉
    	DS18B20_WriteByte(0xcc);			// 忽略ROM指令
    	DS18B20_WriteByte(0xbe);			// 读取温度指令
    
    	for(j=0;j<16;j++)							// 读取温度数量
    	{						
    		DQ=0;
    		_nop_();
    		_nop_();
    		DQ=1;	
    		Delay15us();
    		b=DQ;
    		Delay15us();
    		Delay15us();
    		Delay15us();
    		b=b<<j;
    		temp=temp|b;
    	}
    	
    	temp=temp*0.0625*10;					// 合成温度值并放大10倍					
    	
    	return (temp);								// 返回检测到的温度值
    }
    
    
    /*********************************************************/
    // 定时器初始化
    /*********************************************************/
    void TimerInit()
    {
    	TMOD = 0x01;					// 使用定时器0,工作方式1	 
    	TH0  = 248;						// 给定时器0的TH0装初值
    	TL0  = 48;						// 给定时器0的TL0装初值
    	ET0  = 1;							// 定时器0中断使能
    	EA   = 1;							// 打开总中断
    	TR0	 = 1;							// 启动定时器0
    }
    
    
    /*********************************************************/
    // 显示温度值
    /*********************************************************/
    void ShowTemp(int dat)
    {
    	if(dat<0)												// 负号
    	{
    		Buff[0]=Array1[10];
    		dat=0-dat;
    	}
    	else														// 百位
    	{
    		Buff[0]=Array1[dat/1000];
    	}
    	
    	Buff[1]=Array1[dat%1000/100];		// 十位
    	Buff[2]=Array2[dat%100/10];			// 个位
    	Buff[3]=Array1[dat%10];					// 小数后一位
    }
    
    
    /*********************************************************/
    // 报警判断
    /*********************************************************/
    void AlarmJudge(int dat)
    {
    	if(dat<AlarmLow)				// 判断温度是否过低
    	{
    		LedLow=0;							// 温度低指示灯亮
    		LedHig=1;							// 温度高指示灯灭
    		JdqLow=0;							// 温度过低的继电器闭合(开始加热)
    		JdqHig=1;							// 温度过高的继电器断开(停止降温)
    		Buzzer=0;							// 蜂鸣器报警
    	}
    	else if(dat>AlarmHig)		// 判断温度是否过高
    	{
    		LedLow=1;							// 温度低指示灯灭
    		LedHig=0;							// 温度高指示灯亮
    		JdqLow=1;							// 温度过低的继电器断开(停止加热)
    		JdqHig=0;							// 温度过高的继电器闭合(开始降温)
    		Buzzer=0;							// 蜂鸣器报警
    	}
    	else										// 温度正常
    	{
    		LedLow=1;							// 温度低指示灯灭
    		LedHig=1;							// 温度高指示灯灭
    		JdqLow=1;							// 温度过低的继电器断开(停止加热)
    		JdqHig=1;							// 温度过高的继电器断开(停止降温)
    		Buzzer=1;							// 蜂鸣器停止报警
    	}
    }
    
    
    /*********************************************************/
    // 按键扫描
    /*********************************************************/
    void KeyScanf()
    {
    	if(KeySet==0)									// 如果设置按键被按下
    	{
    		/* 设置温度下限 */
    		LedLow=0;										// 点亮绿色灯(代表当前正在设置温度下限)
    		LedHig=1;										// 熄灭红色灯
    		Buzzer=1;										// 关闭蜂鸣器
    		ShowTemp(AlarmLow);					// 显示温度下限值
    		DelayMs(10);								// 延时去抖
    		while(!KeySet);							// 等待按键释放
    		DelayMs(10);								// 延时去抖
    		
    		while(1)
    		{
    			if(KeyDown==0)								// 如果“减”按键被按下
    			{
    				if(AlarmLow>-550)						// 判断当前温度下限是否大于-55度
    				{
    					AlarmLow--;								// 温度下限值减去0.1度
    					ShowTemp(AlarmLow);				// 刷新显示改变后的温度下限值
    					DelayMs(200);							// 延时
    				}
    			}
    			
    			if(KeyUp==0)									// 如果“加”按键被按下					
    			{
    				if(AlarmLow<1250)						// 判断当前温度下限是否小于125度
    				{
    					AlarmLow++;								// 温度下限值加上0.1度
    					ShowTemp(AlarmLow);				// 刷新显示改变后的温度下限值
    					DelayMs(200);							// 延时
    				}
    			}
    			
    			if(KeySet==0)									// 如果“设置”按键被按下
    			{
    				break;											// 退出温度下限值的设置,准备进入上限值的设置
    			}
    		}
    		
    		/* 设置温度上限 */
    		LedLow=1;										// 熄灭绿色灯
    		LedHig=0;										// 点亮红色灯(代表当前正在设置温度上限)
    		ShowTemp(AlarmHig);					// 显示温度上限值
    		DelayMs(10);								// 延时去抖
    		while(!KeySet);							// 等待按键释放
    		DelayMs(10);								// 延时去抖
    		
    		while(1)
    		{
    			if(KeyDown==0)							// 如果“减”按键被按下							
    			{
    				if(AlarmHig>-550)					// 判断当前温度上限是否大于-55度
    				{
    					AlarmHig--;							// 温度上限值减去0.1度
    					ShowTemp(AlarmHig);			// 刷新显示改变后的温度上限值
    					DelayMs(200);						// 延时
    				}
    			}
    			
    			if(KeyUp==0)								// 如果“加”按键被按下					
    			{
    				if(AlarmHig<1250)					// 判断当前温度上限是否小于125度
    				{
    					AlarmHig++;							// 温度上限值加上0.1度
    					ShowTemp(AlarmHig);			// 刷新显示改变后的温度上限值
    					DelayMs(200);
    				}
    			}
    			
    			if(KeySet==0)								// 如果“设置”按键被按下
    			{
    				break;										// 准备退出设置模式
    			}
    		}
    		
    		/* 退出设置模式 */
    		LedLow=1;									// 熄灭绿灯
    		LedHig=1;									// 熄灭红灯
    		DelayMs(10);							// 延时去抖
    		while(!KeySet);						// 等待按键释放
    		DelayMs(10);							// 延时去抖
    	}
    }
    
    
    /*********************************************************/
    // 主函数
    /*********************************************************/
    void main()
    {
    	int temp;
    	uchar i;
    	
    	TimerInit();										// 定时器0的初始化(数码管的动态扫描)
    	
    	Buff[0]=Array1[0];							// 刚上电显示4个0
    	Buff[1]=Array1[0];
    	Buff[2]=Array1[0];
    	Buff[3]=Array1[0];
    	
    	for(i=0;i<8;i++)								// 由于传感器刚上电读出的温度不稳定,因此先进行几次温度的读取并丢弃
    	{
    		DS18B20_ReadTemp();
    		DelayMs(120);
    	}
    	
    	while(1)
    	{
    		EA=0;													// 屏蔽中断
    		temp=DS18B20_ReadTemp();			// 读取温度值
    		EA=1;													// 恢复中断
    		
    		ShowTemp(temp);								// 显示温度值
    		
    		AlarmJudge(temp);							// 判断是否需要报警
    		
    		for(i=0;i<100;i++)						// 延时并进行按键扫描
    		{
    			KeyScanf();					
    			DelayMs(5);								
    		}
    	}
    }
    
    
    /*********************************************************/
    // 定时器0服务程序
    /*********************************************************/
    void Timer0(void) interrupt 1
    {
    	TH0  = 248;				// 给定时器0的TH0装初值
    	TL0  = 48;				// 给定时器0的TL0装初值
    
    	P0=0x00;					// 先关闭所有显示
    	w1=1;
    	w2=1;
    	w3=1;
    	w4=1;
    
    	if(ShowID==1)  			// 判断是否显示第1位数码管
    	{
    		w1=0;		   				// 打开第1位数码管的控制开关
    		P0=Buff[0];	   		// 第1位数码管显示内容	
    	}
    	
    	if(ShowID==2)  			// 判断是否显示第2位数码管
    	{
    		w2=0;		   				// 打开第2位数码管的控制开关
    		P0=Buff[1];	   		// 第2位数码管显示内容	
    	}
    	
    	if(ShowID==3)  			// 判断是否显示第3位数码管
    	{
    		w3=0;		   				// 打开第3位数码管的控制开关
    		P0=Buff[2];	   		// 第3位数码管显示内容	
    	}
    	
    	if(ShowID==4)  			// 判断是否显示第4位数码管
    	{
    		w4=0;		   				// 打开第4位数码管的控制开关
    		P0=Buff[3];	   		// 第4位数码管显示内容	
    	}	
    	
    	ShowID++;	  				// 切换到下一个数码管的显示
    	if(ShowID==5)
    		ShowID=1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408

    仿真演示视频:
    https://www.bilibili.com/video/BV1MG4y1p74C/

    实物演示视频:
    https://www.bilibili.com/video/BV1Cd4y1i7Ja/

  • 相关阅读:
    [每周一更]-(第23期):Docker 逻辑图及常用命令汇总
    MindSpore手写数字识别体验
    Java进阶(8)——抽象类与接口
    openAI发布基于ChatGPT的AI绘画模型DALL·E3,话说stable-diffusion还香吗?
    Ubuntu 22.04.6 | QEMU KVM 安装 macOS虚拟机
    在字节4年,一个27岁女软件测试工程师的心路历程
    每日刷题记录 (二十九)
    微信小程序开发(四) - 页面配置 - json 文件
    Jetson-AGX-Xavier OTA更新系统固件
    VIVADO的差分转单端IBUFDS的使用
  • 原文地址:https://blog.csdn.net/jimo167913/article/details/128056242