Обсуждаем контроллеры компании Atmel.
Ответить

МК "AT89C51" и LCD "LM016L". Не могу разобраться с кодом.

Пт янв 26, 2018 06:40:56

Код пишу в: Kell uVision
Тестирую в: PROTEUS
Исходники все ниже

Ни как не могу понять почему код не работает на МК хотя спокойно компилируется.
На сколько я понял код просто зависает на одном из циклов и не движется дальше.

Сам код: (Урезанный немного)
Спойлерsbit P1_0 = 0x90;
sfr P0 = 0x80;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TH0 = 0x8C;
sfr Data = 0xA0;
sbit TF0 = 0x8D;
sbit TR0 = 0x8C;
sbit RS = 0xB5;
sbit RW = 0xB6;
sbit E = 0xB7;

timer()
{
TMOD = 0x01;
TH0 = 60136 >> 8;
TL0 = 60136;
TR0=1;
while(!TF0);
TF0=0;
}

cmd(char command)
{
RS=0;
RW=0;
E=1;
Data=command;
E=0;
timer();
}

symbol(char command)
{
RS=1;
RW=0;
E=1;
Data=command;
E=0;
timer();
}

intilization()
{
int i;
for (i = 0; i < 3; i++)
{
timer();
RS = 0;
RW = 0;
Data = 0x30;
}
timer();
cmd(60); // начальные установки
cmd(14); // Курсор
cmd(1); // Отчистка дисплея
cmd(6); // Режим ввода
}

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


int mass[8][5] = {
{1,0,0,0,1,},
{0,0,0,0,0,},
{0,1,1,1,0,},
{0,1,0,1,0,},
{0,1,0,1,0,},
{0,1,1,1,0,},
{0,0,0,0,0,},
{1,0,0,0,1,}};

void video();
void main(void)
{
P1_0 = 0; // Погасить лампочки
intilization(); // Инцилизация дисплея
cmd(0x01); // отчистка дисплея

video(); // Вывод масива на экран

// cmd(0x40); // Установка адреса
// cmd(0x80); // превод на 0 позицию.
// cmd(0xC0); // Перевод на другую строку
while(1);
}



void video() // Вывод масива на экран
{
int line[8] = {0}; // Делим весь массив на строчки
int i,a,p = 0, y = 0;

for (i = 0; i < 8; i++) // Переписываем весь двумерный массив в массив line
{
for(a = 0; a < 5; a++) // Пробегаемся по каждым 5 битам
{
cmd(0x80+a);symbol(0x30); // По идее должны написаться 5 подряд нулей.
line[i] = line[i] + mass[y][a]; // строка | столбец
if (a < 4)
line[i] = line[i] << 1; // записываем все в 1 ячейку

}
while(1);
y++; // С каждым циклом переходим на строку ниже
}
for (i = 0; i < 8;i++) // Добавляем бит (10 000) каждому значению в массив line
{
line[i] = line[i] + 512;
}
// Тест.
cmd(0x40); // Команда Установка адреса CGRAM
for (i = 0; i < 8; i++)
{
symbol(line[i]); // Запись в CGRAM
}

cmd(0x80); // Установка курсора на 1 строку
symbol(0x00); // Вывод первого символа
while(1);
}

Насколько я понял, ошибка появляется именно в этом цикле:
Код:
for (i = 0; i < 8; i++)            // Переписываем весь двумерный массив в массив line
   {
      for(a = 0; a < 5; a++)         // Пробегаемся по каждым 5 битам
      {   
         cmd(0x80+a);symbol(0x30);      // По идее должны написаться 5 подряд нулей.
         line[i] = line[i] + mass[0][a];   // строка | столбец
         if (a < 4)
            line[i] = line[i] << 1;         // записываем все в 1 ячейку
            
      }
      while(1);
      y++;                           // С каждым циклом переходим на строку ниже
   }

после цикла FOR ниже специально поставил бесконечный цикл Что бы проверить остановится ли весь процесс
НО получается так что он почему то бесконечно бегает внутри цикла FOR и даже не доходит до цикла while(1);
что бы убедиться в этом внутри цикла FOR поставил 2 команды
cmd(0x80+a);
symbol(0x30);
на вывод символа "0" и переход на следующую ячейку. Соответственно никакого перехода нету.
СпойлерИзображение

А если убрать две строки:
Код:
      line[i] = line[i] + mass[0][a];   // строка | столбец
         if (a < 4)
            line[i] = line[i] << 1;   

То все работает как нужно!
Хотя они даже никак не влияют на вывод символа ноль
СпойлерИзображение

...
Вообщем я не понимаю почему с ними ничего не работает

Вообще программа заключается не ввыводе ноликов на экран :))
Это небольшой пример проблемы.
Вложения
Proteus.rar
(42.63 KiB) Скачиваний: 128

Re: МК "AT89C51" и LCD "LM016L". Не могу разобраться с кодом

Пт янв 26, 2018 12:08:54

Этот участок кода
Спойлер
Код:
   // Тест.
   cmd(0x40);                  // Команда Установка адреса CGRAM                           
   for (i = 0; i < 8; i++)
   {
      symbol(line[i]);         // Запись в CGRAM
   }
Изменить на
Спойлер
Код:
   // Тест.
for (i = 0; i < 8; i++)
   {
   cmd(0x40+i);            // Команда Установка адреса CGRAM
        symbol(line[i]);      // Запись в CGRAM
   }

Re: МК "AT89C51" и LCD "LM016L". Не могу разобраться с кодом

Пт янв 26, 2018 12:50:20

Этот участок кода
Спойлер
Код:
   // Тест.
   cmd(0x40);                  // Команда Установка адреса CGRAM                           
   for (i = 0; i < 8; i++)
   {
      symbol(line[i]);         // Запись в CGRAM
   }
Изменить на
Спойлер
Код:
   // Тест.
for (i = 0; i < 8; i++)
   {
   cmd(0x40+i);            // Команда Установка адреса CGRAM
        symbol(line[i]);      // Запись в CGRAM
   }


Какой смысл? Если код не может дойти даже до этого участка.
Он застревает в обычном цикле FOR и повторяется в нем бесконечно.

Re: МК "AT89C51" и LCD "LM016L". Не могу разобраться с кодом

Пт янв 26, 2018 14:45:32

Попробуйте так
Спойлер
Код:
char mass_2 [7] = {0x11,0x00,0x0E,0x0A,0x0E,0x00,0x11};

void zagrus_mass_2 (void) {
 char i;
    for (i = 0; i < 8; i++)
   {
         cmd(0x40+i);
         symbol(mass_2[i]);         // Запись в CGRAM
   }
}


zagrus_mass_2();
   cmd(0x80);            //
   symbol(0x00);          // Вывод первого символа

LCD "LM016L". Объяснит мне в чем отличие?

Сб янв 27, 2018 06:31:39

Код пишу в: Kell uVision
Тестирую в: PROTEUS
МК "AT89C51"
LCD "LM016L".

Столкнулся с одной интересной проблемой которая мне мешает дальше что то делать.
Собственно сам код:
Код:
void main(void)
{   
   int AA[5] = {1,0,0,0,1};   // Массив пикселей.
   int S = 0;   

   intilization();       // Инцилизация дисплея
   cmd(0x01);        // отчистка дисплея
   S = S + AA[0];          // 0 + 1 = 1
   cmd(0x40);          // Установка адреса CGRAM
   symbol(512+S);      // Прибавляем биты 10 000
   symbol(512);
   cmd(0x80);            // Установка адреса на 1 ячейку
   symbol(0x00);      // Вывод символа
   while(1);
}

и результат:
СпойлерИзображение

По идее должен загореться 1 пиксель на экране.
НО если в строчке S = S + AA[0]; заменить АА прпосто на значение 1 то все работает.
СпойлерИзображение


Я не понимаю просто почему так происходит. Ведь значение элемента массива AA[0] и так равно 1.
Вложения
Proteus.rar
(38.8 KiB) Скачиваний: 130

Re: LCD "LM016L". Объяснит мне в чем отличие?

Сб янв 27, 2018 06:46:39

symbol() какой параметр обрабатывает? Приведите эту функцию.

Re: МК "AT89C51" и LCD "LM016L". Не могу разобраться с кодом

Сб янв 27, 2018 06:58:05

Denzell, зачем плодите темы, состоящие из нескольких постов и одинаковые по смыслу ?
Перенёс сообщения из другой темы сюда.

PS: И не цитируйте полностью предыдущие сообщения, иначе отправлю читать правила.
Ответить