How to Interface DHT22 sensor with STM32

The DHT22  is a digital-output relative humidity and temperature sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and sends out a digital signal on the data pin. You can download the datasheet HERE.

We have already covered how to generate the delays in micro and nanoseconds using timer in STM32. Today we will utilise the delay in microseconds to interface the DHT22 temperature and Humidity sensor with STM32.

You can also check out the tutorial covering how to interface the DHT11 sensor with STM32.

If you are not able to get DHT11 or DHT22 values, Here is another method you can use. This one is unified for both the sensors. No setup needed for timer and all. Just select the data pin as output and you are done. you need to select the DHT TYPE in DHT.c. Download it from https://controllerstech.com/wp-content/uploads/2020/06/DHT_11_22_DWT.zip

The DHT22 uses one wire to communicate to the MCU. Therefore it is a very time sensitive device. Below are the timing diagrams from the DHT22 datasheet, used in different processes.

INITIALIZATION

Below the image shows the START condition.

Here the Black line is the signal from the microcontroller and the Grey line is the signal from the DHT22.

In order to initialise the sensor, we have to pull the data line LOW for at least 1ms, and pull it HIGH for around 20-40 us.
On receiving the start signal, DHT22 will indicate it’s presence by pulling the line low for 80us and than high for 80us.

NOTE:- You might need to connect pull-up resistance to the data line or else DHT22 will not be able to pull it HIGH.

To initialize the sensor, the steps are as follows:-

  • Set the pin (data) as output.
  • Pull the pin low and wait for > 1 ms.
  • Pull the pin high and wait for 30 us.
  • Release the pin by setting it as input.

DHT22 will now send the response as you can see in the figure above. To check the response, steps are as follows:-

  • Wait for 40us.
  • Check if the pin is low, than wait for 80 us. This will be a total delay of 120 us and the pin should be high now.
  • Check if the pin is high. If it is, then the response is OK.
  • Now wait for the pin to go LOW.

DATA Transmission

Now DHT22 will send 40 bits of data.  Each bit’s transmission begins with low-voltage-level that last 50 us, the following high-voltage-level signal’s length decides whether the bit is “1” or “0“.

  • If the length of high-voltage-level is around 26-28 us, the bit is “0
  • And if the length is around 70 us, than the bit is “1

The 40 bits sent by DHT22 are as follows DATA = 8 bit integral RH data + 8 bit decimal RH data + 8 bit integral T data+8 bit decimal T data + 8 bit checksum
If the data transmission is right, checksum should be the last 8 bit of “8 bit integral RH data+8 bit decimal RH data+8 bit integral T data+8 bit decimal T data”.

Following are the steps to READ DATA from the sensor

  1. Wait for the pin to go HIGH.
  2. Wait for 40us. This is because the length of “0” bit is 26-28us, and if the pin is high after 40us, it indicates that the bit is “1”.
  3. write the respective values to the variable.


Connection & Configuration

Below is the image showing the connection between DHT22 and nucleo F446.

Since the DHT22 only uses 1 wire to communicate to the MCU, I have connected it to the pin PA1. The sensor is powered with 5V from the nucleo board itself.

NOTE:- You might need to connect pull-up resistor to the data line or else DHT11 will not be able to pull the line HIGH.


clock configuration

Below is the image showing the clock configuration in the cubeMX.

The system is clocked from the external 8MHz crystal and the HCLK is set to 50MHz. Note that the APB1 Timer clock is also at 50MHz. This is important because we will use the TIM6 to generate the delays in microseconds and the TIM6 is connected to the APB1 bus.

Timer Configuration

Below is the image showing the configuration of the TIM6.

Since the APB1 Timer clock is at 50MHz, we will use the prescaler of 50 to bring the TIM6 clock to 1 MHz. This is already explained in the tutorial which explains how to generate the delays in micro/nanoseconds.

The pin PA1 is set as output, this is where the DHT22 data pin is connected to.

I2C Configuration

We are using the LCD1602 to display the Temperature and Humidity data. The LCD is connected using the PCF8574 I2C extender. Below is the image showing the I2C configuration.

I am using the I2C1 to connect the LCD. The I2C is configured in the standard mode with the clock speed set to 100KHz. The pins PB8 and PB9 are configured as the SCL and SDA pins.

We have already covered how to interface the LCD via I2C with STM32. You can check out the tutorial for more details.



The CODE

INITIALIZATION

void DHT22_Start (void)
{
	Set_Pin_Output(DHT22_PORT, DHT22_PIN); // set the pin as output
	HAL_GPIO_WritePin (DHT22_PORT, DHT22_PIN, 0);   // pull the pin low
	HAL_Delay(1200);   // wait for > 1ms

	HAL_GPIO_WritePin (DHT22_PORT, DHT22_PIN, 1);   // pull the pin high
	delay (20);   // wait for 30us

	Set_Pin_Input(DHT22_PORT, DHT22_PIN);   // set as input
}
  1. Set the pin (data) as output.
  2. Pull the pin low and wait for > 1 ms.
  3. Set the pin as input for receiving the data.

RESPONSE

uint8_t DHT22_Check_Response (void)
{
	Set_Pin_Input(DHT22_PORT, DHT22_PIN);   // set as input
	uint8_t Response = 0;
	delay (40);  // wait for 40us
	if (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))) // if the pin is low
	{
		delay (80);   // wait for 80us

		if ((HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))) Response = 1;  // if the pin is high, response is ok
		else Response = -1;
	}

	while ((HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN)));   // wait for the pin to go low
	return Response;
}
  1. Wait for 40 us.
  2. Check if the pin is low, than wait for 80 us. This will totally be a delay of 120 us and the pin should be high now.
  3. Check if the pin is high. If it is, then the response is OK.

READ DATA

uint8_t DHT22_Read (void)
{
	uint8_t i,j;
	for (j=0;j<8;j++)
	{
		while (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN)));   // wait for the pin to go high
		delay (40);   // wait for 40 us

		if (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN)))   // if the pin is low
		{
			i&= ~(1<<(7-j));   // write 0
		}
		else i|= (1<<(7-j));  // if the pin is high, write 1
		while ((HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN)));  // wait for the pin to go low
	}

	return i;
}
  1. Wait for the pin to go high.
  2. Wait for 40 us. This is because the length of “0” bit is 26-28 us  and if the pin is high after 40 us, it indicates that the bit is “1”.
  3. Write the respective values to the variable.

The delay function used in the code above is actually the delay in microseconds. We have already covered it another tutorial and below is the function for the same.

void delay (uint16_t time)
{
	/* change your code here for the delay in microseconds */
	__HAL_TIM_SET_COUNTER(&htim6, 0);
	while ((__HAL_TIM_GET_COUNTER(&htim6))<time);
}

The main function

int main()
{
  .....
  HAL_TIM_Base_Start(&htim6);  // for us Delay
  lcd_init();
  lcd_send_string("INITIALISING>>>>");
  HAL_Delay(2000);
  lcd_clear ();
  while (1)
  {
      DHT22_Start();
      Presence = DHT22_Check_Response();
      Rh_byte1 = DHT22_Read ();
      Rh_byte2 = DHT22_Read ();
      Temp_byte1 = DHT22_Read ();
      Temp_byte2 = DHT22_Read ();
      SUM = DHT22_Read();

      TEMP = ((Temp_byte1<<8)|Temp_byte2);
      RH = ((Rh_byte1<<8)|Rh_byte2);

      Temperature = (float) (TEMP/10.0);
      Humidity = (float) (RH/10.0);

      HAL_Delay(2000);

      Display_Temp(Temperature);
      Display_Rh(Humidity);
  }
}
  • We will first send the START condition an then check for the Presence.
  • The read the 40 bit data in sequence and store it in the 5 bytes.
  • Then combine the Temperature data together and Humidity data together.
  • To get the actual data in °C and %Rh, we need to divide the Temp and Rh data by 10.
  • Finally Display the data on the LCD.

Since we are also displaying the data on the LCD, the LCD is initialised in the main function itself. We have already covered how to use the LCD1602 via I2C to display strings, numbers, floats etc. Below are the functions for displaying the data on the LCD.

void Display_Temp (float Temp)
{
	char str[20] = {0};
	lcd_put_cur(0, 0);
	sprintf (str, "TEMP:- %.2f ", Temp);
	lcd_send_string(str);
	lcd_send_data('C');
}
void Display_Rh (float Rh)
{
	char str[20] = {0};
	lcd_put_cur(1, 0);
	sprintf (str, "RH:- %.2f ", Rh);
	lcd_send_string(str);
	lcd_send_data('%');
}


Result

Below is the image showing the output on the LCD.

You can see the temperature and humidity data is being displayed on the LCD.

You can watch the video to see the complete working of DHT22 sensor.

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

39 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Joseph
9 months ago

Hi sir / ma’am
I trust you are well

I’m running a simulation in proteus using the STM32F401RE, DHT22 and LM016L LCD. I used the unified dht11&dht22 library provided.

When I run the simulation, the LCD initially displays the dht22 values accurately. But when I vary the value of temperature and/or the value of humidity, the new values are not being updated on the LCD. It seems like the infinite while loop in STM32CubeIDE breaks after the 1st iteration.

I even made use of uUSART communication by and added a virtual terminal (in proteus) to check if it was my LCD code the source of the problem.

The dht22 values are only displayed once on both LCD and VIRTUAL TERMINAL.

I’m looking forward to hearing from you and any assistance will be much appreciated.

Regards,

Joseph

Hamza Alibi
11 months ago

please help me , i used an stm32 nucleo F439ZI with dht22 (AM2302).
clock config : clock freq = 180MHZ, prescale = 179 , counter period = 0xffff .

result of debugging : Error: check_response
Checksum error: SUM = 43, checksum = 389

#include “main.h”
#include “stdio.h”

/* Private variables ———————————————————*/
TIM_HandleTypeDef htim6;

/* Private function prototypes ———————————————–*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM6_Init(void);

int _write(int file, char *ptr, int len) {
int i;
for (i = 0; i < len; i++) {
ITM_SendChar((*ptr++));
}
return len;
}

void delay_us(uint16_t us)
{
__HAL_TIM_SET_COUNTER(&htim6, 0); // Set the counter value to 0
HAL_TIM_Base_Start(&htim6); // Start the timer
while (__HAL_TIM_GET_COUNTER(&htim6) 1ms

HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_SET); // pull the pin high
delay_us(20); // wait for 20-40us

Set_Pin_Input(DHT22_PORT, DHT22_PIN); // set as input
}

uint8_t DHT22_Check_Response(void)
{
uint8_t Response = 0;
delay_us(40); // wait for 40us
if (!(HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN))) // if the pin is low
{
delay_us(80); // wait for 80us
if (HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN)) Response = 1; // if the pin is high, response is ok
else Response = -1;
}
while (HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN)); // wait for the pin to go low
return Response;
}

uint8_t DHT22_Read(void)
{
uint8_t i, j;
for (j = 0; j < 8; j++)
{
while (!(HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN))); // wait for the pin to go high
delay_us(40); // wait for 40 us

if (!(HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN))) // if the pin is low
{
i &= ~(1 << (7 – j)); // write 0
}
else i |= (1 << (7 – j)); // if the pin is high, write 1
while (HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN)); // wait for the pin to go low
}
return i;
}

/* Main Function */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM6_Init();

while (1)
{
DHT22_Start();
Presence = DHT22_Check_Response();
if (Presence == 1)
{
Rh_byte1 = DHT22_Read();
Rh_byte2 = DHT22_Read();
Temp_byte1 = DHT22_Read();
Temp_byte2 = DHT22_Read();
SUM = DHT22_Read();
uint16_t checksum;
checksum = Rh_byte1 + Rh_byte2 + Temp_byte1 + Temp_byte2;

if (SUM == checksum)
{
TEMP = ((Temp_byte1 << 8) | Temp_byte2);
RH = ((Rh_byte1 << 8) | Rh_byte2);

Temperature = (float)(TEMP / 10.0);
Humidity = (float)(RH / 10.0);
printf("Temperature: %.1f°C, Humidity: %.1f%%\n", Temperature, Humidity);
}
else
{
printf("Checksum error: SUM = %d, checksum = %d\n", SUM, checksum);
}
}
else
{
printf("Error: check_response\n");
}
HAL_Delay(2000); // augmenter le délai entre les lectures pour éviter les lectures erronées
}
}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}

/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief TIM6 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM6_Init(void)
{

/* USER CODE BEGIN TIM6_Init 0 */

/* USER CODE END TIM6_Init 0 */

TIM_MasterConfigTypeDef sMasterConfig = {0};

/* USER CODE BEGIN TIM6_Init 1 */

/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 179;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 0xffff;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM6_Init 2 */

/* USER CODE END TIM6_Init 2 */

}

/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

ive
2 years ago

Hey man,
You got small bug here in the initialization code (just here on the website, source code in zip file is OK thought).

HAL_Delay(1200); // wait for > 1ms

should be
delay (1200); // wait for > 1ms

Dhamodharan Krishnan
3 years ago

Checksum requires fix in the function DHT_GetData below as it is failing.

if (SUM == ( (Rh_byte1 + Rh_byte2 + Temp_byte1 + Temp_byte2) & 0x00FF) )
    {
#if defined(TYPE_DHT11)
        DHT_Data->Temperature = Temp_byte1;
        DHT_Data->Humidity = Rh_byte1;
#endif

#if defined(TYPE_DHT22)
        DHT_Data->Temperature = ( ((Temp_byte1 << 8) | Temp_byte2) * 0.1f);
        DHT_Data->Humidity = ( ((Rh_byte1 << 8) | Rh_byte2) * 0.1f);
#endif
    }

Last edited 3 years ago by Dhamodharan Krishnan
Mitja
4 years ago

Hello,
Where can i found i2c-led.h and .c files?

Bilgehan Kargin
5 years ago

I’ve practiced everything you’ve told us. But, while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))); // wait for the pin to go low
in this line, waiting forever, I can not go to next step. What could be the reason ?

Bilgehan Kargin
Reply to  Bilgehan Kargin
5 years ago

The line of code I’m talking about in response function

Bl3kunja
Reply to  Bilgehan Kargin
5 years ago

I have the same problem…..

kacem
Reply to  Bl3kunja
5 years ago

did you solve the problem

Student
Reply to  kacem
4 years ago

I managed to solve it with the admin. My problem was because i didn’t use 5k ohms pull up and because my stm32 f303k8 had 8MHz system clock. After using internal pull up and setting system clock to 64MHz it worked like a charm.

ktbalazs
Reply to  Student
4 years ago

Unfortunately it did not solve this problem for me. Did anyone solve this problem in another way?

Student
Reply to  Bl3kunja
4 years ago

The same problem here… Still no solution?

On Kaa
Reply to  Bilgehan Kargin
4 years ago

i created new project and solved this problem. But i did not understand how problem is solved 🙂

On Kaa
Reply to  Bilgehan Kargin
4 years ago

i think problem is lcd_init() function. when i added lcd_init function in main funcion, dht22 is not working.

SUMIT MISHRA
5 years ago

Hi, why you used separate delay function instead of HAL Delay? Any specific reason?

SUMIT MISHRA
Reply to  admin
5 years ago

Thanks for the clarification!

Vadim M.
5 years ago

Hi! Thank you for your tuto! For the right checksum you shound do:
if (sum == ((Rh_byte1+Rh_byte2+Temp_byte1+Temp_byte2) & 0xFF))

Best regards

joel
6 years ago

In line No. 78 if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))) check = 1;
Variable “check” is not used anywhrere. Could you explain Why the “check” need?

Joel
Reply to  admin
6 years ago

Thanks for your reply!!

Ritik
Reply to  admin
6 years ago

can you tell how to interface ppd42 with stm32

mohammad
Reply to  admin
5 years ago

hi please run remote codelearn 433mhz with stm32f103 please help me thanks

basma
6 years ago

hello thanks for the code, i want to read values from dht22 but without using an LCD how could to modify your code to be useful in my case

basma
Reply to  admin
6 years ago

thank u, i run it and it works

beema
6 years ago

is it same and works for dht11 module?

Simon
7 years ago

Hello, I just followed your youtube video here.
This code is different with another I2C code,
First your codes on this project are:
void lcd_send_cmd (char cmd)
{
char data_u, data_l;
uint8_t data_t[4];
data_u = cmd&0xf0;
data_l = (cmd<<4)&0xf0;
data_t[0] = data_u|0x04; //en=1, rs=0
data_t[1] = data_u; //en=0, rs=0
data_t[2] = data_l|0x04; //en=1, rs=0
data_t[3] = data_l; //en=0, rs=0
HAL_I2C_Master_Transmit (&hi2c1, 0x4E,(uint8_t *) data_t, 4, 100);
}

void lcd_send_data (char data)
{
char data_u, data_l;
uint8_t data_t[4];
data_u = data&0xf0;
data_l = (data<<4)&0xf0;
data_t[0] = data_u|0x05; //en=1, rs=0
data_t[1] = data_u|0x01; //en=0, rs=0
data_t[2] = data_l|0x05; //en=1, rs=0
data_t[3] = data_l|0x01; //en=0, rs=0
HAL_I2C_Master_Transmit (&hi2c1, 0x4E,(uint8_t *) data_t, 4, 100);
}

But in another project, the lcd_send_cmd and lcd_send_data used different numbers for the data_t[ ] calculation. Why and which one is correct?

void lcd_send_cmd (char cmd)
{
char data_u, data_l;
uint8_t data_t[4];
data_u = (cmd&0xf0);
data_l = ((cmd<<4)&0xf0);
data_t[0] = data_u|0x0C; //en=1, rs=0
data_t[1] = data_u|0x08; //en=0, rs=0
data_t[2] = data_l|0x0C; //en=1, rs=0
data_t[3] = data_l|0x08; //en=0, rs=0
HAL_I2C_Master_Transmit (&hi2c1, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100);
}

void lcd_send_data (char data)
{
char data_u, data_l;
uint8_t data_t[4];
data_u = (data&0xf0);
data_l = ((data<<4)&0xf0);
data_t[0] = data_u|0x0D; //en=1, rs=0
data_t[1] = data_u|0x09; //en=0, rs=0
data_t[2] = data_l|0x0D; //en=1, rs=0
data_t[3] = data_l|0x09; //en=0, rs=0
HAL_I2C_Master_Transmit (&hi2c1, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100);
}

Simon
Reply to  admin
7 years ago

Thank you for your response.
I have another question:
What commands should I send to turn on/off the backlight? I know P3 is the backlight control pin.
I just can’t figure out a way to change only one bit of the register.

Simon
Reply to  Simon
7 years ago

I figured it out myself. Need to read the register first then change P3 bit and write it back.

Zac Pike
7 years ago

Do I need to change the Master Transmit address from 0x4E to whatevery my I2C is putting out? For Arduino I needed to use a scanner and check to see what it was and change that over before transmitting? Just wondering because I used everything here for my STM32F4 and it’s not working…thanks.

Hamza ELGUEZZAR
7 years ago

where is dwt_stm32_delay.h/dwt_stm32_delay.c please !

Hamid
Reply to  admin
6 years ago

Hi, Where are the “dwt_stm32_delay.h/dwt_stm32_delay.c ” and i2c files… Please I need them asap. Many thanks.