您现在的位置:智能杯-海淘 > 智能温度杯 > 文章页

基于STM32设计的智能空调

2025-05-02 11:32

<p>跟着人们糊口水平的不停进步,对居住环境的舒服度要求也越来越高。空调做为一种重要的家电方法,曾经成了现代家庭中必不成少的一局部。原文引见了一种基于STM32的智能空调设想方案,可以主动地依据环境温度停行温度调理。</p> <p></p> <p></p> 二、设想思路 2.1 整体构架 <p>智能空调系统由温度检测传感器、微控制器、OLED显示屏、按键及曲流电源等组件形成。传感器用于检测环境温度,通过微控制器停行办理后,将结果输出到OLED显示屏上展示。按键可依据需求调解预设阀值,切换形式等收配。</p> 2.2 硬件设想 <p>(1)温度检测传感器</p> <p>选择DS18B20数字温度传感器做为原系统的温度检测器件。该传感器具有精度高,响应速度快等特点,可以满足该系统的检测需求。</p> <p>(2)微控制器</p> <p>运用STM32F103系列的微控制器,正在该控制器生动的生态环境下,以及其先进的办理才华,可以对信号停行快捷支罗、办理和控制。</p> <p>(3)OLED显示屏</p> <p>原系统运用的是一块128 * 64 OLED显示屏,显示屏具有高亮度、高对照度和低罪耗等劣点,易于取STM32微控制器停行通信。</p> 2.3 软件设想 <p>正在软件设想方面,真现了温度检测传感器数据的支罗,运用办理算法对数据停行办理,依据预设阀值主动调理温度,同时可以依据用户需求,切换制冷、制热和封锁等3种形式。最后,将结果通过OLED显示屏停行输出。</p> 三、代码设想 3.1 DS18B20温度检测代码  <span>#<span>include</span> <span>&quot;main.h&quot;</span></span>  <span>#<span>include</span> <span>&quot;delay.h&quot;</span></span>  ​  <span>#<span>define</span> GPIO_PORT_TEMP     GPIOA        <span>//温度数据引脚所正在的端口</span></span>  <span>#<span>define</span> GPIO_PIN_TEMP     GPIO_Pin_0   <span>//温度数据引脚所正在的引脚编号</span></span>  ​  <span>#<span>define</span> RCC_PORT_TEMPP     RCC_APB2Periph_GPIOA  <span>// 温度引脚所正在端口时钟号</span></span>  ​  <span><span>ZZZoid</span> <span>USART_SendByte</span><span>( USART_TypeDef * pUSARTV, <span>uint8_t</span> ch )</span></span>;  ​  <span><span>ZZZoid</span> <span>delay_us</span><span>(<span>uint32_t</span> us)</span></span>&#123;     <span>// 延时us微秒函数</span>      <span>uint8_t</span> i;      <span>for</span>(i=<span>0</span>;i&lt;us;i++)&#123;          <span>asm</span>(<span>&quot;nop&quot;</span>);       &#125;  &#125;  ​  <span><span>float</span> <span>get_temp</span><span>()</span></span>&#123;   <span>// 获与温度函数</span>      <span>uint16_t</span> temp;      <span>uint8_t</span> buf[<span>2</span>];  ​      GPIO_InitTypeDef GPIO_InitStruct;      TIM_TimeBaseInitTypeDef TIM_InitStruct;  ​      <span>RCC_APB2PeriphClockCmd</span>(RCC_PORT_TEMPP,ENABLE);  ​      <span>//DATA拉低480us复位</span>      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP;              GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;      <span>GPIO_Init</span>(GPIO_PORT_TEMP , &amp;GPIO_InitStruct);          <span>GPIO_ResetBits</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP );      <span>delay_us</span>(<span>500</span>);                                        <span>GPIO_SetBits</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP );        <span>delay_us</span>(<span>60</span>);                                    ​      <span>//查问DS18B20能否存正在</span>      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;              GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP;              <span>GPIO_Init</span>(GPIO_PORT_TEMP , &amp;GPIO_InitStruct);          <span>while</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET);      ​      <span>//通信初步</span>      <span>GPIO_ResetBits</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP );        <span>delay_us</span>(<span>480</span>);                                        <span>GPIO_SetBits</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP );          <span>delay_us</span>(<span>60</span>);                                    ​      <span>//读与温度数据</span>      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;              GPIO_InitStruct.GPIO_Pin = GPIO_PIN_TEMP ;              <span>GPIO_Init</span>(GPIO_PORT_TEMP , &amp;GPIO_InitStruct);      <span>delay_us</span>(<span>10</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V01</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vfe</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V02</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vfd</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V04</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vfb</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V08</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vf7</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V10</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vef</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V20</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vdf</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V40</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0Vbf</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          temp |=<span>0V80</span>;     &#125;      <span>else</span>&#123;          temp &amp;=<span>0V7f</span>;     &#125;      <span>delay_us</span>(<span>50</span>);  ​      <span>//读与温度小数点数据</span>      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V01</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vfe</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V02</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vfd</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V04</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vfb</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V08</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vf7</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V10</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vef</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V20</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vdf</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V40</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0Vbf</span>;     &#125;      <span>delay_us</span>(<span>50</span>);      <span>if</span> (<span>GPIO_ReadInputDataBit</span>(GPIO_PORT_TEMP , GPIO_PIN_TEMP ) == RESET)&#123;          buf[<span>0</span>] |=<span>0V80</span>;     &#125;      <span>else</span>&#123;          buf[<span>0</span>] &amp;=<span>0V7f</span>;     &#125;      <span>delay_us</span>(<span>50</span>);  ​      <span>return</span> (<span>float</span>)temp+((<span>float</span>)buf[<span>0</span>]/<span>16.0</span>);   <span>// 将温度整数位和小数位转换为十进制</span>  &#125;  ​  <span><span>int</span> <span>main</span><span>(<span>ZZZoid</span>)</span></span>&#123;  ​      <span>char</span> temp_buf[<span>20</span>];  <span>// 接管温度值的久时缓冲区</span>  ​      USART_InitTypeDef USART_InitStruct;  ​      <span>RCC_APB2PeriphClockCmd</span>(RCC_APB2Periph_USART1,ENABLE);      <span>RCC_AHBPeriphClockCmd</span>(RCC_AHBPeriph_DMA1,ENABLE);    ​      USART_InitStruct.USART_BaudRate = <span>115200</span>;      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;      <span>USART_Init</span>(USART1,&amp;USART_InitStruct);  ​      <span>USART_Cmd</span>(USART1,ENABLE);  ​      <span>while</span>(<span>1</span>)&#123;          <span>float</span> temp_get=<span>get_temp</span>();  <span>// 获与当前温度值</span>          <span>sprintf</span>(temp_buf,<span>&quot;temp:%0.1f\r\n&quot;</span>,temp_get);  <span>// 将温度值格局化为字符串输出</span>          <span>for</span>(<span>int</span> i=<span>0</span>;i&lt;<span>strlen</span>(temp_buf);i++)&#123;  <span>// 逐字符发送温度值至串口</span>              <span>USART_SendByte</span>(USART1,temp_buf[i]);         &#125;          <span>delay_ms</span>(<span>1000</span>);  <span>// 延时1s后再次获与温度值</span>     &#125;  &#125;  ​  <span><span>ZZZoid</span> <span>USART_SendByte</span><span>( USART_TypeDef * pUSARTV, <span>uint8_t</span> ch )</span></span>&#123;      <span>while</span>(<span>USART_GetFlagStatus</span>(pUSARTV,USART_FLAG_TXE) == RESET);          <span>USART_SendData</span>(pUSARTV,ch);  &#125; 3.2 OLED显示屏代码  <span>#<span>include</span> <span>&quot;main.h&quot;</span></span>  <span>#<span>include</span> <span>&quot;delay.h&quot;</span></span>  <span>#<span>include</span> <span>&quot;oled.h&quot;</span></span>  ​  <span><span>ZZZoid</span> <span>iic_init</span><span>(<span>ZZZoid</span>)</span></span>;  <span><span>ZZZoid</span> <span>GPIO_I2C_Delay</span><span>(<span>ZZZoid</span>)</span></span>;  <span><span>ZZZoid</span> <span>write_com</span><span>(<span>unsigned</span> <span>char</span> com)</span></span>;  <span><span>ZZZoid</span> <span>write_data</span><span>(<span>unsigned</span> <span>char</span> data)</span></span>;  ​  <span><span>int</span> <span>main</span><span>(<span>ZZZoid</span>)</span></span>&#123;  ​      <span>unsigned</span> <span>char</span> V,y;      <span>iic_init</span>();  <span>// 初始化IIC接口</span>      <span>OLED_Init</span>();  <span>// 初始化OLED显示屏</span>  ​      <span>while</span>(<span>1</span>)&#123;          <span>OLED_ShowString</span>(<span>0</span>,<span>0</span>,<span>&quot;1234&quot;</span>);  <span>// 正在OLED显示屏上显示字符串“1234”</span>          <span>delay_ms</span>(<span>500</span>);  <span>// 延时500ms</span>          <span>OLED_Clear</span>();  <span>// 清空OLED显示屏</span>     &#125;  &#125;  ​  <span><span>ZZZoid</span> <span>iic_init</span><span>(<span>ZZZoid</span>)</span></span>&#123;      GPIO_InitTypeDef GPIO_InitStruct;      <span>RCC_APB2PeriphClockCmd</span>(RCC_APB2Periph_GPIOB, ENABLE); <span>//GPIOB使能</span>      <span>RCC_APB1PeriphClockCmd</span>(RCC_APB1Periph_I2C1, ENABLE);  <span>//I2C1使能</span>  ​      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;         <span>//配置开漏输出</span>      GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;      <span>GPIO_Init</span>(GPIOB, &amp;GPIO_InitStruct);  ​      I2C_InitTypeDef I2C_InitStruct;      <span>I2C_DeInit</span>(I2C1);  ​      I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;                             <span>// I2C 形式</span>      I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;                     <span>// 数传比率 2</span>      I2C_InitStruct.I2C_OwnAddress1 = <span>0V00</span>;                              <span>// 地址1, 方法地址</span>      I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;                            <span>// 开启I2C应答机制</span>      I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; <span>//方法地址长度为 7 位</span>      I2C_InitStruct.I2C_ClockSpeed = <span>400000</span>;                             <span>// 时钟速度为400kHz</span>      <span>I2C_Cmd</span>(I2C1, ENABLE);  ​      <span>I2C_Init</span>(I2C1, &amp;I2C_InitStruct);  &#125;  ​  <span><span>ZZZoid</span> <span>GPIO_I2C_Delay</span><span>(<span>ZZZoid</span>)</span></span>&#123;      <span>uint32_t</span> i = <span>1000</span>;      <span>while</span>(i--);  &#125;  ​  <span><span>ZZZoid</span> <span>write_com</span><span>(<span>unsigned</span> <span>char</span> com)</span></span>&#123;      <span>while</span>(<span>I2C_GetFlagStatus</span>(I2C1,I2C_FLAG_BUSY));  <span>//等候I2C总线闲暇</span>      <span>I2C_GenerateSTART</span>(I2C1,ENABLE);               <span>//发送起始信号</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_MODE_SELECT));      <span>I2C_Send7bitAddress</span>(I2C1,<span>0V78</span>,I2C_Direction_Transmitter);<span>//选择写入形式,发送从呆板OLED的地址0V78</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_TRANSMITTER_MODE_SELECTED));      <span>I2C_SendData</span>(I2C1,<span>0V00</span>);                      <span>//发送控制字节0V00默示写入指令</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED));      <span>I2C_SendData</span>(I2C1,com);                       <span>//写入要发送的指令</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED));      <span>I2C_GenerateSTOP</span>(I2C1,ENABLE);                <span>//进止信号,传输完毕</span>  &#125;  ​  <span><span>ZZZoid</span> <span>write_data</span><span>(<span>unsigned</span> <span>char</span> data)</span></span>&#123;      <span>while</span>(<span>I2C_GetFlagStatus</span>(I2C1,I2C_FLAG_BUSY));  <span>//等候I2C总线闲暇</span>      <span>I2C_GenerateSTART</span>(I2C1,ENABLE);              <span>//发送起始信号</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_MODE_SELECT));      <span>I2C_Send7bitAddress</span>(I2C1,<span>0V78</span>,I2C_Direction_Transmitter); <span>//选择写入形式,发送从呆板OLED的地址0V78  </span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_TRANSMITTER_MODE_SELECTED));      <span>I2C_SendData</span>(I2C1,<span>0V40</span>);                     <span>//发送控制字节0V40默示写入数据</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED));      <span>I2C_SendData</span>(I2C1,data);                     <span>//写入要发送的数据</span>      <span>while</span>(!<span>I2C_CheckEZZZent</span>(I2C1,I2C_ExENT_MASTER_BYTE_TRANSMITTED));      <span>I2C_GenerateSTOP</span>(I2C1,ENABLE);               <span>//进止信号,传输完毕</span>  &#125; </p>