基于STM32单片机DS18B20温度监控报警proteus仿真设计

基于STM32单片机DS18B20温度监控报警仿真设计

(Proteus仿真+程序+原理图+pcb)

Proteus仿真版本:proteus 8.9

原理图:Altium Designer

程序编译器:keil 5

编程语言:C语言

设计编号:C0054

功能要求

运用所学知识,完成基于STM32的温控系统设计。基本功能包括

  1. LCD1602屏幕显示当前温度及上限阈值;

  2. 当温度超过上限值时LED红灯亮,蜂鸣器报警,风扇开始转动;

  3. 可通过按键调节温度上限阈值;

  4. 温度过高时启动继电器控制的风扇,实现自动保护。

注意:

本设计是proteus仿真设计,并未做实物验证,意味着不确定源程序和原理图是否能在实物上正常使用,可能有BUG,故原理图及PCB仅供参考。

仿真图

开始仿真:LCD屏显示实时温度和检测值,同时工作指示灯点亮。
在这里插入图片描述

实时温度大于监测值,马达转动,红灯亮起,蜂鸣器报警。
在这里插入图片描述

原理图

注意,此原理图由仿真图绘制而来,没做实物验证,仅供参考

PCB

注意,此PCB图由仿真图绘制而来,没做实物验证,仅供参考

源程序

img

main函数

int main(void)
{
	short temperature = 0;

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
	delay_init(10);               		//初始化定时器
  TIM3_Init(2400-1, 72-1); // 10ms
	
	Key_Init();
	JDQ_Init();
	LCD_Init();

	LCD_write_string(0, 0, "Temp Value:");
	LCD_write_string(0, 1, "Temp High :");

  while(1)
  {
		do
		{
			DS18B20_Init();
			HAL_Delay(100);		
			temperature = DS18B20_Get_Temp();
			HAL_Delay(200);		
		}
		while(temperature == 0 || temperature > 999 || temperature == 850);
		temp_table[0] = temperature % 1000 / 100 + 0x30;
		temp_table[1] = temperature % 100 / 10 + 0x30;
		temp_table[2] = '.';
		temp_table[3] = temperature % 10 + 0x30;
		
		limt_table[0] = temp_max / 10 + 0x30;
		limt_table[1] = temp_max % 10 + 0x30;

		LCD_write_string(12, 0, (char*)temp_table);
		LCD_write_string(12, 1, (char*)limt_table);

  }
}

DS18B20驱动程序

#include "ds18b20.h"
#include "delay.h"


//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT();   //设置为输出
	DS18B20_DQ_OUT(0);  	//拉低DQ
	delay_us(740);      //拉低750us
	DS18B20_DQ_OUT(1);  	//DQ=1 
	delay_us(15);       //15US
}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_Check(void) 	   
{   
	uint8_t retry = 0;
	
	DS18B20_IO_IN();    //设置为输入 
	
  while (DS18B20_DQ_IN&&retry < 200)
	{
		retry ++;
		delay_us(2);
	};	 
	if(retry >= 200)
		return 1;
	else 
		retry = 0;
	
  while (!DS18B20_DQ_IN&&retry < 240)
	{
		retry++;
		delay_us(2);
	};
	if(retry>=240)
		return 1;	
	
	return 0;
}

//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) 
{
	uint8_t data = 0;
	
	DS18B20_IO_OUT();   //设置为输出
	DS18B20_DQ_OUT(0); 
	delay_us(2);
	
	DS18B20_DQ_OUT(1); 
	DS18B20_IO_IN();    //设置为输入
	delay_us(13);
	
	if(DS18B20_DQ_IN)
		data=1;
	else 
		data=0;
	
	delay_us(50);
	
	return data;
}

//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)   
{        
	uint8_t i, j = 0, dat = 0;
		
	for (i=1;i<=8;i++) 
	{
		j=DS18B20_Read_Bit();
		dat=(j<<7)|(dat>>1);
  }						    
	return dat;
}

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
{             
	uint8_t j;
	uint8_t testb = 0;
 
	DS18B20_IO_OUT();     //设置为输出
 
	for (j=1;j<=8;j++) 
	{
		testb = dat&0x01;
		dat = dat>>1;
		if(testb)       // 写1
		{
			DS18B20_DQ_OUT(0);
			delay_us(2);                            
			DS18B20_DQ_OUT(1);
			delay_us(49);             
		}
		else            //写0
		{
			DS18B20_DQ_OUT(0);
			delay_us(49);             
			DS18B20_DQ_OUT(1);
			delay_us(2);                          
		}
	}
}
 
//开始温度转换
void DS18B20_Start(void)
{   						               
	DS18B20_Rst();	   
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);// skip rom
	DS18B20_Write_Byte(0x44);// convert
}

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
uint8_t DS18B20_Init(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	DS18B20_DATA_CLK();			//开启GPIOA时钟

	GPIO_Initure.Pin=DS18B20_DATA_PIN;           	//PA0
	GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
	GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
	GPIO_Initure.Speed=GPIO_SPEED_FREQ_LOW;//高速
	HAL_GPIO_Init(DS18B20_DATA_PORT,&GPIO_Initure);     //初始化
 
	DS18B20_Rst();
	return DS18B20_Check();
}

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
	uint8_t temp = 0;
	uint8_t TL = 0,TH = 0;
	short tem = 0;

	DS18B20_Start ();           //开始转换
	DS18B20_Rst();
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);   // skip rom
	DS18B20_Write_Byte(0xbe);   // convert	    
	TL=DS18B20_Read_Byte();     // LSB   
	TH=DS18B20_Read_Byte();     // MSB  
	
	if(TH > 7)
	{
			TH = ~TH;
			TL = ~TL; 
			temp = 0;//温度为负  
	}
	else 
		temp = 1;//温度为正	
	
	tem = TH; //获得高八位
	tem <<= 8;    
	tem += TL;//获得底八位
	tem=(double)tem*0.625;//转换  
	
	if(temp)
		return tem; //返回温度值
	else 
		return -tem;    
}
 

LCD1602显示函数

#include "lcd1602.h"
                             
#define DELAY_2N     0

void lcd_delay_us(unsigned int t)
{
	unsigned int i, j;
	
	for(i = 10; i > 0; i--)
		for(j = t; j > 0; j--);
}

void lcd_delay_ms(unsigned int t)
{	
	unsigned int i;
	
	for(i = t; i > 0; i--)
		lcd_delay_us(10);
}

//==================================================
void LCD_Init(void)
{
		GPIO_InitTypeDef GPIO_Initure;   

		LCD_CTRL_CLK();
		LCD_DATA_CLK();
		
		GPIO_Initure.Pin = LCD_RS_PIN|LCD_RW_PIN|LCD_EN_PIN; 				
		GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  	
		GPIO_Initure.Pull = GPIO_PULLUP;          
		GPIO_Initure.Speed = GPIO_SPEED_FREQ_MEDIUM;   
		HAL_GPIO_Init(LCD_CTRL_PORT, &GPIO_Initure);

		GPIO_Initure.Pin = LCD_DATA0_PIN|LCD_DATA1_PIN|LCD_DATA2_PIN|LCD_DATA3_PIN|LCD_DATA4_PIN|LCD_DATA5_PIN|LCD_DATA6_PIN|LCD_DATA7_PIN; 				
		HAL_GPIO_Init(LCD_DATA_PORT, &GPIO_Initure);
	

    LCD_RW(0);			//读写位直接低电平,只写不读

    /*********************液晶初始化**************************/        
    lcd_delay_us(340); 
		LCD_RS(0);
   
    LCD_write_cmd(0x38);          // 8bit显示模式,2行,5x7字体
    lcd_delay_ms(4);  
    LCD_write_cmd(0x08);         // 显示关闭 
    lcd_delay_ms(4); 
    LCD_write_cmd(0x01);         // 显示清屏 
    lcd_delay_ms(4); 
    LCD_write_cmd(0x06);         // 显示光标移动设置 
    lcd_delay_ms(4);
    LCD_write_cmd(0x0c);         // 显示开,光标开,光标闪烁
    lcd_delay_ms(4);
		LCD_write_cmd(0x01);         //清屏
		lcd_delay_ms(4);
}
/*--------------------------------------------------
函数说明:写命令到液晶


---------------------------------------------------*/
void LCD_write_cmd(unsigned char cmd)
{
    LCD_RS(0);
    LCD_Write_byte(cmd);
    lcd_delay_us(340);
}
/*--------------------------------------------------
函数说明:写数据到液晶


---------------------------------------------------*/
void LCD_write_data(unsigned char w_data)
{
    LCD_RS(1);
    LCD_Write_byte(w_data);
    lcd_delay_us(340);
}
/*--------------------------------------------------
函数说明:写4bit到液晶
--------------------------------------------------*/
void LCD_Write_byte(unsigned char num)
{  
		if (num&0x01)
				data0(1);
		else
				data0(0);

		if (num&0x02)
				data1(1);
		else
				data1(0);

		if (num&0x04)
				data2(1);
		else
				data2(0);

		if (num&0x08)
				data3(1);
		else
				data3(0);

		if (num&0x10)
				data4(1);
		else
				data4(0);

		if (num&0x20)
				data5(1);
		else
				data5(0);

		if (num&0x40)
				data6(1);
		else
				data6(0);
		
		if (num&0x80)
				data7(1);
		else
				data7(0);
		
		lcd_delay_us(340);
    LCD_EN(1);
    lcd_delay_us(340);
    LCD_EN(0); 
    lcd_delay_us(340);
}

/*----------------------------------------------------
LCD_set_xy        : 设置LCD显示的起始位置
输入参数:x、y    : 显示字符串的位置,X:0-15,Y:0-1                
-----------------------------------------------------*/
void LCD_set_xy( unsigned char x, unsigned char y )
{
    unsigned char address = 0;
    if (y==0) 
    {
        address=0x80+x;
    }
    else 
    {
        address=0xc0+x;
    }
//		y ? (address=0xc0+x): (address=0x80+x) ;
    LCD_write_cmd(address);
}
/*---------------------------------------------------
LCD_write_string  : 英文字符串显示函数
输入参数:*s      :英文字符串指针;
          X、Y    : 显示字符串的位置                
---------------------------------------------------*/
void LCD_write_string(unsigned char X,unsigned char Y, char *s)
{
    LCD_set_xy(X,Y);   
    while (*s) 
    {
        LCD_write_data(*s);
        s++;
    }
}

//=======================================================
void LCD_wstring(unsigned char X,unsigned char *s)
{
    LCD_write_cmd(X);   
    while (*s) 
    {
        LCD_write_data(*s);
        s++;
    }
}

开发资料

在这里插入图片描述
0.常见使用问题及解决方法–必读!!!!

  1. 程序源码
  2. Proteus仿真
  3. 原理图
  4. PCB
  5. 源文件截图
  6. 参考文档
  7. 讲解视频
    8.功能要求
    Altium Designer 软件资料
    DS18B20(中文).pdf
    KEIL软件资料
    Proteus软件资料
    单片机学习资料
    答辩技巧
    设计报告常用描述
    鼠标双击打开查找更多51 STM32单片机课程毕业设计.url

百度网盘下载链接

51单片机是一种常用的微控制器,具有广泛的应用领域。 DS18B20是一种数字温度传感器,具有高精度、数字输出、单总线接口等特点。Proteus是一种虚拟电路设计仿真软件,能够帮助我们验证电路的功能和性能。 要设计一个可调上下限的温度报警器,我们可以使用51单片机DS18B20传感器进行连接,并在Proteus中进行仿真。 首先,将DS18B20传感器的VCC引脚(3.3V或5V)、GND引脚(地)和DQ引脚(数字接口)分别连接到51单片机的对应引脚上。然后,在Proteus中导入51单片机的库文件,并绘制出相应的电路图。 接下来,我们可以使用51单片机的GPIO口读取DS18B20传感器的温度数据,并将其与预设的上下限进行比较。如果温度超过设定的上限或低于设定的下限,可以设置51单片机的某个引脚输出高电平,触发报警器。 为了实现可调的上下限,我们可以通过外部电位器或软件编程的方式,来调节报警器的温度阈值。可以选择将电位器与51单片机的某个模拟输入引脚相连,通过读取电位器的电阻值来调节阈值。或者在程序中通过用户界面,设置上下限的数值并存储在非易失性存储器中。 最后,我们可以在Proteus中进行仿真测试,输入不同的温度值,观察51单片机的输出状态和报警器是否正常工作。 通过以上步骤,我们可以在Proteus设计一个可调上下限的51单片机DS18B20温度报警器,实现温度监测和报警的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BT-BOX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值