以下是一个使用STM32制作智能窗口的详细代码案例。
一、硬件设计 首先,我们需要准备以下硬件组件:
- STM32开发板(例如STM32F103C8T6)
- 光敏电阻模块(用于检测光照强度)
- 温湿度传感器模块(用于检测室内温湿度)
- 舵机模块(用于控制窗帘的开关)
连接步骤如下:
- 将光敏电阻模块的OUT引脚连接到STM32开发板的ADC引脚。
- 将温湿度传感器模块的DATA引脚连接到STM32开发板的GPIO引脚。
- 将舵机模块的信号引脚连接到STM32开发板的PWM引脚。
二、软件开发
- 配置ADC模块 首先,我们需要配置ADC模块以读取光敏电阻模块的值。在STM32CubeIDE中,打开主函数所在的文件(一般是main.c),找到
HAL_ADC_MspInit
函数,并添加以下代码:
static void MX_ADC_Init(void)
{
// 配置GPIO引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0; // ADC引脚
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // 模拟输入模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上下拉电阻
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置ADC模块
ADC_HandleTypeDef hadc = {0};
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // ADC时钟预分频为PCLK/4
hadc.Init.Resolution = ADC_RESOLUTION_12B; // 12位转换精度
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
hadc.Init.ScanConvMode = DISABLE; // 禁用扫描模式
hadc.Init.ContinuousConvMode = ENABLE; // 连续转换模式
hadc.Init.NbrOfConversion = 1; // 转换个数为1
hadc.Init.DMAContinuousRequests = DISABLE; // 禁用DMA请求
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; // 转换完成标志位于转换序列的最后
HAL_ADC_Init(&hadc);
// 启动ADC模块
HAL_ADC_Start(&hadc);
}
- 读取光照强度 在主函数中添加以下代码,用于读取光敏电阻模块的值,并根据光照强度控制舵机控制窗帘的开关:
int main(void)
{
// 初始化硬件
HAL_Init();
SystemClock_Config();
MX_ADC_Init();
MX_GPIO_Init();
MX_TIM2_Init();
// 设置默认舵机角度为0度(窗帘关闭)
TIM2->CCR1 = 150; // 舵机对应的PWM值
while (1)
{
// 读取光敏电阻模块的值
uint16_t lightIntensity = HAL_ADC_GetValue(&hadc);
// 根据光照强度控制舵机
if (lightIntensity < 1000) { // 光照强度过低,打开窗帘
TIM2->CCR1 = 50; // 舵机对应的PWM值
} else { // 光照强度足够,关闭窗帘
TIM2->CCR1 = 150; // 舵机对应的PWM值
}
// 延时一段时间
HAL_Delay(1000);
}
}
- 配置温湿度传感器模块 首先,我们需要配置GPIO引脚以及I2C模块来与温湿度传感器进行通信。在STM32CubeIDE中,找到
HAL_I2C_MspInit
函数,并添加以下代码:
static void MX_I2C1_Init(void)
{
// 配置GPIO引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10; // I2C引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // 开漏输出
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉电阻
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速模式
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; // I2C1的复用功能
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置I2C模块
I2C_HandleTypeDef hi2c = {0};
hi2c.Instance = I2C1;
hi2c.Init.Mode = I2C_MODE_I2C; // I2C模式
hi2c.Init.OwnAddress1 = 0; // 本机地址(不使用)
hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // 7位地址模式
hi2c.Init.Timing = 0x00303D5B; // 根据传感器的要求来配置时序参数
hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // 禁用双地址模式
hi2c.Init.OwnAddress2 = 0; // 本机地址(不使用)
hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // 禁用总线广播
hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // 允许主机拉伸时钟信号
HAL_I2C_Init(&hi2c);
}
- 读取温湿度值 在主函数中添加以下代码,用于读取温湿度传感器模块的值,并根据温湿度值控制舵机控制窗帘的开关:
int main(void)
{
// 初始化硬件
HAL_Init();
SystemClock_Config();
MX_ADC_Init();
MX_I2C1_Init();
MX_TIM2_Init();
// 设置默认舵机角度为0度(窗帘关闭)
TIM2->CCR1 = 150; // 舵机对应的PWM值
while (1)
{
// 读取光敏电阻模块的值
uint16_t lightIntensity = HAL_ADC_GetValue(&hadc);
// 读取温湿度传感器模块的值
uint8_t humidity;
uint16_t temperature;
HAL_I2C_Mem_Read(&hi2c, 0x80, 0xE5, I2C_MEMADD_SIZE_8BIT, &humidity, 1, HAL_MAX_DELAY); // 读取湿度值
HAL_Delay(50);
HAL_I2C_Mem_Read(&hi2c, 0x80, 0xE3, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&temperature, 2, HAL_MAX_DELAY); // 读取温度值
temperature = (temperature * 175.72 / 65536) - 46.85; // 转换为实际温度值
// 根据光照强度和温湿度控制舵机
if (lightIntensity < 1000 || humidity > 70 || temperature > 28) { // 光照强度过低或湿度高或温度高,打开窗帘
TIM2->CCR1 = 50; // 舵机对应的PWM值
} else { // 光照强度足够且湿度、温度正常,关闭窗帘
TIM2->CCR1 = 150; // 舵机对应的PWM值
}
// 延时一段时间
HAL_Delay(1000);
}
}
至此,我们完成了一个简单的智能窗口系统的代码案例。上述