Страница 1 из 1

LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вс апр 07, 2013 23:08:34
king-live
Доброго времени суток! Хотел вывести на LCD информацию в две строчки. (LCD HD44780-16x2) Исходный код взял отсюда.

http://radioparty.ru/index.php/prog-avr ... vr-lesson1

Переправил под свой проект и информация выводится на экран.
Вот мой код

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


#include <avr/io.h>
#define F_CPU 8000000UL
#include <stdlib.h>
#include <util/delay.h>   

#define RS PD6       
#define EN PD7       

unsigned char x;

void lcd_com(unsigned char p) 
{
PORTD &= ~(1 << RS);   // RS = 0
PORTD |= (1 << EN);    // EN = 1 
PORTC = p;             
_delay_us(300);      
PORTD &= ~(1 << EN);   // EN = 0 
_delay_us(300);        
}

void lcd_dat(unsigned char p)  
{
PORTD |= (1 << RS)|(1 << EN);  //RS = 1, EN = 1
PORTC = p;                    
_delay_us(200);               
PORTD &= ~(1 << EN);           // EN = 0 
_delay_us(200);                
}
 

void lcd_init(void)
{
lcd_com(0x08);          // 
lcd_com(0x38);           //
_delay_us(400);
lcd_com(0x38);           // 
_delay_us(400);
lcd_com(0x38);           // 
lcd_com(0x38);
lcd_com(0x01);           // 
_delay_us(400);
lcd_com(0x06);           //
lcd_com(0x0D);           //
}


int main (void)
{
DDRC=0xFF;
PORTC = 0x00;                   
DDRD = 0xFF;               
PORTB = 0x00;
while(1)
	{
	lcd_init();      
	lcd_dat('H');  
	lcd_dat('e');
	lcd_dat('l');
	lcd_dat('l');
	lcd_dat('o');
	lcd_dat(' ');
	lcd_dat('w');
	lcd_dat('o');
	lcd_dat('r');
	lcd_dat('l');
	lcd_dat('d');
	lcd_dat('!');
	_delay_ms(1000);
	x++;
	}
}


Как вывести на экран во вторую нижнюю строчку, переменную "х"? Спасибо!
Библиотекой LCD не пользовался.

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вс апр 07, 2013 23:21:35
Аlex
Плохой пример взяли, поищите другой... Хотя бы, чтобы была команда перевода курсора по координатам.
Мне кажется, подобных библиотек в тырнете тьма тьмущая...

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вс апр 07, 2013 23:36:18
king-live
Не могу судить об этом примере, плохой или хороший. Просто он самый доходчивый и простой, без подключения библиотеки LCD. Да и мне пока многого и не надо. Нужно всего лишь вывести несколько переменных на экран. Как вывели строку "Hello world!" Если конечно это возможно в этом примере. Спасибо!

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вт апр 09, 2013 20:45:42
Кефир
Вот:

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

#ifndef hd44780
#define hd44780

// HD44780
#define RS BIT7          // 0 - команда, 1 - данные
#define E  BIT6          // Стробирующий вход (синхр.)

// 74HC595
#define SH BIT5          // 
#define ST BIT4          // 
#define DS BIT3          // 

#endif /* hd44780 */

int StrokaOne[] = {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}; // 16

int StrokaTwo[]=  {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}; // 16
int LedPauza = 50;

// Init_HD_44780(Комманда);
int Init_HD_44780(int Commands)
{
// Команда
//************************
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
    P1OUT &= ~RS;
    P1OUT |= E;
    //P1OUT = 12;
    HC595Out(Commands);
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
                
    P1OUT &= ~RS + E;
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
//************************
}
// OUT_LED_Word(Символы, Номер строки, Адрес стартовой ячейки, Статус Символов (char - 1 или int - 2), Символ в Dec);
int OUT_LED_Word(char Text[], int Stroka, int StartAadres, int StatusChar, int TextDec[])
{
  if(StatusChar == 1)
  {
    if(Stroka == 1)
    {
      Stroka = 128;
    }
    
    if(Stroka == 2)
    {
      Stroka = 168;
    }
    
      for(int i = 0; i <= 16; i++)
      {
        if(Text[i] == 0)
        {          }
        else 
        {
          if(Text[i+1] == 0)
          {
            if(Text[i+1] == 0)
            {
              OutStrokaOne(Text[i], i, StartAadres, Stroka);
              i = 16;        
            }
            else
            {
              OutStrokaOne(Text[i], i, StartAadres, Stroka);
            }
          }
          else
          {
            OutStrokaOne(Text[i], i, StartAadres, Stroka);
          }
        }
      }
    }
  
  if(StatusChar == 2)
  {
    if(Stroka == 1)
    {
      Stroka = 128;
    }
    
    if(Stroka == 2)
    {
      Stroka = 168;
    }
      for(int i = 0; i <= 16; i++)
      {
        if(TextDec[i] == 0)
        {          }
        else 
        {
          if(TextDec[i+1] == 0)
          {
            if(TextDec[i+1] == 0)
            {
              OutStrokaOne(TextDec[i], i, StartAadres, Stroka);
              i = 16;        
            }
            else
            {
              OutStrokaOne(TextDec[i], i, StartAadres, Stroka);
            }
          }
          else
          {
            OutStrokaOne(TextDec[i], i, StartAadres, Stroka);
          }
        }
      }
  }
}

// OUT_LED_Dec(Значение, Номер строки, Адрес стартовой ячейки, Статус дроби);
int OUT_LED_Dec(int Value, int Stroka, int StartAadres, int Share )
{
  //Value = Value * 100;
  unsigned char s[16];
  if(Stroka == 1)
  {
    Stroka = 128;
  }
  
  if(Stroka == 2)
  {
    Stroka = 168;
  }
    if(Value < 0)
    {
        s[0] = '-'; 
    }
    else { s[0] = ' '; }
    
    for(int i = 0; i <4; i++)
    {
      if(Value <= 9)
      {
        if(Share == 1)
        {
          s[1] = '0';   
          s[2] = '0';
          s[3] = '.';
          s[4] = Value % 10 + '0';
        }
        if(Share == 2)
        {
          s[1] = ' ';   
          s[2] = ' ';
          s[3] = ' ';
          s[4] = Value % 10 + '0';
        }
        
      }
      if(Value <= 99)
      {
        if(Share == 1)
        {
          s[1] = '0';
          s[2] = (Value / 10) % 10 + '0';
          s[3] = '.';
          s[4] = Value % 10 + '0';
        }
        if(Share == 2)
        {
          s[1] = ' ';
          s[2] = ' ';          
          s[3] = (Value / 10) % 10 + '0';
          s[4] = Value % 10 + '0';
        }
      }
      if(Value <= 999)
      {
        if(Share == 1)
        {
          s[1] = (Value / 100) % 10 +'0';
          s[2] = (Value / 10) % 10 + '0';
          s[3] = '.';
          s[4] = Value % 10 + '0';
        }
        if(Share == 2)
        {

          s[1] = ' ';
          s[2] = (Value / 100) % 10 +'0';
          s[3] = (Value / 10) % 10 + '0';
          s[4] = Value % 10 + '0';
        }
      }
    }
  
    for (int i = 0; i <= 4; i++)
    {
      OutStrokaOne(s[i], i, StartAadres, Stroka);
    }
}

// OutStrokaOne(Символ в Dec, Номер символа, Адрес стартовой ячейки, Адрес строки(128, 168));
int OutStrokaOne(int Simvl, int StrokaAdres, int StartAdresStrokaOne, int StrokaOneTwo)
{
//************************ Команда
    P1OUT &= ~RS;
    P1OUT |= E;
    //P1OUT = StrokaOneTwo + StrokaAdres + StartAdresStrokaOne;
    HC595Out(StrokaOneTwo + StrokaAdres + StartAdresStrokaOne);
    
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
    P1OUT &= ~RS + E;
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
//************************
    
//************************ Данные
    P1OUT |= RS;
    P1OUT |= E;
    //P1OUT = Simvl;
    HC595Out(Simvl);
    
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
    P1OUT |= RS;
    P1OUT &= ~E;
    for(volatile unsigned int i = LedPauza; i != 0; i--); // Задержка
//************************
}

// HC595Out(Значение int); // Вывод на 74HC595
int HC595Out(int Data)
{
  int OutDataRS = 0;
  P2OUT &= ~SH;
  P2OUT &= ~ST;
  P2OUT &= ~DS;   
  for(int i = 0; i < 8; i++)
  {
    OutDataRS = Data >> i;
    if((1&OutDataRS) == 1)
    {
      for(volatile unsigned int i = 40; i != 0; i--); // Задержка
      P2OUT |= DS;
      P2OUT |= SH;
      for(volatile unsigned int i = 50; i != 0; i--); // Задержка
      P2OUT &= ~SH;
    }
    else
    {
      for(volatile unsigned int i = 40; i != 0; i--); // Задержка
      P2OUT &= ~DS;
      P2OUT |= SH;
      for(volatile unsigned int i = 50; i != 0; i--); // Задержка
      P2OUT &= ~SH;
    }
  }
  P2OUT |= ST;    
  //for(volatile unsigned int i = 50; i != 0; i--); // Задержка
}

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вт апр 09, 2013 21:03:22
codenamehawk
Если не хотите воспользоваться умным советом от Аlex, то
выводите пустые символы(знак пробела) до тех пор, пока индикатор сам не перебросит на следующую строку, а там преобразовав х в текст выдавайте на лцд.

Если серьезно, то есть команды перемещения курсора, читайте описание лцд.

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Чт апр 11, 2013 20:40:12
king-live
Спасибо! Я так понимаю длинный код переданный "кефир"ом это библиотека, которую надо подключить к главному коду! Я пользуюсь "WinAVR+Studio4.19" или Studio6 с собственным Toolchain(заменитель WinAVR). Однако ни тот ни другой не видят готовых библиотек работающих с LCD. И библиотеки эти находятся глубоко в поддиррикториях. <hd44780.h>,<lcd.h>. Попробую разобраться с высланным кодом, и с предложеним о пробелах, спасибо! Кстати в готовых библиотеках прописанны порты для работы с шиной LСD. Но в них указанны другие порты чем в моём проекте. Мне нужно в библиотеках редактировать порты ввода вывода, а потом подключать в главную программу?

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Пт апр 12, 2013 21:14:21
codenamehawk
king-live писал(а): Мне нужно в библиотеках редактировать порты ввода вывода, а потом подключать в главную программу?
Да.
Пользуюсь библиотекой http://homepage.hispeed.ch/peterfleury/ ... .html#libs

Порты описаны в файле lcd.h
Подключение обычно сводится к помещению файлов библиотеки (н.п. lcd.c lcd.h) в папку вашего проекта.

В Studio4 становитесь на "Source files" правой и "Add Existings source file"
At16 LCD 4 bit.rar
Пример для протеуса.
(53.27 КБ) 247 скачиваний

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вс апр 14, 2013 20:36:18
king-live
lcd.c
это пример кода, а
lcd.h
это библиотека которую надо подключить? Я правильно понял?

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Вс апр 14, 2013 22:24:41
codenamehawk
Не правильно поняли.

"Правильная" библиотека имеет расширение .а (это отдельная тема)

.h в нем описываются переменные , прототипы функций(файл описаний, подключается инструкцией #include <lcd.h>), а тело функций описано в .с (вот ее и называют библиотекой, в принципе это обычный "с" файл, как подключить уже описывал.)

Re: LCD и Atmega16 самый простой код, на простом примере.

Добавлено: Пн апр 15, 2013 09:20:35
king-live
Спасибо понял! Буду разбираться!