Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Товарищи, гляньте код - устал биться :(
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
d71
Помогите пожалуйста, это иар и mt10s1 мэлт
а понмаю что что-то я недопонял, но почти готов долбануть его об стену
мне над математикой основной проги еще работать, а я до сих пор вывести ничего не могу.
или мож у кого есть рабочий кусок под этот экран...
LordN
може и не в тему...
как-то имел большой трабл с ЛСДшкой, датавижн, 16*2, бился долго (причем код был абсолютно рабочий, с прежней партией ЛСДшек работал без глюков), пока тупо не увеличил все тайм-ауты вдвое-трое.
потом где-то прочел, что бывает в них ставят контроллеры с пониженной вдвое тактовой.
d71
#include <iom16.h>
#include <inavr.h>

#define XTALL 0.1024
#define delay_us(us) __delay_cycles (XTALL * us);
#define delay_ms(ms) delay_us (1000 * ms)

#define Led PORTB_Bit0

#define D PORTA
#define A0 PORTA_Bit6
#define RW PORTA_Bit5
#define E PORTA_Bit4
#define BS PINA_Bit3

//Пример программы для буквенно-цифровых индикаторов MT10S1, MT16S2, MT20S2, MT24S2, MT20S4 с подключением по 4-х битному режиму.

#define MT10S1 //Выбор типа ЖК индикатора из списка: MT10S1, MT16S2, MT20S2, MT24S2, MT20S4.

#ifdef MT10S1 //Текст для ЖК индикатора MT10S1
#define Len1 8 //Количество символов в первой строке индикатора (10 символов на индикаторе набраны из двух строк!)
#define Len2 2 //Количество символов в второй строке индикатора
#define Len3 0 //Количество символов в третьей строке индикатора
#define Len4 0 //Количество символов в четвёртой строке индикатора
const char Text1[Len1]={ 'М','Э','Л','Т',' ','1','0','S' };
const char Text2[Len2]={ '1',24 };
#endif

void WriteByte(unsigned char b,unsigned int cd) {
//Сначала проверим готовность индикатора
//При необходимости настроить здесь шину данных на ввод
RW=1; A0=0; //Чтение флага занятости
delay_ms(40); //Это время предустановки адреса (tAS)
E=1; delay_ms(230); //Это минимально допустимая длительность сигнала E=1 (информация на шину данных индикатором будет выдана раньше, не более чем через 120нс)
while(BS==1); //Ждать сброса флага занятости

E=0; delay_ms(270); //Минимально допустимый интервал между сигналами E=1
E=1; delay_ms(230); //Получим младшую половину байта
E=0; delay_ms(270); //Минимально допустимый интервал между сигналами E=1
//При необходимости настроить здесь шину данных на вывод
RW=0;
if (cd==1){A0=1;}else{A0=0;}
D=b>>4;
delay_ms(40); //Это время предустановки адреса (tAS)
E=1; delay_ms(230); //Время предустановки данных попало сюда (tDSW)
E=0; delay_ms(270); //Минимально допустимый интервал между сигналами E=1
D=b&0x0F; //Выдадим младшие 4 бита (при этом биты RW и A0 измениться не должны!)
E=1; delay_ms(230); //Время предустановки данных попало сюда (tDSW)
E=0; delay_ms(270); //Минимально допустимый интервал между сигналами E=1
}


void WriteCmd(unsigned char cool.gif { WriteByte(b,0); }

void WriteData(unsigned char cool.gif { WriteByte(b,1); }



void LCDinit(void) {
E=0; delay_ms(20);
//При необходимости настроить здесь шину данных на вывод
RW=0; A0=0; D=0x03; //Установка типа интерфейса (8 бит) (0x03 - старший полубайт команды 0x30) - в начале ВСЕГДА переключаем индикатор в 8-ми битный режим работы
delay_ms(40); //Это время предустановки адреса (tAS)
E=1; delay_ms(230); //Время предустановки данных попало сюда (tDSW)
E=0; delay_ms(40); //Пауза между командами
E=1; delay_ms(230); //Минимально допустимая длительность сигнала E=1
E=0; delay_ms(40); //Пауза между командами
E=1; delay_ms(230);
E=0; delay_ms(40); //Пауза между командами
D=0x02; //Установка типа интерфейса (4 бит) (0x02 - старший полубайт команды 0x20) (при этом биты RW и A0 измениться не должны!)
E=1; delay_ms(230); //Время предустановки данных попало сюда (tDSW)
E=0; delay_ms(270); //Минимально допустимый интервал между сигналами E=1
//Здесь индикатор входит в рабочий режим с установленным типом интерфейса и можно подавать команды как обычно
WriteCmd(0x2A); //Настройка правильного режима ЖКИ
WriteCmd(0x0C); //Включение индикатора, курсор выключен
WriteCmd(0x01); //Очистка индикатора
WriteCmd(0x06); //Установка режима ввода данных: сдвигать курсор вправо
}




void main(void) {

PORTA=0x00;
DDRA=0xff;

PORTB=0x00;
DDRB=0xff;

int i;

Led=1;


LCDinit();



WriteCmd(0x80); //Установка курсора в начало первой строки индикатора
//WriteData('a');


/*
#if Len1>0
for(i=0;i<Len1;i++) { WriteData(Text1[i]); }
#endif
#if Len3>0
for(i=0;i<Len3;i++) { WriteData(Text3[i]); } //Третья строка расположена в внутреннем ОЗУ ЖК индикатора сразу за первой
#endif
WriteCmd(0x80+0x40); //Установка курсора в начало второй строки индикатора
#if Len2>0
for(i=0;i<Len2;i++) { WriteData(Text2[i]); }
#endif
#if Len4>0
for(i=0;i<Len4;i++) { WriteData(Text4[i]); } //Четвёртая строка расположена в внутреннем ОЗУ ЖК индикатора сразу за второй
#endif
*/
}
Igor_U
Цитата
Помогите пожалуйста, это иар и mt10s1 мэлт
а понмаю что что-то я недопонял, но почти готов долбануть его об стену


Какая-то странная у тебя инициализация. Поищи описание на KS0066 и сделай как советуют в даташите. Насколько я помню там несколько комманд надо было подавать без проверки флага занятости, и какие-то из них повторять несколько раз. У меня есть проверенная инициализация на Сях, но к сожалению дома. Но в любом случае начни с пдф.
d71
sad.gif помогите кодом, я запутался уже по самые уши. написал разных кучу вариантов, а не кажет сволочь sad.gif
работа стоит
vet
Рабочий код, исправно инициализирует самые разные контроллеры.
Макросы поправьте под свою схему.

Код
#define SET_RS (PORTB |= BIT(4))
#define CLR_RS (PORTB &= ~BIT(4))
#define SET_E  (PORTB |= BIT(5))
#define CLR_E  (PORTB &= ~BIT(5))
#define WRITE_LOW_NIBBLE(x)  ( PORTD = (PORTD & 0x0F) | ((x) << 4) )
#define WRITE_HIGH_NIBBLE(x) ( PORTD = (PORTD & 0x0F) | ((x) & 0xF0) )

...

#define MKS_BYTE 40 /* время на передачу байта на дисплей */

...

void WriteToDisplay(byte value) {
  SET_E;
  WRITE_HIGH_NIBBLE(value);
  CLR_E;
  SET_E;
  WRITE_LOW_NIBBLE(value);
  CLR_E;
}

void WriteDelayed(byte value) {
  WriteToDisplay(value);
  delay_us(MKS_BYTE);
}

void UpdateDisplay() {
  //memset(screen,' ',N_SYM_IN_DISP);
  CLR_RS;
  WriteDelayed(0x01);
  delay_us(1800);
}


void InitDisplay(void) {  //4.88 мс
  CLR_RS;
  WriteDelayed(0x33);
  WriteDelayed(0x32);
  WriteDelayed(0x28); //4-битный интерфейс, 2 строки, шрифт-5х7 точек
  WriteDelayed(0x0c); //включить дисплей, выключить курсор
  WriteDelayed(0x06); //Курсор сдвигается вправо при записи, дисплей стоит на месте
  UpdateDisplay();    //очистить дисплей
}
Igor_U
У меня подобная инициализация не проходила, пока не сделал как советовал кто-то из производителей контроллера (samsung?):

Код
extern char WaitDisplay(void)
{
// функция считывания флага занятости дисплея

unsigned char Time;
unsigned char Flags;
unsigned char TimesReg;

TimesReg=__save_interrupt();
__disable_interrupt(); // запрещаем прерывания
PortDIn(); // шину данных атмеги переключаем на прием данных
ClearRS(); // сбрасываем линию RS
SetRW(); // выставляем линию RW
SetE(); // выставляем линию E
__delay_cycles(0x03); // задержка в 300nS
Time=PortDisplayRead; // в Time запоминаем старший байт данных дисплея
if ((Time&0x10)!=0x00) Flags=0xFF; // запоминаем статус занятости
    else Flags=0x00;
ClearE(); // сбрасываем линию E
__delay_cycles(0x06); // задержка в 542nS
SetE(); // выставляем линию E
__delay_cycles(0x03); // задержка в 300nS
Time=PortDisplayRead; // в Time запоминаем младший байт данных дисплея
__delay_cycles(0x02); // задержка в 180nS
ClearE(); // сбрасываем линию E
__restore_interrupt(TimesReg); // разрешаем прерывания
return Flags; // возвращаем статус занятости дисплея
}

extern void DataDisplay(unsigned char Value)
{
// запись данных в дисплей c ожиданием готовности

unsigned char Time;
unsigned char TimesReg;

LoopDataDisplay:
if (WaitDisplay()!=0) goto LoopDataDisplay; // выполняем цикл пока функция WaitDisplay не вернет статус не занятости дисплея

TimesReg=__save_interrupt();
__disable_interrupt(); // запрещаем прерывания
SetRS(); // выставляем линию RS
ClearRW(); // сбрасываем линию RW
Value=Revers(Value,0x00); // в Value заносим данные для передачи
Time=Value << 4; // сдвигаем на старшую половину полубайта младшую часть данных для передачи
PortDOut(); // переключаем порт D на передачу данных
PortDisplayWrite=Time; // передаем младший полубайт в дисплей
SetE(); // выставляем линию E
__delay_cycles(0x06); // задержка в 542nS
ClearE(); // сбрасываем линию E
PortDisplayWrite=Value; // передаем старший полубайт в дисплей
__delay_cycles(0x03); // задержка в 300nS
SetE(); // выставляем линию E
__delay_cycles(0x06); // задержка в 542nS
ClearE(); // сбрасываем линию E
PortDIn(); // переключаем порт D на прием данных
ClearRS(); // сбрасываем линию RS
SetRW(); // выставляем линию RW
__restore_interrupt(TimesReg); // разрешаем прерывания
}

extern void CommandDisplay(unsigned char Value)
{
// запись комманды в дисплей c ожиданием готовности

unsigned char Time;
unsigned char TimesReg;

LoopCommandDisplay:
if (WaitDisplay()!=0) goto LoopCommandDisplay; // выполняем цикл пока функция WaitDisplay не вернет статус не занятости дисплея

TimesReg=__save_interrupt();
__disable_interrupt(); // запрещаем прерывания
ClearRS(); // сбрасываем линию RS
ClearRW(); // сбрасываем линию RW
Value=Revers(Value,0x00); // в Value заносим данные для передачи
Time=Value << 4; // сдвигаем на старшую половину полубайта младшую часть данных для передачи
PortDOut(); // переключаем порт D на передачу данных
PortDisplayWrite=Time; // передаем младший полубайт в дисплей
SetE(); // выставляем линию E
__delay_cycles(0x06); // задержка в 542nS
ClearE(); // сбрасываем линию E
PortDisplayWrite=Value; // передаем старший полубайт в дисплей
__delay_cycles(0x03); // задержка в 300nS
SetE(); // выставляем линию E
__delay_cycles(0x06); // задержка в 542nS
ClearE(); // сбрасываем линию E
PortDIn(); // переключаем порт D на прием данных
ClearRS(); // сбрасываем линию RS
SetRW(); // выставляем линию RW
__restore_interrupt(TimesReg); // разрешаем прерывания
}

extern void CommandDisplay8(unsigned char Value)
{
// запись младшей части комманды в дисплей без проверки готовности

unsigned char Time;
unsigned char TimesReg;

TimesReg=__save_interrupt();
__disable_interrupt(); // запрещаем прерывания
ClearRS(); // сбрасываем линию RS
ClearRW(); // сбрасываем линию RW
Value=Revers(Value,0x00); // в Value заносим данные для передачи
Time=Value << 4; // сдвигаем на старшую половину полубайта младшую часть данных для передачи
PortDOut(); // переключаем порт D на передачу данных
PortDisplayWrite=Time; // передаем младший полубайт в дисплей
SetE(); // выставляем линию E
__delay_cycles(0x06); // задержка в 542nS
ClearE(); // сбрасываем линию E
PortDIn(); // переключаем порт D на прием данных
SetRW(); // выставляем линию RW
__restore_interrupt(TimesReg); // разрешаем прерывания
}

CommandDisplay8(0x30);
__delay_cycles(0xD800);
CommandDisplay8(0x30);
__delay_cycles(0x500);
CommandDisplay8(0x30);
__delay_cycles(0x500);
CommandDisplay8(0x28);
CommandDisplay(0x28);
CommandDisplay(0x0C);
CommandDisplay(0x06);


CommandDisplay8 - посылала данные без опроса флага занятости дисплея
CommandDisplay - с опросом флага занятости и по четырем линиям.
Revers - переворачивала байт, так цоколевки дисплея и контроллера включены были встречно.

Запись в порт корректнее сделана у vet'а:
#define WRITE_LOW_NIBBLE(x) ( PORTD = (PORTD & 0x0F) | ((x) << 4) )
#define WRITE_HIGH_NIBBLE(x) ( PORTD = (PORTD & 0x0F) | ((x) & 0xF0) )
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.