Отговори на тема  [ 27 мнения ]  Отиди на страница 1, 2  Следваща
Драйвери за матрични дисплеи 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение Драйвери за матрични дисплеи
Здравейте.
От няколко дни безуспешно се мъча да покарам въпросния дисплей. Изпровах повечето известни библиотеки, но резултатите бяха трагични - или не изписва текста който е въведен, или излизат странни символи.
В карйна сметка реших да разбера как се командва дисплея...Написах малка програмка за тестване, чиито код е базиран на обяснения събирани през интернет. Проблема е че отново някъде нещо пропускам или греша.
Моля тези от вас, които са успели да използват ЛЦД дисплей 2х16 базиран на HD44780 да споделят своя опит.
ето и въпросната тестова програма
Код:
#define F_CPU   8000000
#include <avr/io.h>
#include <util/delay.h>

#define RS_PIN   5
#define E_PIN   4

#define RS_LOW   PORTC |= _BV(RS_PIN)
#define RS_HI   PORTC &= ~_BV(RS_PIN)

#define E_LOW   PORTC |= _BV(E_PIN)
#define E_HI   PORTC &= ~_BV(E_PIN)

void lcd_low(unsigned char data);
void lcd_hi(unsigned char data);
void lcd_pulse_e();
void lcd_cmd(unsigned char cmd);
void lcd_char(unsigned char data);
void lcd_string(unsigned char *data);

void lcd_hi(unsigned char data) {
  PORTC = (PORTC & 0xf0) |((data & 0xf0) >> 4);
}

void lcd_low(unsigned char data) {
  PORTC = (PORTC & 0xf0) | (data&0x0F);
}

void lcd_init() {
  DDRC = 0b00111111;
  _delay_ms(300);
 
  RS_LOW;
  lcd_hi(0x20);
  lcd_pulse_e();
  _delay_ms(100);

  lcd_cmd(0x28);

  _delay_us(110);
  lcd_cmd(0x0f);

  _delay_us(110);
  lcd_cmd(0x01);

  _delay_us(110);
  lcd_cmd(0x06);

    _delay_us(110);
  lcd_cmd(0x80);
  lcd_char('A');
}

void lcd_string(unsigned char *data) {
  while (*data != 0) {
    lcd_char(*data);
    data++;
  }
}

void lcd_char(unsigned char data) {
  RS_HI;
  lcd_hi(data);
  lcd_pulse_e();
  _delay_us(100);
  lcd_low(data);
  lcd_pulse_e();
}

void lcd_cmd(unsigned char cmd) {
  RS_LOW;
  lcd_hi(cmd);
  lcd_pulse_e();
  _delay_us(100);
  lcd_low(cmd);
  lcd_pulse_e();
}

void lcd_pulse_e() {
  E_HI;
  _delay_us(100);
  E_LOW;
}


int main() {
  lcd_init();
  lcd_string("tova e test\0");
  return 0;
}



Ето и схемата на свързване
Код:
Дисплей                    МЦУ
                                 PORT C
д5                              0
д6                              1
д7                              2
д8                              3
RS                              5
Е                                4

Благодаря за отделеното внимание![/code]


Сря Дек 24, 2008 12:04 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Проблема е решен!
Поствам отново тестова програма за тези от вас, които имат проблем с подкарването на LCD 16х2 (Ampire AC-162B).
(Незнайно защо, упорито отказват да работят библиотеките които намерих в нет-а...включително и вградената библиотека на БАСКОМ)

Код:
#define F_CPU   8000000
#include <avr/io.h>
#include <util/delay.h>

#define RS_PIN   5
#define E_PIN   4

#define RS_HI   PORTC |= _BV(RS_PIN)
#define RS_LOW   PORTC &= ~_BV(RS_PIN)

#define E_HI   PORTC |= _BV(E_PIN)
#define E_LOW   PORTC &= ~_BV(E_PIN)

void lcd_low(unsigned char data);
void lcd_hi(unsigned char data);
void lcd_pulse_e();
void lcd_cmd(unsigned char cmd);
void lcd_char(unsigned char data);
void lcd_string(char *data);


void lcd_xy(unsigned char x, unsigned char y) {
if (y <= 1) {
    lcd_cmd(0x80 + x);
} else {
    lcd_cmd(0xC0 +  x);
}
}
void lcd_hi(unsigned char data) {
  PORTC = (PORTC & 0xf0) |((data >>4) & 0x0f);
}

void lcd_low(unsigned char data) {
  PORTC = (PORTC & 0xf0) | (data&0x0F);
}

void lcd_init() {

  DDRC = 0xff;
  PORTC = 0x00;
  _delay_ms(200);
 

  lcd_cmd(0x00);
  _delay_ms(15);

  lcd_cmd(0x20);
  lcd_pulse_e();
  _delay_ms(5);


  _delay_ms(5);


  lcd_cmd(0x28);
  lcd_pulse_e();
  _delay_ms(5);


  lcd_cmd(0x06);
  lcd_pulse_e();
  _delay_us(100);


  lcd_cmd(0x0f);
  lcd_pulse_e();
  _delay_us(100);

  lcd_cmd(0x01);
  lcd_pulse_e();
  _delay_us(100);

}

void lcd_string(char *data) {
  while (*data != 0) {
    lcd_char(*data);
    data++;
  }
}

void lcd_char(unsigned char data) {
  _delay_us(100);
  RS_HI;
  _delay_us(100);
  lcd_hi(data);
  lcd_pulse_e();
  _delay_us(1000);
  lcd_low(data);
  lcd_pulse_e();
}

void lcd_cmd(unsigned char cmd) {
  RS_LOW;
  lcd_hi(cmd);
  lcd_pulse_e();
  _delay_us(100);
  lcd_low(cmd);
  lcd_pulse_e();
  _delay_us(100);
}

void lcd_pulse_e() {
  E_HI;
  _delay_us(1000);
  E_LOW;
}


int main() {
  lcd_init();
  lcd_string("tova e test\0");
  lcd_xy(0,2);
  lcd_string("vtori red!\0");
  _delay_ms(3000);
  lcd_xy(0,0);
  lcd_string("Otnovo na red 1\0");
  return 0;
}



Весели празници!


Чет Дек 25, 2008 12:49 am
Профил
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Пон Яну 09, 2006 11:32 am
Мнения: 276
Местоположение: Kozloduy
Мнение 
Радвам се че си успял да си решиш проблема САМ, много хора прекалено много разчитат на чужда помощ. Между другото не знам да ли си търсил из форума подобни проблени са били обсъждани и най че сто причината да не тръгват тези дисплеи е недостатъчни закъснения или контраста на дисплея.


Чет Дек 25, 2008 3:09 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Аз използвам прикачения драйвер. Много е добър, поддържа всичко и се конфигурира 100%. При мен (mega16 и 20х4 дисплей) тръгна от първия път (софтуерно). :)


Прикачени файлове:
lcd.zip [7.72 KiB]
459 пъти
Съб Дек 27, 2008 12:17 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Този драйвер беше един от първите които тествах.. Дисплея не "запали" с него. (дори и времезадръжките увеличавах, но нямаше ефект)
Имам чувството, че дисплеите на Ampire са нещо малко по странни.
Имам направен проект с 128х64 дисплей отново на същата фирма, който отново тръгна с голяяям зор.


Съб Дек 27, 2008 1:49 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Сря Фев 06, 2013 10:25 am
Мнения: 197
Мнение Re: C, atmega8 и hd44780 LCD проблемче
Здравейте,

Използвам LCD библиотеката на колегата Michev. Всичко за сега работи както трябва.
Добавих възможност, за зареждане на потребителси дефинирани знаци.
Зареждам 8 знака. Първите 3 не се показват коректно.
Предположих, че проблема може да е в това, че пазя данните в програмната памет. Прочетох данните. Изглеждат ОК.

Играх си с таймингите, но няма ефект. Предостатъчно са удължени.
Едва ли проблема е от тайминг, защото всички останали символи се печатат правилно и няма черги по екрана.

Намерих заобиколен начин да си реша проблема. Зареждам два пъти и всичко се оправя, но ми се иска да знам причината за проблема и да я оправя.

Прилагам кода и снимка на грешните знаци.
Изображение


Прикачени файлове:
lcd.h [1.63 KiB]
494 пъти
lcd.c [3.12 KiB]
485 пъти
Сря Юли 03, 2013 11:30 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение Re: Драйвери за матрични дисплеи
Позволих си да преместя и прекръстя темата. :) Мисля, че ще бъде полезно на мнозина.


Пет Юли 05, 2013 4:24 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение Re: Драйвери за матрични дисплеи
Ами преди година и нещо и аз слагах някакъв такъв май дисплей, 4 реда.
Не помня да имаше някакво чудене, трябва да е станало за малко над колкото
ми е било нужно да напиша текста. Ама ето го, на асемблер за coldfire,
може и да е полезно някому (и се чете по-лесно от C код дори от C писачи :D ):

http://tgi-sci.com/misc/lcd4r.sa

То не е дълго всъщност, ей го и изцъркано тука:

Код:
*
*
* display on - turn display power on, initialize it etc.
*
dispon:
         push      d1,a0               save regs
         bsr.w     dion      turn display power on
* wait for >15 mS
        move.l     #30000,d0 30mS time
         scall     xtwt$     make sure to wait that long
         moveq     #$30,d1   wakeup command
         bsr.w     dispcmd   issue display command
         bcs       retdpon   if error
         move.l    #$200000,d1 to wait 160 mS or so
         scall     xtwt$     wait
         moveq     #$38,d1   8 bit mode, 2 lines
         bsr.w     dispcmd   issue command to display
         bcs       retdpon   if error
         moveq     #$c,d1    display on, cursor on (to test)
         bsr.w     dispcmd
         bcs       retdpon   if error
         moveq     #$6,d1    to set increment mode
         bsr.w     dispcmd   do so
         bcs       retdpon   if error
         moveq     #1,d1     clearhome
         bsr.w     dispcmd   
*
retdpon
         pull      d1,a0     restore regs
         rts                 *return*
*
* output a message formatted as:
* X coord byte, y coord byte, length, text
* a0 -> message beg. (the x coord length)
*
pmsg0
         push      d1-d3,a0  save regs
         clr.l     d1
         clr.l     d2
         clr.l     d3        zero extend all
         move.b    (a0)+,d1  x coord                                                               
         move.b    (a0)+,d2  y coord
         move.b    (a0)+,d3  length
         bsr       pmsg123   do display the message
         pull      d1-d3,a0  restore regs
         rts       *return*
*
*
* output a message starting at d1,d2 coords.
* a0 -> message; length is in d3
*
pmsg123:
         push      d1-d3,a0
         and.l     #$1f,d1   make sure to have just a X coord (actually 24 is the max.)
         and.l     #$3,d2    and an Y one
         move.l    d3,d0     length extra copy
         cmp.l     #linelen,d1         within line?
         bcc       retpmg3   branch not, nothing to be shown
         add.l     d1,d0     x coord past string end
         sub.l     #linelen,d0  negative no. of characters going past line end
         bls       llnok1    if non, length is OK
         sub.l     d0,d3     show only those showable
llnok1
         clr.l     d0        zero extend
         move.b    ((lbegtb).b,pc,d2),d0   take line beg. address
         add.l     d0,d1     beg. address to write to
         bset      #7,d1     to issue as "set address" command
         bsr       dispcmd   do so
         bcs       retpmg3   if error
* output the data now
         set       loop,*
         move.b    (a0)+,d0  a character
         bsr       putdd0    output it
         bcs       retpmg3   if error
         subq.l    #1,d3     count down
         bgt       loop      if more
retpmg3
         pull      d1-d3,a0
         rts       *return*
*
lbegtb   dc.b      0,$40,$14,$54
*
putddp
         set       loop,*
         clr.l     d0
         move.b    (a0)+,d0  pickup a data byte
         cmp.l     #eot,d0   CR (end of string)?
         beq       endpudd   branch yes
         bsr       putdd0    send to display
         bra       loop
endpudd
         rts       *return*
*
* output d0 to current dsiplay address
* putdd0
*
putdd0
         push      d0-d2     save regs
         lea       (gp_beg+ipsbarv).l,a3         point to gpio port
         move.l    #200000,d2          200 mS timeout
         bsr       wairdy              wait for ready
         bcs       retpudd             if error
         moveq     #$f4,d2             
         move.b    d2,(gp_cltc,a3)     E, a0, R/W all 0
         moveq     #$8,d2            to set a0 high
         move.b    d2,(gp_sptc,a3)
         moveq     #$ff,d2   all ones to write
         move.b    d2,(gp_dddd,a3)     data bits are outputs now
         move.l    (a7),d0   recall data
         move.b    d0,(gp_podd,a3)     do output the data
         moveq     #$2,d2              to set E high
         move.b    d2,(gp_sptc,a3)     do so
         tst.b     (gp_spdd,a3)       just some time holding E high
         tst.b     (gp_spdd,a3)       some more (missed characters)
         tst.b     (gp_spdd,a3)       and some more (missed characters)
         not.l     d2                  to clear now
         move.b    d2,(gp_cltc,a3)     then set E back low
retpudd
         pull      d0-d2        restore regs
         rts       *return*
*
* write byte in d1 as a command to the display
*
dispcmd
         move.l    d2,-(a7)  save regs
         lea       (gp_beg+ipsbarv).l,a3         point to gpio port
         move.l    #200000,d2          200 mS timeout
         bsr       wairdy              wait for ready
         bcs       retdicd             if error
         moveq     #$f4,d2             
         move.b    d2,(gp_cltc,a3)     E, a0, R/W all 0
         moveq     #$ff,d2   all ones to write
         move.b    d2,(gp_dddd,a3)     data bits are outputs now
         move.b    d1,(gp_podd,a3)     do output the data
         moveq     #1!<1,d2            to set E high
         move.b    d2,(gp_sptc,a3)     do so
         tst.b     (gp_spdd,a3)        just some time holding E high
         not.l     d2                  to clear now
         move.b    d2,(gp_cltc,a3)     then set E back low
retdicd
         pull      d2        restore regs
         rts       *return*
*
* wait for display to get ready; timeout in d2
* (in microseconds). If no error (no timeout), returns in d0
* the last data read together with the flag (address counter)
*
wairdy
* check for ready
         push      d1-d2               save regs
         move.l    (sy$slic).w,d1     
         divu.l    d1,d2               no. of slices to wait
         add.l     (sy$time).w,d2      timeout moment
*
         clr.b     (gp_dddd,a3)        all inputs
         moveq     #$f4,d1             
         move.b    d1,(gp_cltc,a3)     E, a0, R/W all 0
         moveq     #1!<0,d1  to set R/W high
         move.b    d1,(gp_sptc,a3)  set R/W high
         set       loop,*
         moveq     #1!<1,d1            to set E high
         move.b    d1,(gp_sptc,a3)     do so
         tst.b     (gp_spdd,a3)        just some delay
         tst.b     (gp_spdd,a3)        some more delay
         move.b    (gp_spdd,a3),d0     read data
         not.l     d1        to clear it now
         move.b    d1,(gp_cltc,a3)     then set E back low
         btst      #7,d0               ready?
         beq       isrdy               branch yes, just return
         scall     xtask$    exit task
         cmp.l     (sy$time).w,d2      timeout?
         bcc       loop      if no timeout, wait here
         moveq     #e$tout,d2          else indicate timeout
         moveq     #1,d1     to set carry
         move.w    d1,ccr    do so
isrdy
         pull      d1-d2     restore regs
         rts                 *return*

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Пет Юли 05, 2013 11:20 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение Re: Драйвери за матрични дисплеи
Колеги, тука се получи едно механично нестиковане. :) Има ли начин картинката да се обърне на 180 градуса?


Съб Юли 06, 2013 10:13 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение Re: Драйвери за матрични дисплеи
В документите не се поменава да има такава възможност.
Веднъж от недоглеждане се получи като при теб и от тогава - дисплей задължително с кабел към платката.


Нед Юли 07, 2013 12:56 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение Re: Драйвери за матрични дисплеи
Рек, ако контролера е на Hitachi:
Цитат:
The HD44780U character generator ROM can generate 208 5х8 dot character patterns and
32 5х10 dot character patterns for a total of 240 different character patterns

това е от 15 страница от описанието на HD44780U. Така че със собствени символи може да спасиш
положението ама ще е гърч докато ги направиш.


Прикачени файлове:
HD44780.pdf [322.07 KiB]
391 пъти
Нед Юли 07, 2013 6:56 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение Re: Драйвери за матрични дисплеи
Рек, ако решиш да се гърчиш да правиш знаков генератор и не намериш редактор
мога да ти пусна онлайн една емулация на прастара машина, за която имам (правен
преди 25+ години). Мъка ще е пак разбира се, то и кодът е един от най-нечистите
дето съм писал някога, ама работи някак, виждат се знаците и могат да се редактират.

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Нед Юли 07, 2013 7:00 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение Re: Драйвери за матрични дисплеи
Ки4о, аз що си мисля че има място само за 8 user символа (CGRAM). Другото е ром и незнам как мое се ръчка в него след като веднъж е бил записан.


Нед Юли 07, 2013 7:27 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение Re: Драйвери за матрични дисплеи
Cekins, прав си, но какво ти пречи на ход да сменяш съдържанието на CG RAM-а и да пишеш каквото си искаш ?
Изисква ресурс и си е гърч,но не е невъзможно :)

http://www.circuitvalley.com/2012/02/lc ... -16x2.html
http://deanandara.com/robots/ApuLcd.html


Нед Юли 07, 2013 7:53 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Фев 04, 2005 9:59 pm
Мнения: 6019
Местоположение: София
Мнение Re: Драйвери за матрични дисплеи
Ки4о написа:
Cekins, прав си, но какво ти пречи на ход да сменяш съдържанието на CG RAM-а и да пишеш каквото си искаш ?

Не по-дълго от 8 символа.

_________________
Warriors of the Night, ASSEMBLER!!!


Нед Юли 07, 2013 8:08 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 27 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 0 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни