Easyelectronics.ru

Электроника для всех
Текущее время: 06 дек 2019, 02:52

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
 Заголовок сообщения: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 00:27 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
Друзья, уже всю голову сломал, 100500 вариантов перебрал, но к истине не приблизился.

При отображении инфы от датчика программа отрабатывает ровно один раз, хотя должна валить в бесконечный цикл. Отлаживаю в CCS5.5, но пробовал и в C::B, никакой разницы. Код вот такой:

Код:

/*
* This program will interface with the DHT22 Temperature and Humidity sensor using propriatory 1-wire
* interface on Pin P1.0 and Timer A1
* When MCU send start signal, RHT03 change from standby-status to running-status. When MCU finish sending the
* start signal, RHT03 will send response signal of 40-bit data that reflect the relative humidity and
* temperature to MCU.
* MCU will pull low data-bus and this process must beyond at least 1~10ms to ensure RHT03 could detect MCU's signal,
* then MCU will pulls up and wait 20-40us for RHT03's response.
* When RHT03 detect the start signal, RHT03 will pull low the bus 80us as response signal, then RHT03 pulls up
* 80us for preparation to send data.
*
* DHT22 is connected to P2.0 to read it through TA1.0 capture mode
* Data from DHT22 flow MSB to LSB, so the High byte (MSB) first then the Low byte of the 16 bit value of
* Humidity and heat.
* The information we need is represented in the high pulse durations.
* Accordingly, we only care about measuring the high pulses duration only
*       -----------------------------------------------------------------------------
*       | This code runs at 8Mhz to ensure capturing the DHT22 pulse width correctly |
*       -----------------------------------------------------------------------------
*/

#include "msp430g2553.h"
#include "hd44780.h"

#define   ISR_DELAY         0         // Timer A1 ISR modes
#define   ISR_DHT22_READ      1

#define   DHT22_DATA_SIZE      5         // Size of the DHT22 data received in bytes (Hum 2, Temp 2 and checksum 1)
#define   DHT22_HIGH_DATA_THRESHOLD   50   // dht22 data high pulse duration threshold to decide on data being 0 or 1
                              // The ZERO bit high pulse width is 26us and the ONE bit high pulse width
                              // is 73us. So, the decision to decide if this is one or zero can be taken
                              // at thresold 50us
#define   TRUE            1
#define   FALSE            0

typedef enum {START_LOW, START_HIGH, DATA_LOW, DATA_HIGH} DHT22_STATES;
DHT22_STATES dht22_state = START_LOW;
DHT22_STATES  previous_dht22_state;         // Store previous DHT22 data parsing state

unsigned char dht22[5];
volatile unsigned int new_cap=0;
volatile unsigned int old_cap=0;
volatile unsigned char TimerA1_ISR_mode = ISR_DELAY;
volatile unsigned char bit_counter;            // keeps track of the data pulses parsed (maximum 40 bits)
volatile unsigned char byte_counter;         // keeps track of the data pulses parsed (maximum 5 bytes)
volatile unsigned char pulse_duration;         // duration in uS of the DHT22 generated pulse data

unsigned char   delay_in_progress=FALSE;

float Temp, Humidity;

void usdelay(unsigned int interval){
   TimerA1_ISR_mode = ISR_DELAY;
                        // Setup TimerA
   TA1CCTL0 = CCIE;              // interrupt enabled
   TA1CCR0 = TA1R + 8*interval;// micro secs @ 8Mhz Clock
   TA1CTL = TASSEL_2 + MC_2;     // SMCLK, continuous mode.
   delay_in_progress = TRUE;   // Indicate to other ISRs that they should not wake the CPU when triggered as the
                        // CPU is currently sleeping waiting for a delay to expire
   __bis_SR_register(CPUOFF + GIE);                  // suspend CPU
   //LPM0;
}

/*
* This Timer A1 interrupt handles two functions:
* - Generate uS delays
* - Read DHT22 sensor data stream in capture mode and store it in an array for later parsing
*/
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer_A1_ISR (void)
{
   if (TimerA1_ISR_mode == ISR_DELAY) {
       TA1CTL = 0;               // Stop Timer_A0
       delay_in_progress = FALSE;   // Indicate to other ISRs that they can wake the CPU now if needed
       __bic_SR_register_on_exit(CPUOFF);
       LPM0_EXIT;               // Return active
   }

   if (TimerA1_ISR_mode == ISR_DHT22_READ) {
      switch (dht22_state) {
         case START_LOW:                     // we receive a low pulse start from the DHT22
            dht22_state = START_HIGH;         // be ready to receive a high pulse start
                                       // Initialize DHT22 readings array
            for (byte_counter = 0; byte_counter < DHT22_DATA_SIZE; byte_counter++) {
               dht22[byte_counter]=0;
            }
            bit_counter = 0;               // reset DHT22 data bit counter within a byte
            byte_counter = 0;               // reset DHT22 data byte counter
            break;

         case START_HIGH:
            previous_dht22_state = dht22_state;
            dht22_state = DATA_LOW;            // be ready to receive a low pulse data
            break;

         case DATA_LOW:
            if (previous_dht22_state == DATA_HIGH){   // if we were previously in a dht22 high data pulse, then parse it
               new_cap = TA1CCR0;               // Store current time stamp (timer value)
                                          // store the length of the previous high pulse
               pulse_duration = (new_cap - old_cap)/8;
               dht22[byte_counter]<<=1;         // shift left to leave a space for the new bit
               if (pulse_duration > DHT22_HIGH_DATA_THRESHOLD){
                  dht22[byte_counter] |= BIT0;   // This is a ONE bit
               } else {
                  dht22[byte_counter] &= ~BIT0;   // This is a ZERO bit
               }
               bit_counter++;               // We passed one date bit, then increment counter
               if (bit_counter == 8) {         // Finished filling one byte, then move to next byte
                  byte_counter++;
                  bit_counter = 0;
                  if (byte_counter == DHT22_DATA_SIZE){
                                       // disable interrupt and wake processor
                     TA1CTL = 0;            // Stop Timer_A1
                     dht22_state = START_LOW;// rest to the initial state
                     LPM0_EXIT;            // Return active
                     break;
                  }
               }
            }
            dht22_state = DATA_HIGH;         // move to the next state
            break;

         case DATA_HIGH:
            old_cap=TA1CCR0;               // Store the start of the high data pulse
            previous_dht22_state = dht22_state; // As this is what contains the information we need
            dht22_state = DATA_LOW;
            break;

         default:
            break;
      }
   }
}

void read_DHT22(void){
   unsigned int T,H;
   P2OUT &= ~BIT0;                        // Issue start signal, P2.0 output low
   usdelay(1000);                        // Wait 1ms to ensure that DHT22 has detected it

                                    // Now listen to the data coming from the DHT22
   TimerA1_ISR_mode = ISR_DHT22_READ;         // Set ISR mode as parsing DHT22 data
   P2SEL |= BIT0;                          // P2.0 option select Timer_A1
   P2DIR &= ~BIT0;                          // P2.0 as input.
   TA1CTL = TASSEL_2 + MC_2 + TAIE;           // SMCLK, continuous mode, enable overflow interrupt
   TA1CCTL0 = CM_3 + SCS + CCIS_0 + CAP + CCIE;
                                                          // Rising and falling edges, capture synchronize, capture mode.
                                               // Interrupt enabled

   LPM0;                                 // Sleep CPU (LPM0 as the DHT22 parser is using SMCLK)
                                    // and let the Timer A1 ISR parse the data coming to it in capture mode
                                    // Once all data is read, the ISR will wakeup the CPU to present
   usdelay(1000);                        // the collected data.
   TimerA1_ISR_mode = ISR_DELAY;
                                    // See if checksum is correct
   if (dht22[4]=dht22[0]+dht22[1]+dht22[2]+dht22[3]) {
      H=dht22[0]<<8;
      Humidity = (H + dht22[1])/10;
      T=dht22[2]<<8;
      Temp = (T + dht22[3])/10;
   }
}


void main(void){

//   WDTCTL = WDTPW + WDTHOLD;
   WDTCTL = WDTPW + WDTTMSEL;                  // WDT as interval timer,
                                                // f = SMCLK / 32768
                                    //Calibrate DCO for 8MHz operation
   BCSCTL1 = CALBC1_1MHZ;
   DCOCTL = CALDCO_1MHZ;

   HD44780_Init();
//   HD44780_Clear_Screen();




   while(1) {

      BCSCTL1 = CALBC1_8MHZ;
      DCOCTL = CALDCO_8MHZ;
//      __enable_interrupt();                  // Enable global interrupt
      P2OUT |= BIT0;                        // P2.0 output high
      P2DIR |= BIT0;                        // P2.0 as output
      read_DHT22();
//      __disable_interrupt();
      BCSCTL1 = CALBC1_1MHZ;
      DCOCTL = CALDCO_1MHZ;

      HD44780_SetPosition(0,0);
      HD44780_PrintStr("Temp:");
      HD44780_SetPosition(1,0);
      HD44780_PrintStr("Humidity:");

      HD44780_SetPosition(0, 6);
      HD44780_outdec(Temp*100, 2);
      HD44780_SetPosition(1, 10);
      HD44780_outdec(Humidity*100, 2);

      HD44780_SetPosition(0,10);
      HD44780_PrintStr("C ");
      HD44780_SetPosition(1,14);
      HD44780_PrintStr("% ");

//      __enable_interrupt();                  // Enable global interrupt
      usdelay(1000);
   }
}



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 00:33 
Старожил
Аватара пользователя

Зарегистрирован: 13 дек 2010, 23:15
Сообщения: 2077
Откуда: Киев
Так ответить сложно. На каком шаге зависает программа?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 00:59 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
зависает после отображения всей информации, из конца цикла в начало не переходит. Отрабатывает ровно до того момента, когда должен был бы новый цикл начаться, но вот нет...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 01:02 
Старожил
Аватара пользователя

Зарегистрирован: 13 дек 2010, 23:15
Сообщения: 2077
Откуда: Киев
Если я правильно понял, то
Код:
//      __enable_interrupt();                  // Enable global interrupt
      usdelay(1000);

usdelay использует прерывания, а у вас строчка включить прерывания закоментирована.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 01:05 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
а, это я по-всякому менял, убирал/добавлял строчку с паузой, включал/выключал прерывания. Там где закомменитировано, - это как раз попытка определить, что именно приводит к зависанию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 12:00 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
Трабла скорее всего кроется в режимах сна, так как если отключить процедуру чтения инфы с датчика, - цикл прекрасно работает. Как такое может быть, что после чтения процессор засыпает, выполняя первый цикл?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 12:19 
Старожил
Аватара пользователя

Зарегистрирован: 13 дек 2010, 23:15
Сообщения: 2077
Откуда: Киев
У меня такое на ардуйне было( точнее енергия для ланч пад), точно не вспомню но надо очень внимательно перечитать про режимы сна, что тактируется, а что нет. А также как правильно из них выходить.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 12:58 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
Почему тогда выполняется содержимое цикла, но только один раз? Если бы не просыпался процессор, наверное совсем бы не выполнялся, и на индикаторе ничего бы не было. Я провёл эксперимент, заменив МК на 2452, теперь реально процессор засыпает после ухода в процедуру чтения информации с датчика, или в процедуру задержки...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 16:22 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
Проблема немножко локализовалась. Зависание происходит на повторном вызове чтения с датчика, либо на процедуре задержки usdelay(),что там может быть не так? нашёл древнюю тему вот здесь, но всё, что там описано, к желаемому эффекту не приводит.

Пишут вот что:
Цитата:
Shame on me. How didn't I see this one. I scanned the code, and found a similar case as well where an "=" should have been an "==" as well in an if statement that was checking the checksum condition. After these adjustment, still the code did not work. So, I put some debugging counters in the ISR trying to find out how it behaves, and interestingly discovered that it is not being invoked at all when the read_DHT22 is called for the second time. This made me suspect that the DHT22 was not responding at all after the first call with any data, which I discovered was the case, and for a simple reason that it was not receiving the low "start" pulse. That is because when switching back and forth between the timer A1 being configured as a compare or a capture mode, I forgot to configure the corresponding PIN properly with respect to the DIR and SEL bits. Once I corrected this one too, it worked properly, and I am was able to invoke the same function multiple times successfully.


Надеюсь на хелп сообщества...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 17:09 
Заглядывает иногда

Зарегистрирован: 05 апр 2011, 21:18
Сообщения: 190
В этой строке "if (dht22[4]=dht22[0]+dht22[1]+dht22[2]+dht22[3])" Вы сравниваете или присваиваете значение? Если сравниваете то должно быть "if (dht22[4]==dht22[0]+dht22[1]+dht22[2]+dht22[3])"


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 17:18 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
_guardianangel писал(а):
В этой строке "if (dht22[4]=dht22[0]+dht22[1]+dht22[2]+dht22[3])" Вы сравниваете или присваиваете значение? Если сравниваете то должно быть "if (dht22[4]==dht22[0]+dht22[1]+dht22[2]+dht22[3])"


здесь одновременно присвоение и сравнение с нулём, то есть по факту - проверка контрольной суммы. значение выражения справа присваивается переменной dht[4] и проверяется на то, чтобы быть ненулевым.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 17:28 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
Трабла вот какая. Всё работает, кроме повторного вызова функции read_DHT22, на ней - программа виснет...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 03 апр 2014, 20:07 
Заглядывает иногда

Зарегистрирован: 05 апр 2011, 21:18
Сообщения: 190
Посмотрите errata на 2553. Там говорится что при переключение значения RSEL = 14 и больше на значение меньше 13 может произойти остановка модуля тактирования. Переключаться надо сначало на значение 13, затем на требуемое. У Вас как раз происходит переключение тактовой с 8 МГц на 1 МГц.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: dht21+hd44780 зависает, не работает в цикле.
СообщениеДобавлено: 04 апр 2014, 15:09 
Только пришел

Зарегистрирован: 14 июл 2013, 21:19
Сообщения: 20
не, собака где-то в другом месте зарыта. Перешёл полностью на 8МГц, в десять раз увеличил задержки для обмена с индикатором (по сравнению с необходимыми по ДШ hd44780), и как-то оно заработало. Надо копать в направлении задержек, только в нужное место, а не куда придётся, что-то из моего салата не успевало восстановиться после первого цикла чтения, осталось разобраться только, в какое место правильно впихнуть задержку.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB