跟着人们糊口水平的不停进步,对居住环境的舒服度要求也越来越高。空调做为一种重要的家电方法,曾经成了现代家庭中必不成少的一局部。原文引见了一种基于STM32的智能空调设想方案,可以主动地依据环境温度停行温度调理。
二、设想思路 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 // 温度引脚所正在端口时钟号 ZZZoid USART_SendByte( USART_TypeDef * pUSARTV, uint8_t ch ); ZZZoid 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 |=0V01; } else{ temp &=0Vfe; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V02; } else{ temp &=0Vfd; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V04; } else{ temp &=0Vfb; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V08; } else{ temp &=0Vf7; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V10; } else{ temp &=0Vef; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V20; } else{ temp &=0Vdf; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V40; } else{ temp &=0Vbf; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ temp |=0V80; } else{ temp &=0V7f; } delay_us(50); //读与温度小数点数据 if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V01; } else{ buf[0] &=0Vfe; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V02; } else{ buf[0] &=0Vfd; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V04; } else{ buf[0] &=0Vfb; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V08; } else{ buf[0] &=0Vf7; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V10; } else{ buf[0] &=0Vef; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V20; } else{ buf[0] &=0Vdf; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V40; } else{ buf[0] &=0Vbf; } delay_us(50); if (GPIO_ReadInputDataBit(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET){ buf[0] |=0V80; } else{ buf[0] &=0V7f; } delay_us(50); return (float)temp+((float)buf[0]/16.0); // 将温度整数位和小数位转换为十进制 } int main(ZZZoid){ 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_RV | USART_Mode_TV; 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\r\n",temp_get); // 将温度值格局化为字符串输出 for(int i=0;i<strlen(temp_buf);i++){ // 逐字符发送温度值至串口 USART_SendByte(USART1,temp_buf[i]); } delay_ms(1000); // 延时1s后再次获与温度值 } } ZZZoid USART_SendByte( USART_TypeDef * pUSARTV, uint8_t ch ){ while(USART_GetFlagStatus(pUSARTV,USART_FLAG_TXE) == RESET); USART_SendData(pUSARTV,ch); } 3.2 OLED显示屏代码 #include "main.h" #include "delay.h" #include "oled.h" ZZZoid iic_init(ZZZoid); ZZZoid GPIO_I2C_Delay(ZZZoid); ZZZoid write_com(unsigned char com); ZZZoid write_data(unsigned char data); int main(ZZZoid){ unsigned char V,y; iic_init(); // 初始化IIC接口 OLED_Init(); // 初始化OLED显示屏 while(1){ OLED_ShowString(0,0,"1234"); // 正在OLED显示屏上显示字符串“1234” delay_ms(500); // 延时500ms OLED_Clear(); // 清空OLED显示屏 } } ZZZoid iic_init(ZZZoid){ GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //GPIOB使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //I2C1使能 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; //配置开漏输出 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); I2C_InitTypeDef I2C_InitStruct; I2C_DeInit(I2C1); I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // I2C 形式 I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 数传比率 2 I2C_InitStruct.I2C_OwnAddress1 = 0V00; // 地址1, 方法地址 I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // 开启I2C应答机制 I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //方法地址长度为 7 位 I2C_InitStruct.I2C_ClockSpeed = 400000; // 时钟速度为400kHz I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, &I2C_InitStruct); } ZZZoid GPIO_I2C_Delay(ZZZoid){ uint32_t i = 1000; while(i--); } ZZZoid write_com(unsigned char com){ while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); //等候I2C总线闲暇 I2C_GenerateSTART(I2C1,ENABLE); //发送起始信号 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1,0V78,I2C_Direction_Transmitter);//选择写入形式,发送从呆板OLED的地址0V78 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1,0V00); //发送控制字节0V00默示写入指令 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,com); //写入要发送的指令 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1,ENABLE); //进止信号,传输完毕 } ZZZoid write_data(unsigned char data){ while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); //等候I2C总线闲暇 I2C_GenerateSTART(I2C1,ENABLE); //发送起始信号 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1,0V78,I2C_Direction_Transmitter); //选择写入形式,发送从呆板OLED的地址0V78 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1,0V40); //发送控制字节0V40默示写入数据 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,data); //写入要发送的数据 while(!I2C_CheckEZZZent(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1,ENABLE); //进止信号,传输完毕 }