基于STM32设计的智能空调

2024-01-17  

一、项目背景

随着人们生活水平的不断提高,对居住环境的舒适度要求也越来越高。空调作为一种重要的家电设备,已经成为了现代家庭中必不可少的一部分。本文介绍了一种基于STM32的智能空调设计方案,可以自动地根据环境温度进行温度调节。


image-20230618181209765

image-20230618181649941

二、设计思路

2.1 整体构架

智能空调系统由温度检测传感器、微控制器、OLED显示屏、按键及直流电源等组件构成。传感器用于检测环境温度,通过微控制器进行处理后,将结果输出到OLED显示屏上展示。按键可根据需求调整预设阀值,切换模式等操作。


2.2 硬件设计

(1)温度检测传感器


选择DS18B20数字温度传感器作为本系统的温度检测器件。该传感器具有精度高,响应速度快等特点,可以满足该系统的检测需求。


(2)微控制器


使用STM32F103系列的微控制器,在该控制器活跃的生态环境下,以及其先进的处理能力,可以对信号进行快速采集、处理和控制。


(3)OLED显示屏


本系统使用的是一块128 * 64 OLED显示屏,显示屏具有高亮度、高对比度和低功耗等优点,易于与STM32微控制器进行通信。


2.3 软件设计

在软件设计方面,实现了温度检测传感器数据的采集,使用处理算法对数据进行处理,根据预设阀值自动调节温度,同时可以根据用户需求,切换制冷、制热和关闭等3种模式。最后,将结果通过OLED显示屏进行输出。


三、代码设计

3.1 DS18B20温度检测代码

#include "main.h"

 #include "delay.h"

 

 #define GPIO_PORT_TEMP     GPIOA        //温度数据引脚所在的端口

 #define GPIO_PIN_TEMP      GPIO_Pin_0   //温度数据引脚所在的引脚编号

 

 #define RCC_PORT_TEMPP     RCC_APB2Periph_GPIOA  // 温度引脚所在端口时钟号

 

 void USART_SendByte( USART_TypeDef * pUSARTx, uint8_t ch );

 

 void delay_us(uint32_t us){     // 延时us微秒函数

     uint8_t i;

     for(i=0;i< us;i++){

         asm("nop");  

     }

 }

 

 float get_temp(){   // 获取温度函数

     uint16_t temp;

     uint8_t buf[2];

 

     GPIO_InitTypeDef GPIO_InitStruct;

     TIM_TimeBaseInitTypeDef TIM_InitStruct;

 

     RCC_APB2PeriphClockCmd(RCC_PORT_TEMPP,ENABLE);

 

     //DATA拉低480us复位

     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

     GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP;        

     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_Init(GPIO_PORT_TEMP , &GPIO_InitStruct);    

     GPIO_ResetBits(GPIO_PORT_TEMP , GPIO_PIN_TEMP ); 

     delay_us(500);                                  

     GPIO_SetBits(GPIO_PORT_TEMP , GPIO_PIN_TEMP );   

     delay_us(60);                                   

 

     //查询DS18B20是否存在

     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;        

     GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP;         

     GPIO_Init(GPIO_PORT_TEMP , &GPIO_InitStruct);    

     while (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET);     

 

     //通信开始

     GPIO_ResetBits(GPIO_PORT_TEMP , GPIO_PIN_TEMP );  

     delay_us(480);                                  

     GPIO_SetBits(GPIO_PORT_TEMP , GPIO_PIN_TEMP );    

     delay_us(60);                                   

 

     //读取温度数据

     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;        

     GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP ;        

     GPIO_Init(GPIO_PORT_TEMP , &GPIO_InitStruct);

     delay_us(10);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x01;

     }

     else{

         temp &=0xfe;

     } 

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x02;

     }

     else{

         temp &=0xfd;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x04;

     }

     else{

         temp &=0xfb;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x08;

     }

     else{

         temp &=0xf7;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x10;

     }

     else{

         temp &=0xef;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x20;

     }

     else{

         temp &=0xdf;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x40;

     }

     else{

         temp &=0xbf;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         temp |=0x80;

     }

     else{

         temp &=0x7f;

     }

     delay_us(50);

 

     //读取温度小数点数据

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x01;

     }

     else{

         buf[0] &=0xfe;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x02;

     }

     else{

         buf[0] &=0xfd;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x04;

     }

     else{

         buf[0] &=0xfb;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x08;

     }

     else{

         buf[0] &=0xf7;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x10;

     }

     else{

         buf[0] &=0xef;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x20;

     }

     else{

         buf[0] &=0xdf;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x40;

     }

     else{

         buf[0] &=0xbf;

     }

     delay_us(50);

     if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){

         buf[0] |=0x80;

     }

     else{

         buf[0] &=0x7f;

     }

     delay_us(50);

 

     return (float)temp+((float)buf[0]/16.0);   // 将温度整数位和小数位转换为十进制

 }

 

 int main(void){

 

     char temp_buf[20];  // 接收温度值的临时缓冲区

 

     USART_InitTypeDef USART_InitStruct;

 

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);   

 

     USART_InitStruct.USART_BaudRate = 115200;

     USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

     USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

     USART_InitStruct.USART_Parity = USART_Parity_No;

     USART_InitStruct.USART_StopBits = USART_StopBits_1;

     USART_InitStruct.USART_WordLength = USART_WordLength_8b;

     USART_Init(USART1,&USART_InitStruct);

 

     USART_Cmd(USART1,ENABLE);

 

     while(1){

         float temp_get=get_temp();  // 获取当前温度值

         sprintf(temp_buf,"temp:%0.1f

",temp_get);  // 将温度值格式化为字符串输出

         for(int i=0;i< strlen(temp_buf);i++){  // 逐字符发送温度值至串口

             USART_SendByte(USART1,temp_buf[i]); 

         }

         delay_ms(1000);  // 延时1s后再次获取温度值

     }

 }

 

 void USART_SendByte( USART_TypeDef * pUSARTx, uint8_t ch ){

     while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);     

     USART_SendData(pUSARTx,ch);

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。