Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Odczyt busy flag z wyświetlacza LCD HD44780

Cinis 12 Lut 2016 21:08 510 1
  • #1 12 Lut 2016 21:08
    Cinis
    Poziom 4  

    Witajcie :)

    Od rana próbuje zmusić wyświetlacz do pracy na maksymalnej prędkości. Niestety, każda próba odczytu bitu BF powoduje ,ze program się wysypuje? Tzn zaczyna wypisywać wyrazy w jednym wierszu (nie chce nawet "wejść" na drugi) pomimo ,że w międzyczasie zmieniam adres wskaźnika, po dłuższym czasie na wyświetlaczu robi się bałagan.

    Wszystko działa prawidłowo, kiedy podłączam pin RW do masy i stosuje sztywne opóźnienia, wtedy mogę ładnie formatować tekst.

    Co mniej ciekawe dla mnie, program "wysypuje się" nawet wtedy, kiedy stosuję podwójne ograniczenie tzn:

    Code:

      int i=0;
      for(;i<200000;i++);
     while(LCD_ReadStatus() & (1<<7) );


    Rozumiem ,że problemem jest moja funkcja LCD_ReadStatus... Ale nie wiem dokładnie gdzie robię błąd. Po zmianie pinów na wejścia pracują one prawidłowo. Sprawdzałem to podając "ręcznie" napięcie lub masę na pin i obserwację zakładki Expression w Eclipsie- w trybie debug.

    Funkcja LCD_ReadStatus

    Code:
    unsigned char LCD_ReadStatus(void)
    
    {
      unsigned char status = 0;

      LCD_RS_bb=0;

      gpio_pin_cfg(LCD_GPIO, LCD_pin_d4, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d5, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d6, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d7, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value);

      LCD_D4_bb=1;
      LCD_D5_bb=1;
      LCD_D6_bb=1;
      LCD_D7_bb=1;

      LCD_RW_bb=1;
      LCD_EN_bb=1;


      status |= (LCD_ReadNibble() << 4);
      LCD_EN_bb=0;
      LCD_EN_bb=1;

      status |= LCD_ReadNibble();
      LCD_EN_bb=0;


      gpio_pin_cfg(LCD_GPIO, LCD_pin_d4, GPIO_CRx_MODE_CNF_OUT_PP_2M_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d5, GPIO_CRx_MODE_CNF_OUT_PP_2M_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d6, GPIO_CRx_MODE_CNF_OUT_PP_2M_value);
      gpio_pin_cfg(LCD_GPIO, LCD_pin_d7, GPIO_CRx_MODE_CNF_OUT_PP_2M_value);

      return status;
    }



    Funkcja ReadNibble

    Code:
    unsigned char LCD_ReadNibble(void)
    
    {
      unsigned char tmp = 0;


      tmp |= (LCD_D4_bbi << 0);
      tmp |= (LCD_D5_bbi << 1);
      tmp |= (LCD_D6_bbi << 2);
      tmp |= (LCD_D7_bbi << 3);



      return tmp;
    }



    Przykład inicjalizacji pinu

    Code:
    #define LCD_D7_bbi                        bitband_t m_BITBAND_PERIPH(&LCD_IDR, LCD_pin_d7)
    

    #define LCD_D7_bb                        bitband_t m_BITBAND_PERIPH(&LCD_ODR, LCD_pin_d7)   


    Za wszelaką pomoc dziękuję :)

    0 1
  • #2 12 Lut 2016 22:06
    BlueDraco
    Specjalista - Mikrokontrolery

    Jeśli chcesz uzyskać minimalny narzut czasu procesora na obsługę wyświetlacza - w ogóle nie czytaj znacznika BUSY, bo jego wyzerowanie nie oznacza gotowości. Obsługuj wyświetlacz w przerwaniu timera. Jakiś czas temu obsługa HD44780 na STM32 w przerwaniu timera była pokazana w EP.

    A pierwszy błąd w Twoim kodzie jest tu:

    LCD_EN_bb=0;
    LCD_EN_bb=1;

    - wymagany odstęp 250 ns, nie jedyny zresztą.

    0
  Szukaj w 5mln produktów