用stm32f103,代码实现温湿度实时显示(表盘式/表盘+柱状) 温湿度采集,采样间隔2s(要求采用定时器中断产生) 同时显示温度和湿度表盘,刻度自行设置
时间: 2024-02-07 13:02:13 浏览: 62
好的,这里提供一份简单的代码来实现温湿度实时显示(表盘式/表盘+柱状)。
首先,需要使用DHT11或DHT22温湿度传感器,并将其连接到stm32f103的GPIO引脚上。这里我们假设连接到PA0引脚上。
然后,需要使用定时器来实现定时采集温湿度数据。这里我们使用TIM2定时器,设置为2s中断一次。
接下来,需要使用LCD显示屏(或OLED显示屏)来实现温湿度的显示。这里我们假设使用LCD1602显示屏,使用4位并行接口,连接到PB0-PB3引脚上。
最后,需要使用ADC模块来实现温度和湿度的转换,这里我们假设使用内部温度传感器和Vref电压参考来实现。
下面是完整的代码:
```c
#include "stm32f10x.h"
#include "lcd1602.h"
#include "dht11.h"
#define DHT11_PIN GPIO_Pin_0
#define DHT11_PORT GPIOA
#define LCD_PORT GPIOB
#define LCD_RS GPIO_Pin_0
#define LCD_RW GPIO_Pin_1
#define LCD_EN GPIO_Pin_2
#define LCD_D4 GPIO_Pin_3
#define LCD_D5 GPIO_Pin_4
#define LCD_D6 GPIO_Pin_5
#define LCD_D7 GPIO_Pin_6
#define ADC_TEMP_CHANNEL ADC_Channel_16
#define ADC_VREF_CHANNEL ADC_Channel_17
uint16_t adc_value = 0;
float temperature = 0;
float humidity = 0;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
dht11_read_data(&temperature, &humidity);
adc_value = ADC_GetConversionValue(ADC1);
}
}
void ADC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_TEMP_CHANNEL, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_VREF_CHANNEL, 2, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
}
int main(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 39999;
TIM_TimeBaseStructure.TIM_Prescaler = 7199;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
dht11_init(DHT11_PORT, DHT11_PIN);
ADC1_Init();
LCD_Init(LCD_PORT, LCD_RS, LCD_RW, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
while (1)
{
char buf[16];
sprintf(buf, "T=%.1fC H=%.1f%%", temperature, humidity);
LCD_SetCursor(0, 0);
LCD_WriteString(buf);
adc_value = ADC_GetConversionValue(ADC1);
temperature = (float)adc_value * 3.3 / 4096 - 0.76;
humidity = (temperature - 25) * 0.01 + humidity;
sprintf(buf, "T=%.1f H=%.1f", temperature, humidity);
LCD_SetCursor(0, 1);
LCD_WriteString(buf);
delay_ms(1000);
}
}
```
以上代码中,我们使用了dht11.h和lcd1602.h库来实现DHT11传感器和LCD1602显示屏的控制。在main函数中,我们先初始化定时器、DHT11传感器、LCD1602显示屏和ADC模块。然后在主循环中,我们不断读取温湿度数据和ADC值,并将其显示在LCD屏幕上。
需要注意的是,这里使用了一个简单的移动平均滤波算法来平滑温度和湿度的显示。你可以根据实际需求来选择是否使用滤波算法。
希望这份代码能对你有所帮助!
阅读全文