|
@@ -21,6 +21,12 @@
|
|
|
#include "main.h"
|
|
|
|
|
|
/* Defines */
|
|
|
+/* Timer1, IC negative edge, CTC mode, 64 prescaler */
|
|
|
+#define TIMER1_ON TCCR1B = ((0<<ICES1) | (1<<WGM12) | (1<<CS11) | (1<<CS10))
|
|
|
+#define TIMER1_OFF TCCR1B = 0x00
|
|
|
+#define DHT_TIMEOUT 1500
|
|
|
+#define DHT_MAX_COUNT 42
|
|
|
+/* Timer2 settings */
|
|
|
#define TIMER2_HZ 252
|
|
|
#define TIMER2_PRESCALER 1024
|
|
|
#define TIMER2_CS (1<<CS22 | 1<<CS21 | 1<<CS20)
|
|
@@ -36,6 +42,13 @@
|
|
|
/* Display timeout, sec */
|
|
|
#define DISP_WDT_TIME 10
|
|
|
|
|
|
+/* USART */
|
|
|
+#define BAUD 19200UL
|
|
|
+#define BAUD_PRESCALE (uint8_t)((F_CPU / BAUD / 16UL) - 1)
|
|
|
+#define CHAR_NEWLINE '\n'
|
|
|
+#define CHAR_RETURN '\r'
|
|
|
+#define RETURN_NEWLINE "\r\n"
|
|
|
+
|
|
|
|
|
|
/* Variables */
|
|
|
static volatile uint8_t Digit[4] = {1, 2, 3, 4};
|
|
@@ -59,6 +72,7 @@ static volatile uint8_t DISP_WDT = 0;
|
|
|
static EEMEM uint8_t EEP_BrightIdx;
|
|
|
static uint8_t brightIdx;
|
|
|
static EEMEM uint8_t EEP_SummerTime;
|
|
|
+static uint8_t dhtBuf[42];
|
|
|
|
|
|
/* Constants */
|
|
|
#if (USE_BRIGHT_CONTROL == 1)
|
|
@@ -75,6 +89,12 @@ static void valIncrease(uint8_t * val, uint8_t max);
|
|
|
static void valDecrease(uint8_t * val, uint8_t max);
|
|
|
static void blink(void);
|
|
|
static void setSummerWinterTime(void);
|
|
|
+static void dhtStart(void);
|
|
|
+static void dhtBegin(void);
|
|
|
+static void dhtEnd(void);
|
|
|
+static void dhtTimeout(void);
|
|
|
+void usart_putc (char send);
|
|
|
+void usart_puts (const char *send);
|
|
|
|
|
|
void main(void) {
|
|
|
/**
|
|
@@ -116,9 +136,11 @@ void main(void) {
|
|
|
showTime();
|
|
|
|
|
|
RTOS_SetTask(btnProcess, 5, BTN_SCAN_PERIOD);
|
|
|
+ RTOS_SetTask(dhtStart, 7, 60000); //once per minute start DHT22 measure
|
|
|
|
|
|
/** main loop */
|
|
|
do {
|
|
|
+ /* new second interrupt from RTC */
|
|
|
if (Flag.RTC_Int != 0) {
|
|
|
Flag.RTC_Int = 0;
|
|
|
ES_PlaceEvent(evNewSecond);
|
|
@@ -193,15 +215,28 @@ static void Board_Init(void) {
|
|
|
/* Timer2 - refresh Nixie values */
|
|
|
TCCR2 = TIMER2_CS;
|
|
|
TCNT2 = TIMER2_CNT;
|
|
|
- TIMSK = _BV(TOIE2) | _BV(OCIE2);
|
|
|
+
|
|
|
+ /* Timer interrupts */
|
|
|
+ TIMSK = _BV(TOIE2) | _BV(TICIE1) | _BV(TOIE1);
|
|
|
+
|
|
|
#if (USE_BRIGHT_CONTROL == 1)
|
|
|
OCR2 = pgm_read_byte(&brightConv[BRIGHT_IDX_MAX]);
|
|
|
+ TIMSK |= _BV(OCIE2);
|
|
|
#endif // USE_BRIGHT_CONTROL
|
|
|
|
|
|
/* Interrupt from RTC */
|
|
|
MCUCR = _BV(ISC11); // falling edge
|
|
|
GICR = _BV(INT1);
|
|
|
|
|
|
+ /* USART */
|
|
|
+ // Turn on USART hardware (no RX, TX)
|
|
|
+ UCSRB |= (0 << RXEN) | (1 << TXEN);
|
|
|
+ // 8 bit char sizes
|
|
|
+ UCSRC |= (1 << UCSZ0) | (1 << UCSZ1);
|
|
|
+ // Set baud rate
|
|
|
+ UBRRH = (BAUD_PRESCALE >> 8);
|
|
|
+ UBRRL = BAUD_PRESCALE;
|
|
|
+
|
|
|
/* Enable Interrupts */
|
|
|
sei();
|
|
|
}
|
|
@@ -246,6 +281,35 @@ void dotOnPersistent(void) {
|
|
|
PORTD |= DOT_PIN;
|
|
|
}
|
|
|
|
|
|
+static void dhtStart(void) {
|
|
|
+ RTOS_SetTask(dhtBegin, 2, 0);
|
|
|
+ DHT_PIN_LOW;
|
|
|
+}
|
|
|
+
|
|
|
+static void dhtBegin(void) {
|
|
|
+ DHT_PIN_INPUT;
|
|
|
+ TCNT1 = 0;
|
|
|
+ OCR1A = DHT_TIMEOUT;
|
|
|
+ TIMER1_ON;
|
|
|
+}
|
|
|
+
|
|
|
+static void dhtEnd(void) {
|
|
|
+ uint8_t i;
|
|
|
+ char buffer[8];
|
|
|
+
|
|
|
+ usart_puts("DHT22 timing data:\r\n");
|
|
|
+
|
|
|
+ for (i=0; i<DHT_MAX_COUNT; i++) {
|
|
|
+ itoa(dhtBuf[i], buffer, 10);
|
|
|
+ usart_puts(buffer);
|
|
|
+ usart_puts(RETURN_NEWLINE);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void dhtTimeout(void) {
|
|
|
+ usart_puts("DHT22 Timeout reached.\r\n");
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* @brief Обработка кнопок.
|
|
|
* @param : None
|
|
@@ -529,6 +593,20 @@ static void valDecrease(uint8_t * val, uint8_t max) {
|
|
|
*val = ((bin / 10 ) << 4) | (bin % 10);
|
|
|
}
|
|
|
|
|
|
+void usart_putc (char send) {
|
|
|
+ // Do nothing for a bit if there is already
|
|
|
+ // data waiting in the hardware to be sent
|
|
|
+ while ((UCSRA & (1 << UDRE)) == 0) {};
|
|
|
+ UDR = send;
|
|
|
+}
|
|
|
+
|
|
|
+void usart_puts (const char *send) {
|
|
|
+ // Cycle through each character individually
|
|
|
+ while (*send) {
|
|
|
+ usart_putc(*send++);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* П р е р ы в а н и я
|
|
@@ -622,6 +700,32 @@ ISR(TIMER2_COMP_vect) {
|
|
|
}
|
|
|
#endif // USE_BRIGHT_CONTROL
|
|
|
|
|
|
+/**
|
|
|
+ * @brief DHT input capture
|
|
|
+ */
|
|
|
+ISR(TIMER1_CAPT_vect) {
|
|
|
+ static uint8_t count = 0;
|
|
|
+ static uint16_t old_tcnt = 0;
|
|
|
+
|
|
|
+ dhtBuf[count] = (uint8_t)(ICR1 - old_tcnt);
|
|
|
+ old_tcnt = ICR1;
|
|
|
+ count ++;
|
|
|
+ if (count == DHT_MAX_COUNT) {
|
|
|
+ TIMER1_OFF;
|
|
|
+ old_tcnt = 0;
|
|
|
+ count = 0;
|
|
|
+ RTOS_SetTask(dhtEnd, 0, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief DHT timeout
|
|
|
+ */
|
|
|
+ISR(TIMER1_OVF_vect) {
|
|
|
+ TIMER1_OFF;
|
|
|
+ RTOS_SetTask(dhtTimeout, 0, 0);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* @brief заглушка для неиспользуемых прерываний
|
|
|
*/
|