реклама на сайте
подробности

 
 
> LCD дисплей KS0076, не могу инициализировать
Freeze Anti
сообщение Dec 10 2007, 05:52
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613



Здравствуйте.

У меня такая проблема. Есть LCD дисплей с контроллером KS0076, подключенный к микроконтроллеру ATmega32.

Я пытаюсь его инициализировать и вместо нужной мне строки символов получаю какие-то иероглифы вперемежку с черными прямоугольничками...

Вот текст программы, написанной в среде WinAVR...

Код
#include <avr/io.h>
#include <util/delay.h>

#define RD_1 PORTB |= 64 //PORTB = PORTB | 0b1000000 - RD = 1
#define RS_1 PORTB |= 16 //PORTB = PORTB | 0b0010000 - RS = 1
#define E_1 PORTB |= 32 //PORTB = PORTB | 0b0100000 - E = 1
#define RD_0 PORTB &= 63 //PORTB = PORTB & 0b0111111 - RD = 0
#define RS_0 PORTB &= 111 //PORTB = PORTB & 0b1101111 - RS = 0
#define E_0 PORTB &= 95 //PORTB = PORTB & 0b1011111 - E = 0

//Объявляем массив с адресами во внутренней памяти ЖК-модуля,
//соответствующими первой позиции в каждой из 4-х строк дисплея
const unsigned char addLUT[2] = {0x80, 0xC0};
unsigned char LCD_Address, LCD_Line; //Переменные для хранения
                                       //адреса позиции и номера строки ЖК-дисплея
char Buffer[15]; //Буфер для хранения строки, выводимой на дисплей

//Функция записи в ЖК-модуль полубайта
void WriteNibble(unsigned char data)
{
    RD_0; //Режим записи
    E_1; //Активируем передачу
    PORTB = (data & 0x0F); //Передаем данные
    E_0; //Завершаем передачу
    RD_1; //Режим чтения
    _delay_loop_2(5000); //Задержка 5 мс, чтобы ЖК-модуль имел
                          //достаточно времени на обработку данных
}

//Функция записи в ЖК-модуль байта
void WriteByte(unsigned char data)
{
    RD_0; //Режим записи
    E_1; //Активизируем передачу
    PORTB = (data >> 4); //Передаем старший полубайт
    E_0; //Завершаем передачу
    E_1; //Активизируем передачу
    PORTB = (data & 0xF); //Передаем младший полубайт
    E_0; //Завершаем передачу
    RD_1; //Режим чтения
    _delay_loop_2(3000); //Задержка 3мс, чтобы ЖК-модуль имел
                          //достаточно времени на обработку данных
}

//Функция перехода к первой позиции строки с номером LineNum
void GoToLine(char LineNum)
{
    RS_0; //Передача команды
    LCD_Address = addLUT[LineNum - 1]; //Определяем адрес строки
    WriteByte(LCD_Address); //и передаем его в ЖК-модуль
    RS_1; //Конец передачи команд
    LCD_Address = 0; //Обнуляем адрес
    LCD_Line = LineNum; //Устанавливаем текущую строку
}

//Функция очистки дисплея
void ClearLCD(void)
{
    RS_0; //Передача команды
    WriteByte(0x01); //Команда очистки, курсор перемещается
                      //в исходную позицию
    _delay_loop_2(10000); //Задержка 10мс, чтобы ЖК-модуль имел
                           //достаточно времени на обработку команды
    RS_1; //Конец передачи команд
    GoToLine(1); //Переходим к строке 1
}

//Функция установки текущей позиции col в строке row дисплея
void SetLCDPosition(char row, char col)
{
    RS_0; //Передача команды
    LCD_Address = addLUT[row - 1] + col; //Определяем позицию дисплея
    WriteByte(LCD_Address); //Записываем в ЖК-модуль адрес
    RS_1; //Конец передачи команды
    LCD_Line = row; //Устанавливаем текущую строку
}

//Функция отображения в текущей позиции на дисплее символа
void ShowChar(unsigned char c)
{
    RS_1; //Передача данных
    WriteByte(c); //Записываем символ
    LCD_Address++; //Увеличиваем адрес на 1
    switch(LCD_Address) //Определяем, произошел ли
                         //переход на новую строку дисплея
    {
        case 20:
            GoToLine(2);
            break;
        case 40:
            GoToLine(1);
            break;
    }
}

//Функция вывода на дисплей строки
void ShowStr(unsigned char *s)
{
    while(*s != 0)
        ShowChar(*s++);
}

//Функция инициализации ЖК-модуля
void InitLCD(void)
{
    RD_1; //предустановка управляющих сигналов
    E_0;
    RS_0;
    _delay_loop_2(50000); //Задержка на 50мс, чтобы ЖК-модуль
                           //имел достаточно времени на инициализацию
    WriteByte(0x33);
    _delay_loop_2(1100);
    WriteByte(0x33);
    WriteByte(0x33);
    WriteByte(0x38); //Определение параметров развертки и ширины шины данных сейчас 0x38 если не получится - попробовать 0x28
    WriteByte(0x01);
    WriteByte(0x10); //Устанавливаем режим смещения курсора
    WriteByte(0x06); //вправо, без сдвига содержимого дисплея
    WriteByte(0x0C); //Включаем дисплей, прячем курсор
    for(char i = 0x40; i < 0x5F; i++) //Инициализируем память
                                         //знакогенератора
    {
        _delay_loop_2(10000);
        RS_0;
        WriteByte(i);
        _delay_loop_2(10000);
        ShowChar(0);
    }
    RS_1; //Переходим в режим передачи данных
    SetLCDPosition(1, 4); //Переходим в первую строку дисплея
}

void main(void)
{
    DDRB = 0xFF; //Выводы 0 - 6 порта B - выходы (передача данных и управляющие сигналы)
    InitLCD(); //Инициализируем ЖК-дисплей
    while(1)
    {
        char Test[] = {0x53, 0x65, 0x63, 0xBF, 0x6F, 0xB3, 0x61, 0xC7, 0x00};
        char String[] = {0x63, 0xBF, 0x70, 0x6F, 0xBA, 0x61, 0x00};
        ClearLCD();
        ShowStr(Test);
        SetLCDPosition(2, 1);
        ShowStr(String);
        _delay_loop_2(10000);
    }
}


Данные передаются по четырем линиям, подключенным к PORTB, к этому же порту подключены и выводы, отвечающие за управляющие сигналы R/W, RS и ES.

Объясните, пожалуйста, что я делаю не так?


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 05:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01397 секунд с 7
ELECTRONIX ©2004-2016