首页 > 其他分享 >基于STM32设计的智能空调

基于STM32设计的智能空调

时间:2023-08-06 10:01:46浏览次数:33  
标签:void 空调 STM32 智能 OLED InitStruct GPIO I2C I2C1

一、项目背景

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

基于STM32设计的智能空调_智能空调系统

基于STM32设计的智能空调_智能空调系统_02

二、设计思路

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\r\n",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);
}

3.2 OLED显示屏代码

#include "main.h"
#include "delay.h"
#include "oled.h"

void iic_init(void);
void GPIO_I2C_Delay(void);
void write_com(unsigned char com);
void write_data(unsigned char data);

int main(void){

    unsigned char x,y;
    iic_init();  // 初始化IIC接口
    OLED_Init();  // 初始化OLED显示屏

    while(1){
        OLED_ShowString(0,0,"1234");  // 在OLED显示屏上显示字符串“1234”
        delay_ms(500);  // 延时500ms
        OLED_Clear();  // 清空OLED显示屏
    }
}

void iic_init(void){
    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 = 0x00;                              // 地址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);
}

void GPIO_I2C_Delay(void){
    uint32_t i = 1000;
    while(i--);
}

void write_com(unsigned char com){
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //等待I2C总线空闲
    I2C_GenerateSTART(I2C1,ENABLE);               //发送起始信号
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(I2C1,0x78,I2C_Direction_Transmitter);//选择写入模式,发送从机器OLED的地址0x78
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    I2C_SendData(I2C1,0x00);                      //发送控制字节0x00表示写入指令
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,com);                       //写入要发送的指令
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_GenerateSTOP(I2C1,ENABLE);                //停止信号,传输结束
}

void write_data(unsigned char data){
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //等待I2C总线空闲
    I2C_GenerateSTART(I2C1,ENABLE);              //发送起始信号
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(I2C1,0x78,I2C_Direction_Transmitter); //选择写入模式,发送从机器OLED的地址0x78  
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    I2C_SendData(I2C1,0x40);                     //发送控制字节0x40表示写入数据
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,data);                     //写入要发送的数据
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_GenerateSTOP(I2C1,ENABLE);               //停止信号,传输结束
}


标签:void,空调,STM32,智能,OLED,InitStruct,GPIO,I2C,I2C1
From: https://blog.51cto.com/u_11822586/6981906

相关文章

  • stm32用keil5新建C/C++写硬件串口模块的套路
    新建文件:写代码:就在这里开始写initSerial了..........
  • 当没有STLINK的时候,用串口进行下载程序到stm32里操作步骤:
    https://www.bilibili.com/video/BV1th411z7sn?p=30&vd_source=791674f04f7270b40ba9c9d5a7e3281e前5min0、连接电路:1、打开软件:FlyMcu2、keil5导出.hex文件重新编译就出来了hex文件3、FlyMcu配置波特率等参数4、stm32跳冒切换+复位5、烧录6、stm32跳冒切换+复位......
  • 智慧工地管理平台源码,视频监控、劳务实名制、环境监测、安全质量管理、GIS地理信息、
    智慧工地可视化系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术,通过工地中台、三维建模服务、视频AI分析服务等技术支撑,实现智慧工地高精度动态仿真,趋势分析、预测、模拟,建设智能化、标准化的智慧工地综合业务系统,解决传统工地管理存在的弊端,更好的提高工地......
  • 什么是人工智能?
    当然!人工智能(AI)是计算机科学的一个领域,专注于创建能够执行通常需要人类智能的任务的机器。这些任务包括解决问题、学习、决策、语言理解、感知等。人工智能涉及人工大脑的开发,称为神经网络或算法,模仿人类大脑处理信息的方式。人工智能在市场上获得如此多的嗡嗡声的原因之一是它......
  • PLC、DCS、SCADA系统通过OPC智能网关与云平台实时通讯
    OPC作为一种工业控制领域常用的标准通信规约,如PLC、DCS、SCADA等工业自动化系统大多提供了基于OPC规约的数据访问接口,通过OPC智能网关即可采集自动化设备系统数据并将数据传输至云端,打通工业系统数据孤岛,实现数据的互联互通,利用云端大数据平台对数据进行智能化运营。物通博联推出的......
  • 基于工业互联网实现MES系统中的设备智能管理
    MES系统是制造业工厂常用的一种操作管理系统,通过对生产流程进行实时监控和管理控制,帮助企业更好的关注到生产进度、物料消耗、设备状态等信息,从而帮助优化生产工艺与提高效率,因此设备管理是MES系统重要的组成部分,可以实现设备实时监控、故障预警、控制管理等功能,从而提高设备的可靠......
  • openGauss —— 智能优化器之基数估计
    openGauss——智能优化器之基数估计现代数据库优化器主要依赖于其内部的代价估计系统,而代价估计最重要的依据就是查询算子的基数,即数据通过算子内查询条件过滤之后剩余的结果行数。因此基数估计技术是影响优化器产生的执行计划性能最关键的技术。学术界和工业界针对基数估计技术......
  • STM32F030C8T6 SPI 通讯问题排查分析
    配置及问题列举1.STM32F030C8T6:48M系统时钟配置;2.SPI1:驱动LCD,半工主机通讯,极性为高、边沿为2,时钟分频系数16分频;3.SPI2:驱动TDC-GP21,全工主机通讯,极性为低、边沿为2,时钟分频系数4分频;1.LCD驱动为上升沿,改为{极性为低、边沿为1},初始化却无效;2.TDC-GP21驱动为下降沿,读取I......
  • 【触想智能】工控一体机为什么需要定制?
    工控一体机在工业领域上的应用越来越广泛,在智能化生产车间、城市交通、自助服务终端、商业金融、医疗、安防、军事、政府单位等都可以看到它们的身影。工控一体机作为工业大数据触控中心,在工厂智能化数字转型中起着不可替代的作用。 由于工控一体机对应用环境要......
  • 智能助手——SlideSpeak服务介绍
    在现代职场和学术领域,PowerPoint(PPT)文稿常常扮演着重要的角色。然而,处理大量的PPT文件并从中获取有用的信息可能是一项繁琐的任务。现在,有了SlideSpeak服务,这一问题将变得更加轻松。SlideSpeak是一款开源的人工智能应用,专门为用户处理PowerPoint文件提供帮助。通过使用AI技术,SlideS......