Reloj multifunción 2 basado en stm32-DHT 11 mide temperatura y humedad.
? En el último capítulo, lo llevé a implementar las funciones de visualización del reloj y ajuste de botones. En este capítulo, utilizaré el sensor de temperatura y humedad DHT11 para medir la temperatura y la humedad ambiente.
El sensor de temperatura y humedad DHT11 es digital e incluye 1 elemento sensor de humedad resistivo y 1 elemento medidor de temperatura NTC. Tiene una función de conversión AD incorporada y utiliza un solo bus. Tiene las características de respuesta rápida, fuerte capacidad antiinterferencias y rendimiento de alto costo. Este módulo tiene un total de 4 pines, dos de los cuales son pines de alimentación VCC y GND, uno es un pin de datos y el otro es un pin vacío.
Los buses de transmisión de datos más populares actualmente incluyen el bus II2C, el bus SPI y el bus único DHT11 que utiliza un solo bus para transmitir datos. El bus único, como sugiere el nombre, utiliza una línea de señal para transmitir reloj y datos al mismo tiempo. La transmisión de datos es bidireccional, por lo que se divide en maestro y esclavo. Aquí, stm32 es el host como controlador central y DHT11 es el esclavo. Cuando utilice un único bus para la transmisión de datos, deberá consultar el diagrama de tiempos en la hoja de datos. ?
El estado inactivo del bus es alto y el host baja el bus y espera la respuesta de DHT11. El anfitrión debe bajar el bus durante más de 18 milisegundos para garantizar que el DHT11 pueda detectar la señal de inicio. Después de recibir la señal de inicio del host, DHT11 espera a que finalice la señal de inicio del host y luego envía una señal de respuesta de bajo nivel de 80us. Después de enviar la señal de inicio del host, la señal de respuesta del DHT11 se lee después de un retraso de 20 a 40 us. Después de que el host envía una señal de inicio, puede cambiar al modo de entrada o emitir un bus promedio de alta potencia.
Según el diagrama de tiempo, el microcontrolador necesita bajar el bus durante al menos 18 ms y luego subirlo durante 20 ~ 40 us. En este momento, la señal de inicio del host finaliza y se detecta la señal de respuesta de DHT11. Si se detecta un nivel bajo, DHT11 responde manteniendo el nivel bajo durante 80us, y luego DHT11 eleva el bus durante 80us. En este momento, DHT11 está listo para transmitir datos y la brecha entre la transmisión de datos es de 50us de nivel bajo. Los datos enviados pueden distinguir "0" y "1" por la longitud del nivel alto. Después de la transmisión de datos, DHT11 baja el autobús durante 50 us y, finalmente, el anfitrión vuelve a subir el autobús.
(1) Función de retraso de escritura
Debido a que el tiempo de DHT11 es relativamente estricto, se requieren retrasos de nivel de milisegundos y retrasos sutiles. Aquí usamos Systick para implementar el retraso. El retraso también se utilizó en la función de escaneo de teclas anterior, así que lo describiré aquí.
Necesitamos configurar el reloj del sistema y luego configurar el Systick en 72 para generar una base de tiempo de 1us. En segundo lugar, necesitamos escribir la función de procesamiento de interrupciones Systick para permitir que las variables disminuyan por sí mismas, logrando así el efecto de retraso. Finalmente, necesitamos escribir una función de retraso, que consiste en asignar un valor inicial a la variable que se disminuye a sí misma.
_ _ IO uint32 _ t TimingDelay
/*Configurar la función SysTick*/
void systick_init(void)
{ p>
/*Configurar el valor de sobrecarga de Systick, el reloj del sistema es 72MHz*/
/*Establecer 72, tiempo de interrupción: 72 *(1/72000000)= 1us */
If(SysTick_Config(72)== 1)//Si la función sy stick _ Config devuelve una señal de interrupción, el valor de retorno es 0.
{
mientras(1);? // El valor de retorno de la función SysTick_Config es 1, así que espera.
}
}
/*Función de decremento variable en el tiempo*/
void TimingDelay_Decrement(void)
{
if(TimingDelay!=0x00)
{
retraso de tiempo-;
}
}
/*Manejador de interrupciones SysTick*/
void SysTick_Handler(void)
{
retraso de tiempo _ Decrement(); /p>
}
/*Función de retardo, la base de tiempo es 1 ms*/
Delay_ms no válido (__IO uint32_t tiempo)
{
retraso de tiempo = nTime * 1000;
while(TimingDelay!=0);
}
/*Función de retraso, la base de tiempo es 1us*/
Retraso no válido_us(__IO uint32_t nTime)
{
TimingDelay = nTime
while( TimingDelay! =0);
}
(2) Configure el puerto GPIO correspondiente como terminal de datos de un solo cable.
/*Configure el pin de datos DHT11 y configúrelo en modo de entrada de punto flotante*/
void DHT 11 _ gpio _ portIn(void)
{
GPIO_init typedef estructura GPIO_init;
RCC_APB 2 periphclockcmd(RCC_APB 2 periph_gpio a, habilitar);
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz
GPIO_Init(GPIOA amp; estructura GPIO_init);
}
/*Configurar el pin de datos DHT11, configurado en salida push-pull modo*/
void DHT 11 _ gpio _ port out(void)
{
GPIO _ init typedef GPIO _ init estructura;
RCC_APB 2 periphclockcmd(RCC_APB 2 periph_gpio a, habilitar);
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_Out_PP
GPIO_InitStructure.
GPIO_Speed = GPIO_Speed_50MHz
GPIO_Init(GPIOA amp; estructura GPIO_init);
}
Dado que DHT11 utiliza un protocolo de comunicación de bus único, la transmisión de datos es bidireccional, por lo que los puertos de datos están configurados en modo de entrada flotante y modo de salida push-pull respectivamente. Y la entrada y salida del puerto de datos se definen como definiciones de macro.
# definir DHT 11 _ OUT _ H GPIO _ establecer bits (GPIO a, GPIO_Pin_4)
# definir DHT 11 _ OUT _ L GPIO _ restablecer bits (GPIO a, GPIO_Pin_4)
#Define DHT 11 _ IN GPIO _ ReadInputDataBit (GPIOA, GPIO_Pin_4)
(3) Según el diagrama de tiempo DHT11, escriba la función de tiempo.
Ahora comenzamos a escribir la función del conductor del autobús. Según el diagrama de tiempo, el host envía un comando para iniciar la conversión, luego espera la respuesta de conversión del DHT11 y genera datos, y finalmente lee los datos.
/*Iniciar función bus*/
void DHT 11 _ reset(void)
{
DHT 11 _ gpio _ puerto out(); //Establecer en modo de salida
DHT 11 _ OUT _ L;? //El host baja el bus durante al menos 18 ms.
retraso _ ms(18);
DHT 11 _ SALIDA _ H;? //El anfitrión se detiene por 20~40us.
delay_us(30);
DHT 11_gpio_portIn();? //Establezca el modo de entrada y espere la respuesta de DHT11.
}
/*Función de respuesta DHT11*/
u8 dht11_scan(void)
{
Volver DHT 11_IN;? //El valor de retorno es la señal de respuesta de DHT11
}
Monitorea la línea de datos de DHT11 en tiempo real hasta que se genere un nivel bajo, lo que indica que DHT11 responde a la solicitud del host y comienza a transmitir datos.
/*DHT11 función de bit de lectura*/
u8 DHT 11 _ lectura _ bit(void)
{
mientras( DHT 11 _ IN = = RESET); //Hay un nivel bajo de 50us antes de la transmisión de bits de datos.
retraso_us(40);? //Determina si el nivel es 1 o 0 según la duración del nivel alto.
si(DHT11_IN==SET)? // El nivel "0" tiene una longitud de 26 ~ 28 us y el nivel "1" tiene una longitud de 70 us.
{
mientras(DHT 11 _ IN == SET);
Devolver 1;? //Si se detecta un nivel alto, el valor de retorno es 1.
}
Otro
{
Devuelve 0;? //Si se detecta un nivel alto, el valor de retorno es 0.
}
}
/*Función de lectura de bytes DHT11*/
//Nota: Los datos más significativos se transmiten en primer lugar .
u8 DHT 11 _ lectura _ byte(vacío)
{
u8 i, dat = 0x00
for(I = 0 ;ilt8;i)
{
dat = dat lt1;
dat = dat | DHT 11_read_bit();//leer datos seriales de salida.
}
Devolver datos
}
Cuando DHT11 responde, comienza a transmitir datos a través de un único bus. En la función de lectura de bits, el tiempo de nivel alto se utiliza para determinar si la salida es '1' o '0'. En la función de lectura de bytes, llame a la función de lectura de bits para integrar cada dato transmitido de 8 bits en bytes y leerlos.
Consultamos el manual de datos del DHT11 para conocer la estructura de transmisión de datos (en orden): parte entera de humedad (1 byte), parte decimal de humedad (1 byte), parte entera de temperatura (1 byte), Parte decimal de temperatura (1 byte), etc. En este caso, en realidad se trata de un protocolo de comunicación simple. La suma de verificación son los 8 bits inferiores de la suma de todos los bytes de los datos de origen, lo que garantiza la exactitud y estabilidad de los datos transmitidos.
/*DHT11 función de lectura de datos*/
u8 DHT 11 _ lectura _ datos(void)
{
u8i; /p>
DHT 11_reset();
if(DHT 11_scan()== reset)//DHT 11 envía una señal de respuesta.
{
while(DHT 11 _ IN == RESET); //DHT11 bus desplegable 80us.
while(DHT11_IN!=reset); //DHT11 eleva el autobús por 80us.
for(I = 0; i lt5; i )
{
búfer[I]= DHT 11 _ lectura _ byte(); >
}
while(DHT 11 _ IN == RESET); //Después de enviar el último bit de datos, espere a que finalice el nivel bajo de 50us.
DHT 11 _ gpio _ port out();
DHT 11 _ OUT _ H; //El host eleva el bus
if(buffer[ 0] buffer[1] buffer[2] buffer[3]= =buffer[4])
{
Devuelve 1;? //Verificación exitosa.
}
Otro
{
Devuelve 0;? //La verificación falló.
}
}
Otro
{
Devuelve 0;? //DHT11 no envió una señal de respuesta.
}
}
Al leer bytes, espere la respuesta de DHT11, luego comience a recibir datos y léalos cinco veces seguidas, almacenados en el pre- en la matriz definida. El host envía la señal de finalización y finalmente verifica los datos leídos.
(4) Mide y muestra la temperatura y la humedad
La función principal llama a la función de lectura de datos DHT11 y a la función de pantalla LCD para mostrar la temperatura y la humedad.
if(DHT11 _ Read _ data() = = 1)//Leer datos, siempre que DHT 11 responda y la verificación de datos sea exitosa.
{
Humedad = buffer[0]; //buffer[0] almacena la parte entera de la humedad.
Temperatura = buffer[2]; //buffer[2] almacena la parte entera de la temperatura.
}
Lcd_display_string(2,0,"temperatura");
lcd_display_num_m(2,32,temperatura/10);
lcd_display_num_m(2, 40, temperatura 10);
Lcd_display_string (4, 0, "humedad");
lcd_display_num_m (4, 32, humedad/10); >
lcd_display_num_m(4, 40, humedad 10);
En este punto, a través de la explicación de este capítulo, creo que todos deberían tener una comprensión general del módulo DHT11. Por supuesto, si acaba de leer el artículo, es posible que el efecto no sea el ideal. Todas estas cosas requieren experiencia práctica. Como dice el refrán, "la práctica hace la perfección". Por lo tanto, puedes comprar placas de desarrollo y algunos módulos en línea, y no tienen que ser iguales a los míos. Por supuesto, si quiere desafiarse a sí mismo, puede comprar una placa base mínima para poder construir usted mismo los circuitos de hardware periféricos (las funciones están personalizadas), lo cual es flexible y también ejercita su capacidad práctica. Si eres un gran jefe que puede diseñar PCB, eso es aún mejor. Para estimar tu nivel, simplemente navega por mis artículos.