STM32温湿度达到设定值控制舵机和水泵打开的代码
时间: 2024-06-09 19:05:10 浏览: 134
以下是一个简单的示例代码,使用STM32的ADC模块读取温湿度传感器的值,当温度或湿度达到设定值时,控制舵机和水泵输出信号。
```c
#include "stm32f10x.h"
#define TEMP_SENSOR_PIN GPIO_Pin_0
#define HUMIDITY_SENSOR_PIN GPIO_Pin_1
#define SERVO_PIN GPIO_Pin_2
#define PUMP_PIN GPIO_Pin_3
#define TEMP_SETPOINT 25 // 温度设定值
#define HUMIDITY_SETPOINT 60 // 湿度设定值
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t adc_value_temp, adc_value_humidity;
void ADC_Configuration(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 设置ADC时钟频率为PCLK2的1/6
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1时钟
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 2; // 要转换的通道数
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 选择ADC1的通道0,采样时间为55.5个时钟周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // 选择ADC1的通道1,采样时间为55.5个时钟周期
ADC_Cmd(ADC1, ENABLE); // 使能ADC1
ADC_ResetCalibration(ADC1); // 复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); // 等待校准寄存器复位完成
ADC_StartCalibration(ADC1); // 开始校准
while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成
}
void GPIO_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = TEMP_SENSOR_PIN | HUMIDITY_SENSOR_PIN; // 温湿度传感器的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SERVO_PIN | PUMP_PIN; // 舵机和水泵的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟
TIM_TimeBaseStructure.TIM_Period = 20000; // PWM周期为20ms
TIM_TimeBaseStructure.TIM_Prescaler = 72-1; // 定时器预分频为72-1
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // PWM占空比为7.5%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure); // 配置TIM2的通道1为PWM输出模式
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_OC2Init(TIM2, &TIM_OCInitStructure); // 配置TIM2的通道2为PWM输出模式
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
}
void delay_ms(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++) {
for (volatile uint32_t j = 0; j < 2000; j++);
}
}
int main(void)
{
ADC_Configuration();
GPIO_Configuration();
TIM_Configuration();
while (1) {
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 开始ADC转换
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换完成
adc_value_temp = ADC_GetConversionValue(ADC1); // 读取温度传感器的ADC值
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 开始ADC转换
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换完成
adc_value_humidity = ADC_GetConversionValue(ADC1); // 读取湿度传感器的ADC值
float temp = adc_value_temp * 3.3 / 4095 * 100 - 50; // 转换为温度值
float humidity = adc_value_humidity * 3.3 / 4095 * 100; // 转换为湿度值
if (temp > TEMP_SETPOINT) { // 如果温度超过设定值
TIM_SetCompare1(TIM2, 2000); // 舵机转到最大角度
GPIO_SetBits(GPIOA, PUMP_PIN); // 打开水泵
} else {
TIM_SetCompare1(TIM2, 1000); // 舵机转到中间位置
GPIO_ResetBits(GPIOA, PUMP_PIN); // 关闭水泵
}
if (humidity > HUMIDITY_SETPOINT) { // 如果湿度超过设定值
TIM_SetCompare2(TIM2, 2000); // 舵机转到最大角度
GPIO_SetBits(GPIOA, PUMP_PIN); // 打开水泵
} else {
TIM_SetCompare2(TIM2, 1000); // 舵机转到中间位置
GPIO_ResetBits(GPIOA, PUMP_PIN); // 关闭水泵
}
delay_ms(1000); // 延时1秒钟
}
}
```
注意:上述代码仅供参考,实际应用中需要根据具体的传感器和执行器进行修改。另外,舵机和水泵的控制需要根据具体的硬件连接方式进行配置。
阅读全文