Сб май 19, 2018 10:48:59
#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);
}
}
Вт май 22, 2018 18:40:31
console_put - вывод строки.
console_put_* - вывод чего-либо ещё строкой.
console_put_hex - выведет байт в виде FF
Можете заменить на printf или что-то подобное.
void DWT_Init(void) {
//разрешаем использовать счётчик
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// Разблокировка регистров
DWT->LAR = 0xC5ACCE55;
//обнуляем значение счётного регистра
DWT->CYCCNT = 0;
//запускаем счётчик
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
};
static __inline uint32_t delta(uint32_t t0, uint32_t t1) {
return (t1 - t0);
};
void delay_us(uint32_t us) {
uint32_t t0 = DWT->CYCCNT;
uint32_t us_count_tic = us * (SystemCoreClock/1000000);
while (delta(t0, DWT->CYCCNT) < us_count_tic) ;
};
/* void delay_ms(uint32_t ms) {
uint32_t ms_now = tick_count;
while ((ms_now + ms) > tick_count) {
__WFI();
};
}; */
void delay_ms(uint32_t ms) {
uint32_t i=ms;
while (i--) {
delay_us(1000);
};
};
// Где-то в дебрях main()
uint8_t th[5];
uint32_t i, j;
// console_put("Searching DHT22\r\n");
GPIOB->BSRR = GPIO_BSRR_BR_2; // Select Flash
delay_ms(1);
GPIOB->BSRR = GPIO_BSRR_BS_2; // DeSelect Flash
delay_us(25);
GPIOB->BSRR = GPIO_BSRR_BR_2; // Select Flash
delay_us(1);
GPIOB->MODER &= 0xFFFFFFCF; // GPIOB[2] -> Input
j = 0;
for (i=0;i<100;i++) {
if ((GPIOB->IDR & GPIO_IDR_IDR_2) == 0) {
// console_put("DHT22 detected\r\n");
j = 1;
break;
};
delay_us(5);
};
while(((GPIOB->IDR & GPIO_IDR_IDR_2) == 0));
while((GPIOB->IDR & GPIO_IDR_IDR_2));
if (j) {
for (v=0;v<40;v++) {
while(((GPIOB->IDR & GPIO_IDR_IDR_2) == 0)) { delay_us(1); };
j = 0;
while((GPIOB->IDR & GPIO_IDR_IDR_2)) { j++; delay_us(1); };
if (j > 40) {
th[((v)>>3)] |= (0x80 >> (v & 0x07));
} else {
};
};
};
// console_put("Data read done.");
// for (i=0;i<5;i++) {
// console_put_hex_byte(th[i]);
// };
// console_put("\r\n");
i = th[0] + th[1] + th[2] + th[3];
i = i & 0xFF;
if (i == th[4]) {
// console_put("CRC OK\r\n");
console_put("RH: ");
console_put_int((th[0] * 256 + th[1]) / 10);
console_put(".");
console_put_int((th[0] * 256 + th[1]) % 10);
console_put("%\tTemp: ");
console_put_int((th[2] * 256 + th[3]) / 10);
console_put(".");
console_put_int((th[2] * 256 + th[3]) % 10);
console_put("C\r\n");
} else {
console_put("CRC ERROR\r\n");
};