I'm new to STM32, and I want to write a function that will check if the sensor (DHT11) has sent data. I set PA6 to OUTPUT mode and hold low for at least 18ms (according to datasheet), and then release it and set PA6 to INPUT mode, then external interrupt (IT_RISING mode) on pin PA5 is triggered. Then the simple cycle checks PA5 pinstate for some time (because DHT11, if connected properly, will pull down the line multiple times). If the DHT11 is not connected, then the PA5 will be high all the time. But when I test the program in Proteus, only "else" condition always enabled... I've tried multiple methods (IDR, HAL, CMSIS, macros), but no one of them didn't solve the problem. Where is the mistake?
The interrupt function is:
volatile uint32_t check_cnt = 0, check_delay = 100;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == GPIO_PIN_5) {
while (check_cnt < check_delay) {
if (GPIOA->IDR & (0 << 5)) { //CHECK PA5 PINSTATE (if low, then DHT11 have send data)
GPIOA->BSRR = (1 << 8); //line, that shows DHT11 connected
break;
} else {
GPIOA->BSRR = (1 << 9); //line, that shows DHT11 disconnected
check_cnt++;
}
}
}
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
}
GPIO Init function:
void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART2_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12;
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);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
DHT11 Init function:
void DHT11_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6;
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);
GPIOA->BSRR = (0 << 6);
HAL_Delay(18);
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
main.c
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
//MX_USART2_UART_Init();
//DWT_Init();
DHT11_Init();
HAL_GPIO_EXTI_Callback(GPIO_PIN_5);
while(1)
{
//other code
}
}
1 Answer 1
This is not about STM32 but purely C mistake.
Anding anything with a 0 results in 0 so the comparison result is never true.
Explore related questions
See similar questions with these tags.
if (GPIOA->IDR & (0 << 5))
will always evaluate to false because0 << 5
will always be0
. You probably meant1 << 5
there. \$\endgroup\$GPIO_PIN_5
which you already used on the line above. \$\endgroup\$