Добрый день всем! Есть проблема с работой датчика DHT22. Я пытаюсь использовать стороннюю библиотеку и выводить все в порт или на LCD. Код библиотеки (ногодрыг)
Спойлер
Код:
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
#include "delay.h"
#include "dht22.h"
uint16_t bits[40];
uint8_t hMSB = 0;
uint8_t hLSB = 0;
uint8_t tMSB = 0;
uint8_t tLSB = 0;
uint8_t parity_rcv = 0;
static GPIO_InitTypeDef PORT;
void DHT22_Init(void) {
RCC_APB2PeriphClockCmd(DHT22_GPIO_CLOCK,ENABLE);
PORT.GPIO_Mode = GPIO_Mode_Out_PP;
PORT.GPIO_Pin = DHT22_GPIO_PIN;
PORT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT22_GPIO_PORT,&PORT);
}
uint32_t DHT22_GetReadings(void) {
uint32_t wait;
uint8_t i;
// Generate start impulse for sensor
DHT22_GPIO_PORT->BRR = DHT22_GPIO_PIN; // Pull down SDA (Bit_SET)
Delay_ms(2); // Host start signal at least 800us
DHT22_GPIO_PORT->BSRR = DHT22_GPIO_PIN; // Release SDA (Bit_RESET)
// Switch pin to input with Pull-Up
PORT.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(DHT22_GPIO_PORT,&PORT);
// Wait for AM2302 to start communicate
wait = 0;
while ((DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 200)) Delay_us(2);
if (wait > 50) return DHT22_RCV_NO_RESPONSE;
// Check ACK strobe from sensor
wait = 0;
while (!(DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 100)) Delay_us(1);
if ((wait < 8) || (wait > 15)) return DHT22_RCV_BAD_ACK1;
wait = 0;
while ((DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 100)) Delay_us(1);
if ((wait < 8) || (wait > 15)) return DHT22_RCV_BAD_ACK2;
// ACK strobe received --> receive 40 bits
i = 0;
while (i < 40) {
// Measure bit start impulse (T_low = 50us)
wait = 0;
while (!(DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 20)) Delay_us(1);
if (wait > 16) {
// invalid bit start impulse length
bits[i] = 0xffff;
while ((DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 20)) Delay_us(1);
} else {
// Measure bit impulse length (T_h0 = 25us, T_h1 = 70us)
wait = 0;
while ((DHT22_GPIO_PORT->IDR & DHT22_GPIO_PIN) && (wait++ < 20)) Delay_us(1);
bits[i] = (wait < 16) ? wait : 0xffff;
}
i++;
}
for (i = 0; i < 40; i++) if (bits[i] == 0xffff) return DHT22_RCV_RCV_TIMEOUT;
return DHT22_RCV_OK;
}
uint16_t DHT22_DecodeReadings(void) {
uint8_t parity;
uint8_t i = 0;
hMSB = 0;
for (; i < 8; i++) {
hMSB <<= 1;
if (bits[i] > 7) hMSB |= 1;
}
hLSB = 0;
for (; i < 16; i++) {
hLSB <<= 1;
if (bits[i] > 7) hLSB |= 1;
}
tMSB = 0;
for (; i < 24; i++) {
tMSB <<= 1;
if (bits[i] > 7) tMSB |= 1;
}
tLSB = 0;
for (; i < 32; i++) {
tLSB <<= 1;
if (bits[i] > 7) tLSB |= 1;
}
for (; i < 40; i++) {
parity_rcv <<= 1;
if (bits[i] > 7) parity_rcv |= 1;
}
parity = hMSB + hLSB + tMSB + tLSB;
return (parity_rcv << 8) | parity;
}
uint16_t DHT22_GetHumidity(void) {
return (hMSB << 8) + hLSB;
}
uint16_t DHT22_GetTemperature(void) {
return (tMSB << 8) + tLSB;
}
Либа задержек
Спойлер
Код:
#include <stm32f10x_rcc.h>
#include "delay.h"
// SysTick interrupt handler
void SysTick_Handler() {
if (TimingDelay != 0) { TimingDelay--; }
}
// Do delay for mSecs milliseconds
void Delay_ms(uint32_t mSecs) {
SysTick_Config(SystemCoreClock / DELAY_TICK_FREQUENCY_MS);
TimingDelay = mSecs+1;
while (TimingDelay != 0);
}
// Do delay for nSecs microseconds
void Delay_us(uint32_t uSecs) {
SysTick_Config(SystemCoreClock / DELAY_TICK_FREQUENCY_US);
TimingDelay = uSecs+1;
while (TimingDelay != 0);
}
В мейн все инициализирую и пытаюсь работать с датчиком.
Спойлер
Код:
int main(void)
{
//SysTick_Config(SystemCoreClock / 1000);
UART_Init();
UART_SendStr("\nSTM32VLDiscovery is online.\n");
while (1) {
DHT22_Init();
response = DHT22_GetReadings();
if (response != DHT22_RCV_OK) {
UART_SendStr("DHT22_GetReadings() error = ");
UART_SendInt(response); UART_SendChar('\n');
} else {
response = DHT22_DecodeReadings();
UART_SendStr("Parity: Received = "); UART_SendInt(response & 0xff);
UART_SendStr(" Actual = "); UART_SendInt(response >> 8);
UART_SendChar('\n');
if ((response & 0xff) != (response >> 8)) {
UART_SendStr("Wrong data received.\n");
} else {
temperature = DHT22_GetTemperature();
humidity = DHT22_GetHumidity();
UART_SendStr("Humidity: ");
UART_SendInt(humidity / 10); UART_SendChar('.');
UART_SendInt(humidity % 10); UART_SendStr("%RH");
UART_SendChar('\n');
UART_SendStr("Temperature: ");
if ((temperature & 0x8000) != 0) UART_SendChar('-');
UART_SendInt((temperature & 0x7fff) / 10); UART_SendChar('.');
UART_SendInt((temperature & 0x7fff) % 10); UART_SendStr("C");
UART_SendChar('\n');
}
}
Delay_ms(1000);
}
}
Дохожу до response = DHT22_GetReadings(); И тут происходит какое-то зацикливание, если я правильно понимаю. Все что ниже, больше не работает. Хоть в порт пиши, хоть на экран выводи, хоть ножкой дрыгай. В отладчике тоже до этого места доходит, захожу во внутрь функции DHT22_GetReadings(); и на первом же цикле застреваю. По идее, если бы не было ответа, я бы получил соответствующее предупреждение в терминале. В чем может быть проблема. Заранее благодарен за ответ и любую помощь!
Использую Keil uVision и VLDiscovery + DHT22 ()