Проблемма с отображением символов на LCD

помощь начинающим осваивать программирование МК (PIC, AVR) на Си.

Модератор: koolhatcker

Ответить
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Проблемма с отображением символов на LCD

Сообщение ChaiSER »

Нарисовалась такая проблемма (см. фото):

Изображение

Подключёние 4-х битное к PORTC ATmega32. D4-D7 подключены к PC3-PC0 соответственно, тоисть инверсно...
Пробовал подключать две разные библиотеки LCD - результат тот-же. При стандартном подключении D4-D7 -> PC0-PC3 на отладочной плате - всё работает без проблемм.
Вопросс: может ли такое подключение быть причиной данного глюка? Какие ещё есть соображения?

P.S.: Юзаю AVR-GCC
koolhatcker
Смотрящий
Сообщения: 1504
Зарегистрирован: 30 авг 2009, 00:00
Откуда: Омск
Контактная информация:

Re: Проблемма с отображением символов на LCD

Сообщение koolhatcker »

ChaiSER писал(а):Вопросс: может ли такое подключение быть причиной данного глюка?
Естественно. В библиотеке нужно поменять строчки вывода в порт.
Автономный контроллер станка с ЧПУ: http://it-en.ru/cnc
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Re: Проблемма с отображением символов на LCD

Сообщение ChaiSER »

Об этом речь?

Код: Выделить всё

/***************************************************************************/
/*                       define the LCD connections:                       */
/***************************************************************************/
#define	LCD_D4		SBIT( PORTC, 3 )
#define	LCD_DDR_D4	SBIT( DDRC, 3 )

#define	LCD_D5		SBIT( PORTC, 2 )
#define	LCD_DDR_D5	SBIT( DDRC, 2 )

#define	LCD_D6		SBIT( PORTC, 1 )
#define	LCD_DDR_D6	SBIT( DDRC, 1 )

#define	LCD_D7		SBIT( PORTC, 0 )
#define	LCD_DDR_D7	SBIT( DDRC, 0 )

#define	LCD_RS		SBIT( PORTC, 5 )
#define	LCD_DDR_RS	SBIT( DDRC, 5 )

#define	LCD_E0		SBIT( PORTC, 4 )
#define	LCD_DDR_E0	SBIT( DDRC, 4 )

/***************************************************************************/ 
Или нужно править функции в библиотеке?
koolhatcker
Смотрящий
Сообщения: 1504
Зарегистрирован: 30 авг 2009, 00:00
Откуда: Омск
Контактная информация:

Re: Проблемма с отображением символов на LCD

Сообщение koolhatcker »

В библиотеке.
Автономный контроллер станка с ЧПУ: http://it-en.ru/cnc
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Re: Проблемма с отображением символов на LCD

Сообщение ChaiSER »

koolhatcker, покажите что именно копать, по-возможности. Вот файлы библиотеки:

mydefs.h
Показать/Спрятать

Код: Выделить всё

/************************************************************************/
/*                                                                      */
/*                      Several helpful definitions                     */
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                                                                      */
/************************************************************************/
#ifndef _mydefs_h_
#define _mydefs_h_
#include<avr/io.h>


// Access bits like variables
struct bits {
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
} __attribute__((__packed__));
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
#define	SBIT(x,y)       SBIT_(x,y)


// avoid push in main
int main( void )        __attribute__((OS_main));


// always inline function x
#define AIL(x)          static x __attribute__ ((always_inline)); static x


#endif
lcd_lib.h
Показать/Спрятать

Код: Выделить всё

#ifndef LCD_LIB_H
#define LCD_LIB_H

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#include "mydefs.h"

#define	F_CPU	16000000UL	// 16MHz

/***************************************************************************/
/*                       define the wanted LCD type:                       */
/***************************************************************************/
//#define LCD_1X8
//#define LCD_1X16
//#define LCD_1X20
//#define LCD_1X40
//#define LCD_2X8       // some 1x16 are wired as 2x8
//#define LCD_2X12
#define LCD_2X16
//#define LCD_2X20
//#define LCD_2X24
//#define LCD_2X40
//#define LCD_4X16
//#define LCD_4X20

/***************************************************************************/
/*                       define the LCD connections:                       */
/***************************************************************************/
#define	LCD_D4		SBIT( PORTC, 3 )
#define	LCD_DDR_D4	SBIT( DDRC, 3 )

#define	LCD_D5		SBIT( PORTC, 2 )
#define	LCD_DDR_D5	SBIT( DDRC, 2 )

#define	LCD_D6		SBIT( PORTC, 1 )
#define	LCD_DDR_D6	SBIT( DDRC, 1 )

#define	LCD_D7		SBIT( PORTC, 0 )
#define	LCD_DDR_D7	SBIT( DDRC, 0 )

#define	LCD_RS		SBIT( PORTC, 5 )
#define	LCD_DDR_RS	SBIT( DDRC, 5 )

#define	LCD_E0		SBIT( PORTC, 4 )
#define	LCD_DDR_E0	SBIT( DDRC, 4 )

/***************************************************************************/

#ifdef LCD_1X8
#define LCD_COLUMN      8
#define LCD_LINE        1
#define LCD_LINE1       0x80
#endif

#ifdef LCD_1X16
#define LCD_COLUMN      16
#define LCD_LINE        1
#define LCD_LINE1       0x80
#endif

#ifdef LCD_1X20
#define LCD_COLUMN      20
#define LCD_LINE        1
#define LCD_LINE1       0x80
#endif

#ifdef LCD_1X40
#define LCD_COLUMN      40
#define LCD_LINE        1
#define LCD_LINE1       0x80
#endif

#ifdef LCD_2X8
#define LCD_COLUMN      8
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_2X12
#define LCD_COLUMN      12
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_2X16
#define LCD_COLUMN      16
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_2X20
#define LCD_COLUMN      20
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_2X24
#define LCD_COLUMN      24
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_2X40
#define LCD_COLUMN      40
#define LCD_LINE        2
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#endif

#ifdef LCD_4X16
#define LCD_COLUMN      16
#define LCD_LINE        4
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#define LCD_LINE3       (0x80 + 0x10)
#define LCD_LINE4       (0x80 + 0x50)
#endif

#ifdef LCD_4X20
#define LCD_COLUMN      20
#define LCD_LINE        4
#define LCD_LINE1       0x80
#define LCD_LINE2       (0x80 + 0x40)
#define LCD_LINE3       (0x80 + 0x14)
#define LCD_LINE4       (0x80 + 0x54)
#endif

#define	LCD_TIME_ENA    1.0             // 1µs
#define LCD_TIME_DAT    50.0            // 50µs
#define LCD_TIME_CLR    2000.0          // 2ms

/***************************************************************************/


#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))


extern void lcd_init(void);
extern void lcd_putchar(uint8_t d);
extern void lcd_puts(void *s);					// display string from SRAM
extern void lcd_puts_p(const char *str);		// display string from FLASH
extern void lcd_blank(uint8_t len);				// blank n digits
extern void lcd_command(uint8_t d);


#if 0
AIL( void lcd_xy( uint8_t x, uint8_t y ))       // always inline function 
{
#ifdef LCD_LINE2
  if( y == 1 )
    x += LCD_LINE2 - LCD_LINE1;
#ifdef LCD_LINE3
  if( y == 2 )
    x += LCD_LINE3 - LCD_LINE1;
#ifdef LCD_LINE4
  if( y == 3 )
    x += LCD_LINE4 - LCD_LINE1;
#endif  
#endif  
#endif  
  lcd_command( x + LCD_LINE1 );
}
#else

#ifdef LCD_LINE4
#define lcd_xy(x, y)    lcd_command((x) + ((y==3) ? LCD_LINE4 : \
                                           (y==2) ? LCD_LINE3 : \
                                           (y==1) ? LCD_LINE2 : LCD_LINE1 ))
#else
#ifdef LCD_LINE3
#define lcd_xy(x, y)    lcd_command((x) + ((y==2) ? LCD_LINE3 : \
                                           (y==1) ? LCD_LINE2 : LCD_LINE1 ))
#else
#ifdef LCD_LINE2
#define lcd_xy(x, y)    lcd_command((x) + ((y==1) ? LCD_LINE2 : LCD_LINE1 ))
#else
#define lcd_xy(x, y)    lcd_command((x) + LCD_LINE1 )
#endif  
#endif  
#endif  

#endif


//Макроопределения для установки курсора
#define lcd_clear()				lcd_command(0x01) //Clear LCD
#define lcd_cursor_off()		lcd_command(0x0C) //Cursor OFF
#define lcd_cursor_on()			lcd_command(0x0E) //Underline cursor ON
#define lcd_cursor_on_blink()	lcd_command(0x0F) //Underline blinking cursor ON


#endif //LCD_LIB_H
lcd_lib.с
Показать/Спрятать

Код: Выделить всё

#include "lcd_lib.h"


uint8_t lcd_pos = LCD_LINE1;


static void lcd_nibble( uint8_t d )
{
  LCD_D7 = 0; if( d & 1<<7 ) LCD_D7 = 1;
  LCD_D6 = 0; if( d & 1<<6 ) LCD_D6 = 1;
  LCD_D5 = 0; if( d & 1<<5 ) LCD_D5 = 1;
  LCD_D4 = 0; if( d & 1<<4 ) LCD_D4 = 1;
  LCD_E0 = 1;
  _delay_us( LCD_TIME_ENA );
  LCD_E0 = 0;
}


static void lcd_byte( uint8_t d )
{
  lcd_nibble( d );
  lcd_nibble( d<<4 );
  _delay_us( LCD_TIME_DAT );
}


void lcd_command( uint8_t d )
{
  LCD_RS = 0;
  lcd_byte( d );
  switch( d ){
    case 0 ... 3:                       // on longer commands
      _delay_us( LCD_TIME_CLR );
      d = LCD_LINE1;
    case 0x80 ... 0xFF:                 // set position
      lcd_pos = d;
  }
}


void lcd_putchar( uint8_t d )
{
  LCD_RS = 1;
  lcd_byte( d );
  switch( ++lcd_pos ){
    case LCD_LINE1 + LCD_COLUMN:
#ifdef LCD_LINE2
      d = LCD_LINE2;
      break;
    case LCD_LINE2 + LCD_COLUMN:
#ifdef LCD_LINE3
      d = LCD_LINE3;
      break;
    case LCD_LINE3 + LCD_COLUMN:
#ifdef LCD_LINE4
      d = LCD_LINE4;
      break;
    case LCD_LINE4 + LCD_COLUMN:
#endif
#endif
#endif
      d = LCD_LINE1;
      break;
    default: 
      return;
  }
  lcd_command( d );
}


void lcd_puts( void *s )                        // display string from SRAM
{
  for( uint8_t *s1 = s; *s1; s1++ )             // until zero byte
    lcd_putchar( *s1 );
}


//Вывод строки s из Flash памяти на LCD
void lcd_puts_p(const char *s)					// display string from FLASH
{
  register char c;

  while( (c = pgm_read_byte( s++ )) )
    lcd_putchar( c );
}


void lcd_blank( uint8_t len )                   // blank n digits
{
  while( len-- )
    lcd_putchar( ' ' );
}


// initialize the LCD controller
void lcd_init( void )
{
  LCD_DDR_D4 = 1;                               // enable output pins
  LCD_DDR_D5 = 1;
  LCD_DDR_D6 = 1;
  LCD_DDR_D7 = 1;
  LCD_DDR_RS = 1;
  LCD_DDR_E0 = 1;
  LCD_E0 = 0;
  LCD_RS = 0;                                   // send commands

  _delay_ms( 15 );
  lcd_nibble( 0x30 );
  _delay_ms( 4.1 );
  lcd_nibble( 0x30 );
  _delay_us( 100 );
  lcd_nibble( 0x30 );
  _delay_us( LCD_TIME_DAT );
  lcd_nibble( 0x20 );                           // 4 bit mode
  _delay_us( LCD_TIME_DAT );
#if LCD_LINE == 1
  lcd_command( 0x20 );                          // 1 line
#else
  lcd_command( 0x28 );                          // 2 lines 5*7
#endif
  lcd_command( 0x08 );                          // display off
  lcd_command( 0x01 );                          // display clear
  lcd_command( 0x06 );                          // cursor increment
  lcd_command( 0x0C );                          // on, no cursor, no blink
}
koolhatcker
Смотрящий
Сообщения: 1504
Зарегистрирован: 30 авг 2009, 00:00
Откуда: Омск
Контактная информация:

Re: Проблемма с отображением символов на LCD

Сообщение koolhatcker »

static void lcd_nibble( uint8_t d )
{
LCD_D7 = 0; if( d & 1<<7 ) LCD_D7 = 1;
LCD_D6 = 0; if( d & 1<<6 ) LCD_D6 = 1;
LCD_D5 = 0; if( d & 1<<5 ) LCD_D5 = 1;
LCD_D4 = 0; if( d & 1<<4 ) LCD_D4 = 1;
LCD_E0 = 1;
_delay_us( LCD_TIME_ENA );
LCD_E0 = 0;
}
Как минимум это.
Если юзаете avr-gcc, то там есть в комплекте библиотека аналогичного назначения.
Её и поправить легче...
Автономный контроллер станка с ЧПУ: http://it-en.ru/cnc
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Re: Проблемма с отображением символов на LCD

Сообщение ChaiSER »

koolhatcker, спасибо за наводки... пробовал менять сдвиги именно этой функции, но безрезультатно...

Попробовал подключить D4-D7 -> PC0-PC3 и результат тот-же:
Изображение
Абракадабра - это типа отображение русского шрифта :)

Выходит, не в библиотеке дело...
koolhatcker
Смотрящий
Сообщения: 1504
Зарегистрирован: 30 авг 2009, 00:00
Откуда: Омск
Контактная информация:

Re: Проблемма с отображением символов на LCD

Сообщение koolhatcker »

ChaiSER, в чём именно проблема?
Можно четко и по пунктам? Без шарад и метафор.
Автономный контроллер станка с ЧПУ: http://it-en.ru/cnc
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Re: Проблемма с отображением символов на LCD

Сообщение ChaiSER »

Николай, проблемма, собственно, на фото не правильно отображаються 13-16 столбцы LCD. Я грешил на проблемы библиотеки из-за инверсного подключения дата шины D4-D7, но когда вывел дисплей на макетку и подключил не инверсно, а стандартно (D4-D7 -> PC0-PC3) - отображение на LCD осталось прежним. Тоисть, проблемма ИМХО не в библиотеке.

Сейчас подумал... у меня в девайсе есть модуль для подключения CD-карты, но он пока не исспользуеться и инициализацию не писал в коде... Возможно в этом причина?
koolhatcker
Смотрящий
Сообщения: 1504
Зарегистрирован: 30 авг 2009, 00:00
Откуда: Омск
Контактная информация:

Re: Проблемма с отображением символов на LCD

Сообщение koolhatcker »

Не думаю. Если индикатор инициализируется и отображает символы, значит он подключен правильно.
Больше похоже на дохлый индикатор. Кстати, какая у него маркировка(полностью)?
Автономный контроллер станка с ЧПУ: http://it-en.ru/cnc
ChaiSER
Станкостроитель
Станкостроитель
Сообщения: 51
Зарегистрирован: 31 авг 2009, 00:00
Откуда: UA

Re: Проблемма с отображением символов на LCD

Сообщение ChaiSER »

Вот фото LCD:

Изображение Изображение

Здесь даташит: Скачать файл mc1602c-syr.pdf (549.49 kB)

PS: сорцы бросил на мыло.

---

Подключил дисплей к отладочной плате на ATmega8 - проблемма осталась прежней...
Из чего делаю вывод - проблемма именно в LCD.
Andry
Станкостроитель
Станкостроитель
Сообщения: 532
Зарегистрирован: 20 янв 2010, 01:00
Имя: Андрей
Откуда: Украина.Г.Носовка

Re: Проблемма с отображением символов на LCD

Сообщение Andry »

У меня много таких LCD ,тыкаю куда попало так попался именно с такой проблемой,решилось заменой индикатора.Видать убили или статикой или напряжением.
Ответить