移植到AHL-GEC-IDE中适用的DHT11温湿度传感器驱动。
//tempRegression.h文件
///=====================================================================
#ifndef __ADC_TEMP_REGRESSION_H
#define __ADC_TEMP_REGRESSION_H
#include "mcu.h"
#include "user.h"
void begin();
uint32_t expectPulse(uint8_t level);
uint8_t read();
float readTemperature();
#endif
//tempRegression.c文件
#include "tempRegression.h"
#define DHT_11 (PTB_NUM|13) //GEC30
#define MIN_INTERVAL 2000
#define TIMEOUT 0xFFFFFFFF
uint8_t data[5];
uint16_t _pin=DHT_11;
uint32_t _lastreadtime;
uint32_t _maxcycles;
uint8_t _lastresult = 0;
uint8_t pullTime; // Time (in usec) to pull up data line before reading
void begin() {
// set up the pins!
gpio_init(_pin, GPIO_INPUT, 0);
_maxcycles = 8000;
_lastreadtime = millis() - MIN_INTERVAL;
printf("DHT max clock cycles: ");
pullTime = 55;
}
uint32_t expectPulse(uint8_t level) {
uint32_t count = 0;
while (gpio_get(_pin) == level) {
if (count++ >= _maxcycles) {
return TIMEOUT; // Exceeded timeout, fail.
}
}
return count;
}
uint8_t read() {
// Check if sensor was read less than two seconds ago and return early
// to use last reading.
uint32_t currenttime = millis();
if (((currenttime - _lastreadtime) < MIN_INTERVAL)) {
return _lastresult; // return last correct measurement
}
_lastreadtime = currenttime;
// Reset 40 bits of received data to zero.
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// Send start signal. See DHT datasheet for full signal diagram:
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
// Go into high impedence state to let pull-up raise data line level and
// start the reading process.
gpio_init(_pin, GPIO_INPUT, 0);
Delay_ms(1);//延时1毫秒
// First set data line low for a period according to sensor type
gpio_init(_pin, GPIO_OUTPUT, 0);
gpio_set(_pin, 0);
Delay_ms(20); // data sheet says at least 18ms, 20ms just to be safe//延时20毫秒
uint32_t cycles[80];
{
// End the start signal by setting data line high for 40 microseconds.
gpio_init(_pin, GPIO_INPUT, 0);
// Delay a moment to let sensor pull data line low.
Delay_us(pullTime);
// Now start reading the data line to get the value from the DHT sensor.
// First expect a low signal for ~80 microseconds followed by a high signal
// for ~80 microseconds again.
if (expectPulse(0) == TIMEOUT) {
printf("DHT timeout waiting for start signal low pulse.");
_lastresult = 0;
return _lastresult;
}
if (expectPulse(1) == TIMEOUT) {
printf("DHT timeout waiting for start signal high pulse.");
_lastresult = 0;
return _lastresult;
}
for (uint32_t i = 0; i < 80; i += 2) {
cycles[i] = expectPulse(0);
cycles[i + 1] = expectPulse(1);
}
} // Timing critical code is now complete.
// Inspect pulses and determine which ones are 0 (high state cycle count < low
// state cycle count), or 1 (high state cycle count > low state cycle count).
for (uint32_t i = 0; i < 40; ++i) {
uint32_t lowCycles = cycles[2 * i];
uint32_t highCycles = cycles[2 * i + 1];
if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) {
printf("DHT timeout waiting for pulse.");
_lastresult = 0;
return _lastresult;
}
data[i / 8] <<= 1;
// Now compare the low and high cycle times to see if the bit is a 0 or 1.
if (highCycles > lowCycles) {
// High cycles are greater than 50us low cycle count, must be a 1.
data[i / 8] |= 1;
}
// Else high cycles are less than (or equal to, a weird case) the 50us low
// cycle count so this must be a zero. Nothing needs to be changed in the
// stored data.
}
printf("Received from DHT:");
// Check we read 40 bits and that the checksum matches.
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
_lastresult = 1;
return _lastresult;
} else {
printf("DHT checksum failure!");
_lastresult = 0;
return _lastresult;
}
}
float readTemperature() {
float f = NAN;
if (read()) {
f = data[2];
if (data[3] & 0x80) {
f = -1 - f;
}
f += (data[3] & 0x0f) * 0.1;
}
return f;
}