USER CODE BEGIN Header
USER CODE BEGIN Header
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE
file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------
*/
#include "main.h"
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* MCU Configuration--------------------------------------------------------
*/
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(DHT11_Start())
{
RHI = DHT11_Read(); // Relative humidity integral
RHD = DHT11_Read(); // Relative humidity decimal
TCI = DHT11_Read(); // Celsius integral
TCD = DHT11_Read(); // Celsius decimal
SUM = DHT11_Read(); // Check sum
if (RHI + RHD + TCI + TCD == SUM)
{
// Can use RHI and TCI for any purposes if whole number only
needed
tCelsius = (float)TCI + (float)(TCD/10.0);
printf(RHI);
printf(TCD);
tFahrenheit = tCelsius * 9/5 + 32;
RH = (float)RHI + (float)(RHD/10.0);
Lcd_cursor(&lcd,0,0);
Lcd_string(&lcd,"tCelsius=");
Lcd_cursor(&lcd,0,11);
Lcd_float(&lcd,tCelsius);
Lcd_cursor(&lcd,1,0);
Lcd_string(&lcd,"RH=");
Lcd_cursor(&lcd,1,5);
Lcd_float(&lcd,RH);
// Can use tCelsius, tFahrenheit and RH for any purposes
}
HAL_Delay(2000);
}
/* USER CODE END WHILE */
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/**
* @brief TIM1 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM1_Init(void)
{
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state
*/
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line
number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line)
*/
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
This is an embedded C program for a STM32 microcontroller, likely running
an RTOS such as FreeRTOS. The program is used to interface with a DHT11
temperature and humidity sensor, and display the results on an LCD screen.
Here is an explanation of each section of the code:
The timer was used in this program to introduce a delay between the
transmission of the start signal and the beginning of the data transmission
from the DHT11 sensor. This delay is necessary because the DHT11 sensor
requires a certain amount of time to prepare the data after receiving the start
signal.
The timer is configured to generate an interrupt after a specified time period.
In this program, the timer is configured to generate an interrupt after 20
milliseconds. This delay allows the DHT11 sensor to prepare the data.
After the timer interrupt, the program reads the data from the DHT11 sensor.
The data is then processed and displayed on the LCD screen.
Here is the code snippet that demonstrates the use of the timer:
EditDownloadCopy code
1void SystemClock_Config(void);
2void MX_GPIO_Init(void);
3void MX_TIM1_Init(void);
4
5int main(void)
6{
7 HAL_Init();
8 SystemClock_Config();
9 MX_GPIO_Init();
10 MX_TIM1_Init();
11
12 Lcd_Init();
13 Lcd_Clear();
14
15 while (1)
16 {
17 HAL_TIM_Base_Start_IT(&htim1); // Start the timer in interrupt mode
18 HAL_Delay(200); // Wait for the timer interrupt to occur
19
20 DHT11_Start(); // Send the start signal to the DHT11 sensor
21 DHT11_Read(); // Read the temperature and humidity data from the DHT11 sensor
22
23 Lcd_SetCursor(0, 0);
24 Lcd_WriteString("Temp: ");
25 Lcd_WriteFloat(tCelsius);
26 Lcd_WriteString(" C");
27
28 Lcd_SetCursor(0, 1);
29 Lcd_WriteString("Humidity: ");
30 Lcd_WriteFloat(RH);
31 Lcd_WriteString("%");
32
33 HAL_Delay(2000); // Wait for 2 seconds before reading the sensor again
34 }
35}
In this code snippet, the HAL_TIM_Base_Start_IT() function is used to start the
timer in interrupt mode. The HAL_Delay() function is used to introduce a delay
of 200 milliseconds before reading the data from the DHT11 sensor. This
delay allows the DHT11 sensor to prepare the data.
After the delay, the program reads the temperature and humidity data from the
DHT11 sensor using the DHT11_Read() function. The data is then processed
and displayed on the LCD screen.
The start signal used in the DHT11_Start function is a sequence of setting and
resetting the output of a specific pin ( DHT11_PIN on DHT11_PORT). Here is the
relevant code:
EditDownloadCopy code
1GPIO_InitTypeDef GPIO_InitStructPrivate = {0};
2GPIO_InitStructPrivate.Pin = DHT11_PIN;
3GPIO_InitStructPrivate.Mode = GPIO_MODE_OUTPUT_PP;
4GPIO_InitStructPrivate.Speed = GPIO_SPEED_FREQ_LOW;
5GPIO_InitStructPrivate.Pull = GPIO_NOPULL;
6HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate);
7
8HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 0); // pull the pin low
9HAL_Delay(20); // wait for 20ms
10HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 1); // pull the pin high
11microDelay (30); // wait for 30us
This code sets the pin as an output, pulls it low for 20ms, then pulls it high for
30us. This is the start signal for the DHT11 sensor.
Is this conversation helpful so far?
After the data is read from the DHT11 sensor, it is processed and then
displayed on an LCD screen. Here is the relevant code:
EditDownloadCopy code
1Lcd_cursor(&lcd,0,0);
2Lcd_string(&lcd,"tCelsius=");
3Lcd_cursor(&lcd,0,11);
4Lcd_float(&lcd,tCelsius);
5
6Lcd_cursor(&lcd,1,0);
7Lcd_string(&lcd,"RH=");
8Lcd_cursor(&lcd,1,5);
9Lcd_float(&lcd,RH);
This code sets the cursor position on the LCD screen and displays the
temperature in Celsius and the relative humidity in percentage.
The Lcd_cursor function sets the cursor position, the Lcd_string function
displays a string, and the Lcd_float function displays a floating point number.
Note that the Lcd_float function is a custom function defined in the lcd.c file,
which is not included in the code snippet provided. This function converts a
floating point number to a string and displays it on the LCD screen.
The Lcd_handleTypeDef struct, which is used to initialize and control the LCD
screen, is also defined in the lcd.c file.
After the data is read from the DHT11 sensor, it is processed to convert the
raw binary data to temperature and humidity values. Here is the relevant
code:
EditDownloadCopy code
1RHI = DHT11_Read(); // Relative humidity integral
2RHD = DHT11_Read(); // Relative humidity decimal
3TCI = DHT11_Read(); // Celsius integral
4TCD = DHT11_Read(); // Celsius decimal
5SUM = DHT11_Read(); // Check sum
6
7if (RHI + RHD + TCI + TCD == SUM) { // Check sum correct
8 // Can use RHI and TCI for any purposes if whole number only needed
9 tCelsius = (float)TCI + (float)(TCD/10.0);
10 tFahrenheit = tCelsius * 9/5 + 32;
11 RH = (float)RHI + (float)(RHD/10.0);
12 Lcd_cursor(&lcd,0,0);
13 Lcd_string(&lcd,"tCelsius=");
14 Lcd_cursor(&lcd,0,11);
15 Lcd_float(&lcd,tCelsius);
16 Lcd_cursor(&lcd,1,0);
17 Lcd_string(&lcd,"RH=");
18 Lcd_cursor(&lcd,1,5);
19 Lcd_float(&lcd,RH);
20}
This code reads the raw binary data from the DHT11 sensor using
the DHT11_Read function, and stores it in the variables RHI, RHD, TCI, TCD,
and SUM. The check sum is then calculated by adding up all the data values
and comparing it to the check sum value read from the sensor. If the check
sum is correct, the temperature and humidity values are calculated by
converting the raw binary data to decimal values and storing them in the
variables tCelsius, tFahrenheit, and RH. The temperature and humidity
values are then displayed on the LCD screen using
the Lcd_cursor, Lcd_string, and Lcd_float functions, which are defined in
the lcd.c file.
Note that the Lcd_float function is a custom function defined in the lcd.c file,
which is not included in the code snippet provided. This function converts a
floating point number to a string and displays it on the LCD screen.
So, the raw binary data is processed to convert it to temperature and humidity
values by calculating the decimal values of the raw binary data and storing it
in the variables tCelsius, tFahrenheit, and RH. The temperature and humidity
values are then displayed on the LCD screen.
Is this conversation helpful so far?
In the code, the DHT11_Start function is used to send a start signal to the
DHT11 sensor to initiate a data transfer. This is necessary because the
DHT11 sensor is a digital sensor that uses a single data line for both input and
output.
The start signal is used to wake up the sensor and indicate that the
microcontroller is ready to receive data. The start signal is generated by
pulling the data line low for at least 18 milliseconds, then releasing it and
waiting for the sensor to pull the data line low. This indicates that the sensor is
ready to send data.
EditDownloadCopy code
1uint8_t DHT11_Start (void) {
2 uint8_t Response = 0;
3 GPIO_InitTypeDef GPIO_InitStructPrivate = {0};
4 GPIO_InitStructPrivate.Pin = DHT11_PIN;
5 GPIO_InitStructPrivate.Mode = GPIO_MODE_OUTPUT_PP;
6 GPIO_InitStructPrivate.Speed = GPIO_SPEED_FREQ_LOW;
7 GPIO_InitStructPrivate.Pull = GPIO_NOPULL;
8 HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate);
9 // set the pin as output
10 HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 0);
11 // pull the pin low
12 HAL_Delay(20);
13 // wait for 20ms
14 HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 1);
15 // pull the pin high
16 microDelay (30);
17 // wait for 30us
18 GPIO_InitStructPrivate.Mode = GPIO_MODE_INPUT;
19 GPIO_InitStructPrivate.Pull = GPIO_PULLUP;
20 HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate);
21 // set the pin as input
22 microDelay (40);
23 if (!(HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN))) {
24 microDelay (80);
25 if ((HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)))
26 Response = 1;
27 }
28 pMillis = HAL_GetTick();
29 cMillis = HAL_GetTick();
30 while ((HAL_GPIO_ReadPin (DHT11_PORT, DHT11_PIN)) && pMillis + 2 > cMillis) {
31 cMillis = HAL_GetTick();
32 }
33 return Response;
34}
The function first initializes the data pin as an output, then pulls it low for 20
milliseconds, then releases it and waits for the sensor to pull the data line low.
It then initializes the data pin as an input and waits for the sensor to send the
response signal. If the response signal is received, the function returns 1,
otherwise, it returns 0.
So, the DHT11_Start function is used to send a start signal to the DHT11
sensor to initiate a data transfer, and it also checks for the response signal
from the sensor. This is necessary to ensure that the sensor is ready to send
data and that the data transfer can proceed correctly.