Подскажите новичку как соединить жк и atmega.
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Насколько я в курсе, тип byte содержит числа от 0 до 255 (кстати, кое-где встречал и диапазон от -127 до 127).
То есть в CVAVR переменные типа byte можно объявлять типом unsigned char либо char.
То есть в CVAVR переменные типа byte можно объявлять типом unsigned char либо char.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

- adrenocrome
- Потрогал лапой паяльник
- Сообщения: 365
- Зарегистрирован: Вт окт 21, 2008 15:03:06
- Откуда: moscow
- Контактная информация:
Re: Подскажите новичку как соединить жк и atmega.
Товарищ "новичок в микроконтроллерах и прочей шняге", вот так писать
Это FFFUUUUUUUUU!!!!!
Пиши хотя бы так ,если хочешь каждый бит видеть.
Ибо в порт можно сразу затолкать 8 бит.
И еще. Нафига тебе эти наносекунды? Задай задержку с запасом, микросекунд на 10 например. Никакого криминала в этом не будет.
Код: Выделить всё
PORTA.7=1;
PORTA.6=1;
PORTA.5=1;
PORTA.4=0;
PORTA.3=0;
PORTA.2=0;
PORTA.1=1;
PORTA.0=0;Это FFFUUUUUUUUU!!!!!
Пиши хотя бы так ,если хочешь каждый бит видеть.
Код: Выделить всё
PORTA = 0b11100010Ибо в порт можно сразу затолкать 8 бит.
И еще. Нафига тебе эти наносекунды? Задай задержку с запасом, микросекунд на 10 например. Никакого криминала в этом не будет.
День прошёл, а ты всё жив
Re: Подскажите новичку как соединить жк и atmega.
Насколько я в курсе, тип byte содержит числа от 0 до 255 (кстати, кое-где встречал и диапазон от -127 до 127).
То есть в CVAVR переменные типа byte можно объявлять типом unsigned char либо char.
В CVAVR byte такое-же название как и, к примеру, byte_drytte или Vasja.
Можно конечно определить его, к примеру, типом unsigned char: typedef unsigned char byte;
Тогда вместо unsigned char можно будет писать byte.
к примеру: byte a=10;
Если имеется ввиду bit, то в CVAVR это переменная, которая может принимать значение только "0" или "1". Под них надо в свойствах проекта выделять место: C Compiler -> Code Generation -> Bit Variables Size
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Volly писал(а):В CVAVR byte такое-же название как и, к примеру, byte_drytte или Vasja.![]()
Можно конечно определить его, к примеру, типом unsigned char: typedef unsigned char byte;
Тогда вместо unsigned char можно будет писать byte.
к примеру: byte a=10;
Если имеется ввиду bit, то в CVAVR это переменная, которая может принимать значение только "0" или "1". Под них надо в свойствах проекта выделять место: C Compiler -> Code Generation -> Bit Variables Size
Благодарю за информацию, но все, что Вы изложили, я давно знаю.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

Re: Подскажите новичку как соединить жк и atmega.
К чему тогда:
???
Насколько я в курсе, тип byte содержит числа от 0 до 255 (кстати, кое-где встречал и диапазон от -127 до 127).
То есть в CVAVR переменные типа byte можно объявлять типом unsigned char либо char.
???
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Volly, я поясню к чему. На предыдущей странице, самым последним, располагается вот это сообщение:
Очевидно, что Alerr увидел этот тип в программе либо на ассемблере, либо на Delphi, либо где-то еще. Я и объяснил, что переменные, которые на асме (или где он увидел byte) объявляются с типом byte, в CVAVR можно объявить типом, например char, либо unsigned char. Главное, конечно же, учитывать диапазон чисел, в котором будет находиться переменная.
Только и всего.
Alerr писал(а):Товарищи, я не силен в кодвижене и уже неделю кручусь-верчусь с типом байт. Кодвижен похоже не понимает этот тип, как мне быть??? Кто сталкивался?
Очевидно, что Alerr увидел этот тип в программе либо на ассемблере, либо на Delphi, либо где-то еще. Я и объяснил, что переменные, которые на асме (или где он увидел byte) объявляются с типом byte, в CVAVR можно объявить типом, например char, либо unsigned char. Главное, конечно же, учитывать диапазон чисел, в котором будет находиться переменная.
Только и всего.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

Re: Подскажите новичку как соединить жк и atmega.
Спасибо, ценные подсказки. Выходит можно бит заменить на инт?
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Alerr писал(а):Выходит можно бит заменить на инт?
Переменные типа bit могут принимать значения либо 0, либо 1. Переменные типа int - 16-битные, лежат в диапазоне чисел от -32768..32767.
Можете, конечно, и заменить.
Только я бы этого не делал.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

Re: Подскажите новичку как соединить жк и atmega.
А как бы Вы, Subdia, сделали бы?
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Я бы отталкивался от диапазона значений, которые принимает переменная. Если она принимает значения 0 или 1, то тут уместен тип bit. Если от -127 до 127, то тип char, если от 0 до 255, то unsigned char. И так далее. Я ведь не вижу ни строки кода, откуда мне знать, где Вы намерены применить ту или иную переменную? 
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

Re: Подскажите новичку как соединить жк и atmega.
Могли бы вы SubDia взглянуть на код и дать некоторые разьяснения?
Вот код:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 06.07.2011
Author : PaRaGoN
Company : Administrator
Comments:
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 40,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#define byte char
#define bit int
void Pset(byte x, byte y, bit c) {//Записать одну точку в индикатор (координата 0,0 в левом верхнем углу индикатора)
byte c8;//Временное хранение считаного из индикатора байта
byte m8;//Маска нужного бита в байте
if ((x>60)||(y>15)) return;//Выход за пределы индикатора
WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора
WriteCode(x);//Установить адрес нужного байта
c8=ReadData();//Фиктивное чтение
c8=ReadData();//Чтение нужного байта из индикатора
m8=1<<(y&0x07);//Вычислить маску нужного бита в байте
if (c==1) //Зажигать точку?
c8|=m8//Установить нужный бит в байте
else //Или гасить точку?
c8&=~m8;//Сбросить нужный бит в байте
WriteCode(x);//Снова установить адрес нужного байта
WriteData(c8);//Записать изменённый байт обратно в индикатор
}
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
//Процедура выдачи байта в индикатор
void WriteByte(byte b, bit cd) {
WaitReady(); //Ждать готовности индикатора
//При необходимости настроить здесь шину данных на вывод
PORTB.1=0; PORTB.3=cd; //Выдача байта в индикатор как данных или команды
PORTA=b; //Выдать байт на шину данных индикатора
delay_ms(1); //Это время предустановки адреса (tAW)***** >40ns
PORTB.2=1; delay_ms(1); //***>160ns //Длительность сигнала E=1 (время предустановки данных попало сюда (tDS))
PORTB.2=0; Delay(>(2000ns-40ns-160ns)); //Минимально допустимый интервал между сигналами E=1
}
void WaitReady(void) {//Ждать готовности индикатора, опрашивая байт статуса
//При необходимости настроить здесь шину данных на ввод
PORTB.1=1; PORTB.3=0; //Чтение флага занятости
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
while(PORTA.7==1); //Ждать сброса флага занятости
PORTB.2=0; Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
}
byte ReadByte(bit cd) {
byte b;
WaitReady(); //Ждать готовности индикатора
PORTB.1=1; PORTB.3=cd; //Будем читать байт как команду или данные
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; //Выдать строб в индикатор
delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
b=PORTA; //Прочитать данные с шины индикатора (они на ней уже минимум 120нс)
PORTB.2=0; //Сбросить сигнал E
Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
return b; //Вернуть прочитанный байт
}
//Данные изображения, побитые по строкам и байты будут на индикаторе вертикально.
//Это просто последовательность байт для записи в индикатор начиная с верхней страницы.
//Полностью соответствуют картинке распределения ОЗУ в документации на модуль.
const byte Logo61[2][61]=//61x16 pixel, каждые 8 вертикальных точек собраны в байт
{
{ 0xF8,0xFC,0xFE,0xFB,0xEF,0x7F,0x1F,0x0F,0x0F,0x3F,
0x1F,0x0F,0xBE,0x0C,0x18,0xE0,0x00,0x00,0x08,0x88,
0xE8,0xE8,0xE8,0x08,0x88,0xE8,0xE8,0xE8,0x08,0x08,
0xC8,0xE8,0xE8,0x68,0x68,0x68,0x68,0xE8,0xC8,0xC8,
0x88,0x08,0x08,0x08,0x08,0x88,0xC8,0xE8,0xE8,0xE8,
0x68,0x68,0x68,0x68,0xE8,0xE8,0xE8,0x68,0x68,0x68,
0x68
},
{ 0x0F,0x18,0x27,0x4F,0x43,0x80,0x80,0x80,0x80,0x80,
0x80,0x40,0x40,0xE8,0xFC,0xFF,0x7C,0x1E,0x0F,0x07,
0xFF,0xFF,0xFF,0x1F,0x0F,0xFF,0xFF,0xFF,0x00,0x20,
0x70,0x70,0xE6,0xCE,0xCE,0xCE,0xCE,0xE4,0x71,0x3F,
0xFF,0xF0,0xF8,0x7C,0x3F,0x0F,0x07,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x00
}
};
//******************************
void status_read()
{
PORTB.1=1; // status read
PORTB.3=0;
delay_ms(1);
PORTB.2=1;
delay_ms(1);
while(PORTA.7==1);
PORTB.2=0;
delay_ms(1);
PORTB.2=1;
delay_ms(1);
PORTB.2=0;
delay_ms(1);
}
void glcd_init() // верно
{
// LCD module initialization
PORTB.2=0;
PORTB.0=0; // 1 res
delay_us(15);
PORTB.0=1; // 2 res
delay_ms(2);
PORTB.0=0;
PORTB.1=0; // 3 reset
PORTB.3=0;
PORTA=0b11100010;
PORTB.1=0; // 4 (end)
PORTB.3=0;
PORTA=0b11001110;
PORTB.1=0; // 5 static drive on/off
PORTB.3=0;
PORTA=0b10100100;
PORTB.1=0; // 6 duty select
PORTB.3=0;
PORTA=0b10101000;
PORTB.1=0; // верхнюю строку на 0 (dis start line)
PORTB.3=0;
PORTA=0b11000000;
PORTB.1=0; //NonInvert scan RAM
PORTB.3=0;
PORTA=0b10100000;
PORTB.1=0; // 7 display on/off
PORTB.3=0;
PORTA=0b10101111;
}
void main(void)
{
byte p;//Номер текущей страницы индикатора
byte c;//Позиция по горизонтали выводимого байта
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTB=0xFF;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTC=0xFF;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
PORTB=0;
//============ запуск lcd(инициализация)
glcd_init();
//=============== end of iallisation
for(p=0; p<2; p++) {//Цикл по всем 2-м страницам индикатора
WriteCode(p|0xB8);//Установка текущей страницы для обоих кристаллов индикатора
WriteCode(0x00);//Установка текущего адреса для записи данных в 0
for(c=0; c<61; c++) {//Цикл вывода
WriteData(Logo61[p][c]);//Вывод очередного байта в индикатор
}
}
}
1 Мне не понятно это:
WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора
WriteCode(x);//Установить адрес нужного байта
0xB8|(y>>3)-что это, и что за икс во второй строчке??? Что значит написать код-write code&&&&
2Почему-то компилятор выдает тут ошибку:
if (c==1) //Зажигать точку?
c8|=m8//Установить нужный бит в байте
else //Или гасить точку? -говорит missing ';'
c8&=~m8;//Сбросить нужный бит в байте
3 И не понятно, какой код здесь нужен- "Delay(>(2000ns-40ns-300ns));" Как этот делай осуществить(мне сказали что можно наносекунды заменить на микросекунды, но дело не в этом, а в >(2000ns-40ns-300ns))???
Вот код:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 06.07.2011
Author : PaRaGoN
Company : Administrator
Comments:
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 40,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#define byte char
#define bit int
void Pset(byte x, byte y, bit c) {//Записать одну точку в индикатор (координата 0,0 в левом верхнем углу индикатора)
byte c8;//Временное хранение считаного из индикатора байта
byte m8;//Маска нужного бита в байте
if ((x>60)||(y>15)) return;//Выход за пределы индикатора
WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора
WriteCode(x);//Установить адрес нужного байта
c8=ReadData();//Фиктивное чтение
c8=ReadData();//Чтение нужного байта из индикатора
m8=1<<(y&0x07);//Вычислить маску нужного бита в байте
if (c==1) //Зажигать точку?
c8|=m8//Установить нужный бит в байте
else //Или гасить точку?
c8&=~m8;//Сбросить нужный бит в байте
WriteCode(x);//Снова установить адрес нужного байта
WriteData(c8);//Записать изменённый байт обратно в индикатор
}
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
//Процедура выдачи байта в индикатор
void WriteByte(byte b, bit cd) {
WaitReady(); //Ждать готовности индикатора
//При необходимости настроить здесь шину данных на вывод
PORTB.1=0; PORTB.3=cd; //Выдача байта в индикатор как данных или команды
PORTA=b; //Выдать байт на шину данных индикатора
delay_ms(1); //Это время предустановки адреса (tAW)***** >40ns
PORTB.2=1; delay_ms(1); //***>160ns //Длительность сигнала E=1 (время предустановки данных попало сюда (tDS))
PORTB.2=0; Delay(>(2000ns-40ns-160ns)); //Минимально допустимый интервал между сигналами E=1
}
void WaitReady(void) {//Ждать готовности индикатора, опрашивая байт статуса
//При необходимости настроить здесь шину данных на ввод
PORTB.1=1; PORTB.3=0; //Чтение флага занятости
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
while(PORTA.7==1); //Ждать сброса флага занятости
PORTB.2=0; Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
}
byte ReadByte(bit cd) {
byte b;
WaitReady(); //Ждать готовности индикатора
PORTB.1=1; PORTB.3=cd; //Будем читать байт как команду или данные
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; //Выдать строб в индикатор
delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
b=PORTA; //Прочитать данные с шины индикатора (они на ней уже минимум 120нс)
PORTB.2=0; //Сбросить сигнал E
Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
return b; //Вернуть прочитанный байт
}
//Данные изображения, побитые по строкам и байты будут на индикаторе вертикально.
//Это просто последовательность байт для записи в индикатор начиная с верхней страницы.
//Полностью соответствуют картинке распределения ОЗУ в документации на модуль.
const byte Logo61[2][61]=//61x16 pixel, каждые 8 вертикальных точек собраны в байт
{
{ 0xF8,0xFC,0xFE,0xFB,0xEF,0x7F,0x1F,0x0F,0x0F,0x3F,
0x1F,0x0F,0xBE,0x0C,0x18,0xE0,0x00,0x00,0x08,0x88,
0xE8,0xE8,0xE8,0x08,0x88,0xE8,0xE8,0xE8,0x08,0x08,
0xC8,0xE8,0xE8,0x68,0x68,0x68,0x68,0xE8,0xC8,0xC8,
0x88,0x08,0x08,0x08,0x08,0x88,0xC8,0xE8,0xE8,0xE8,
0x68,0x68,0x68,0x68,0xE8,0xE8,0xE8,0x68,0x68,0x68,
0x68
},
{ 0x0F,0x18,0x27,0x4F,0x43,0x80,0x80,0x80,0x80,0x80,
0x80,0x40,0x40,0xE8,0xFC,0xFF,0x7C,0x1E,0x0F,0x07,
0xFF,0xFF,0xFF,0x1F,0x0F,0xFF,0xFF,0xFF,0x00,0x20,
0x70,0x70,0xE6,0xCE,0xCE,0xCE,0xCE,0xE4,0x71,0x3F,
0xFF,0xF0,0xF8,0x7C,0x3F,0x0F,0x07,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x00
}
};
//******************************
void status_read()
{
PORTB.1=1; // status read
PORTB.3=0;
delay_ms(1);
PORTB.2=1;
delay_ms(1);
while(PORTA.7==1);
PORTB.2=0;
delay_ms(1);
PORTB.2=1;
delay_ms(1);
PORTB.2=0;
delay_ms(1);
}
void glcd_init() // верно
{
// LCD module initialization
PORTB.2=0;
PORTB.0=0; // 1 res
delay_us(15);
PORTB.0=1; // 2 res
delay_ms(2);
PORTB.0=0;
PORTB.1=0; // 3 reset
PORTB.3=0;
PORTA=0b11100010;
PORTB.1=0; // 4 (end)
PORTB.3=0;
PORTA=0b11001110;
PORTB.1=0; // 5 static drive on/off
PORTB.3=0;
PORTA=0b10100100;
PORTB.1=0; // 6 duty select
PORTB.3=0;
PORTA=0b10101000;
PORTB.1=0; // верхнюю строку на 0 (dis start line)
PORTB.3=0;
PORTA=0b11000000;
PORTB.1=0; //NonInvert scan RAM
PORTB.3=0;
PORTA=0b10100000;
PORTB.1=0; // 7 display on/off
PORTB.3=0;
PORTA=0b10101111;
}
void main(void)
{
byte p;//Номер текущей страницы индикатора
byte c;//Позиция по горизонтали выводимого байта
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTB=0xFF;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTC=0xFF;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
PORTB=0;
//============ запуск lcd(инициализация)
glcd_init();
//=============== end of iallisation
for(p=0; p<2; p++) {//Цикл по всем 2-м страницам индикатора
WriteCode(p|0xB8);//Установка текущей страницы для обоих кристаллов индикатора
WriteCode(0x00);//Установка текущего адреса для записи данных в 0
for(c=0; c<61; c++) {//Цикл вывода
WriteData(Logo61[p][c]);//Вывод очередного байта в индикатор
}
}
}
1 Мне не понятно это:
WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора
WriteCode(x);//Установить адрес нужного байта
0xB8|(y>>3)-что это, и что за икс во второй строчке??? Что значит написать код-write code&&&&
2Почему-то компилятор выдает тут ошибку:
if (c==1) //Зажигать точку?
c8|=m8//Установить нужный бит в байте
else //Или гасить точку? -говорит missing ';'
c8&=~m8;//Сбросить нужный бит в байте
3 И не понятно, какой код здесь нужен- "Delay(>(2000ns-40ns-300ns));" Как этот делай осуществить(мне сказали что можно наносекунды заменить на микросекунды, но дело не в этом, а в >(2000ns-40ns-300ns))???
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
1. Вызов функций. Разбирайтесь, что именно они делают - тогда Вам станет понятно, что за WriteCode и WriteByte.
2. Потому что нужно после if вообще ставить фигурные скобки, а c8|=m8 размещать между ними, и после "c8|=m8" нужно поставить точку с запятой.
3. Я так понимаю, что нужно вычислить разность. Тут посмотреть еще на диаграммы в даташите к индикатору надо - внесут ясность. Вы даташит листали, диаграммы видели рассматривали? А менять наносекунды на миллисекунды тоже не вариант - разница-то на шесть порядков. Проще тогда высчитать, сколько нужно выполнить пустых операций, и сделать ассемблерную вставку с nopами.
2. Потому что нужно после if вообще ставить фигурные скобки, а c8|=m8 размещать между ними, и после "c8|=m8" нужно поставить точку с запятой.
3. Я так понимаю, что нужно вычислить разность. Тут посмотреть еще на диаграммы в даташите к индикатору надо - внесут ясность. Вы даташит листали, диаграммы видели рассматривали? А менять наносекунды на миллисекунды тоже не вариант - разница-то на шесть порядков. Проще тогда высчитать, сколько нужно выполнить пустых операций, и сделать ассемблерную вставку с nopами.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

- adrenocrome
- Потрогал лапой паяльник
- Сообщения: 365
- Зарегистрирован: Вт окт 21, 2008 15:03:06
- Откуда: moscow
- Контактная информация:
Re: Подскажите новичку как соединить жк и atmega.
Код: Выделить всё
Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1Ну вот смотри, отними от 2000нс 40нс и 300нс. Сколько получаем? 1660 нс. Это минимальный интевал. Ставь 1мс и не парься. Больше - не меньше, хуже не будет. Это всё минимальные интервалы, за время которых дисплюй должен переварить то, что ты ему скормил. Вполне возможно, что на твоих частотах он вобще без этих delay-ев бут работать. Но изначально лучше их соблюдать.
Код: Выделить всё
2Почему-то компилятор выдает тут ошибку:
if (c==1) //Зажигать точку?
c8|=m8//Установить нужный бит в байте
else //Или гасить точку? -говорит missing ';'
c8&=~m8;//Сбросить нужный бит в байтеВ таком случае во избежание всяких ошибок я пишу в лоб со скобками. Ну и что, что не красиво код выглядит, но на начальном этапе однозначно не вызовет ошибки. Да и вобще стараюсь писать с отступами, так код читается лучше.
Код: Выделить всё
if (c==1){
c8|=m8;
}
else{
c8&=~m8;
};День прошёл, а ты всё жив
- adrenocrome
- Потрогал лапой паяльник
- Сообщения: 365
- Зарегистрирован: Вт окт 21, 2008 15:03:06
- Откуда: moscow
- Контактная информация:
Re: Подскажите новичку как соединить жк и atmega.
SubDia писал(а): А менять наносекунды на миллисекунды тоже не вариант - разница-то на шесть порядков. Проще тогда высчитать, сколько нужно выполнить пустых операций, и сделать ассемблерную вставку с nopами.
Это вариант, когда надо просто запустить дисплюй. Потом, когда оно заработает, для оптимизации можно и поиграться с задержками. Эти 6 порядков невооружённым глазом не заметишь. Если заливать сплошняком дисп 320х240, то тогда конечно
День прошёл, а ты всё жив
Re: Подскажите новичку как соединить жк и atmega.
Да, я с даташита и беру команды. Только не совсем понимаю где Вы прочитали про асемблерные вставки с делай? Почему-то мой хелп в кодвижене не работает.
- adrenocrome
- Потрогал лапой паяльник
- Сообщения: 365
- Зарегистрирован: Вт окт 21, 2008 15:03:06
- Откуда: moscow
- Контактная информация:
Re: Подскажите новичку как соединить жк и atmega.
Alerr писал(а):Да, я с даташита и беру команды. Только не совсем понимаю где Вы прочитали про асемблерные вставки с делай? Почему-то мой хелп в кодвижене не работает.
nop - стандартная команда.
http://ru.wikipedia.org/wiki/Nop
День прошёл, а ты всё жив
Re: Подскажите новичку как соединить жк и atmega.
А можете по возможности, adrenocrome, рассказать как эти функции должны работать???
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
Я читал, вижу даташит на индикатор... Чтение запись... Это всё выставляется портом. Не понятно как с портами связать функцию и что вот она должна делать?????????? Может что передавать, но я пока этого никак не пойму...
Вот последнее что написал и отредактировал:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 06.07.2011
Author : PaRaGoN
Company : Administrator
Comments:
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 40,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#define byte char
#define bit int
void WaitReady(void) {//Ждать готовности индикатора, опрашивая байт статуса
//При необходимости настроить здесь шину данных на ввод
PORTB.1=1; PORTB.3=0; //Чтение флага занятости
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
while(PORTA.7==1); //Ждать сброса флага занятости
PORTB.2=0; delay_ms(1); //Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
}
void Pset(byte x, byte y, bit c) {//Записать одну точку в индикатор (координата 0,0 в левом верхнем углу индикатора)
byte c8;//Временное хранение считаного из индикатора байта
byte m8;//Маска нужного бита в байте
if ((x>60)||(y>15)) return;//Выход за пределы индикатора
PORTB.1=0; PORTB.3=0; PORTA=0b10111000; //&&&WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора ***0xB8- set Page
PORTB.1=0; PORTB.3=0; PORTA=0; //&&&WriteCode(x);//Установить адрес нужного байта
c8=ReadData();//Фиктивное чтение
c8=ReadData();//Чтение нужного байта из индикатора
m8=1<<(y&0x07);//Вычислить маску нужного бита в байте
if (c==1) //Зажигать точку?
c8|=m8;//Установить нужный бит в байте
else //Или гасить точку?
c8&=~m8;//Сбросить нужный бит в байте
PORTB.1=0; PORTB.3=0; PORTA=0; //x=PORTA; // WriteCode(x);//Снова установить адрес нужного байта
PORTB.1=0; PORTB.3=1; PORTA=c8; //WriteData(c8);//Записать изменённый байт обратно в индикатор
}
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
//Процедура выдачи байта в индикатор
void WriteByte(byte b, bit cd) {
WaitReady(); //Ждать готовности индикатора
//При необходимости настроить здесь шину данных на вывод
PORTB.1=0; PORTB.3=cd; //Выдача байта в индикатор как данных или команды
PORTA=b; //Выдать байт на шину данных индикатора
delay_ms(1); //Это время предустановки адреса (tAW)***** >40ns
PORTB.2=1; delay_ms(1); //***>160ns //Длительность сигнала E=1 (время предустановки данных попало сюда (tDS))
PORTB.2=0; delay_ms(1); //Delay(>(2000ns-40ns-160ns)); //Минимально допустимый интервал между сигналами E=1
}
byte ReadByte(bit cd) {
byte b;
WaitReady(); //Ждать готовности индикатора
PORTB.1=1; PORTB.3=cd; //Будем читать байт как команду или данные
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; //Выдать строб в индикатор
delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
b=PORTA; //Прочитать данные с шины индикатора (они на ней уже минимум 120нс)
PORTB.2=0; //Сбросить сигнал E
delay_ms(1); //Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
return b; //Вернуть прочитанный байт
}
//Данные изображения, побитые по строкам и байты будут на индикаторе вертикально.
//Это просто последовательность байт для записи в индикатор начиная с верхней страницы.
//Полностью соответствуют картинке распределения ОЗУ в документации на модуль.
const byte Logo61[2][61]=//61x16 pixel, каждые 8 вертикальных точек собраны в байт
{
{ 0xF8,0xFC,0xFE,0xFB,0xEF,0x7F,0x1F,0x0F,0x0F,0x3F,
0x1F,0x0F,0xBE,0x0C,0x18,0xE0,0x00,0x00,0x08,0x88,
0xE8,0xE8,0xE8,0x08,0x88,0xE8,0xE8,0xE8,0x08,0x08,
0xC8,0xE8,0xE8,0x68,0x68,0x68,0x68,0xE8,0xC8,0xC8,
0x88,0x08,0x08,0x08,0x08,0x88,0xC8,0xE8,0xE8,0xE8,
0x68,0x68,0x68,0x68,0xE8,0xE8,0xE8,0x68,0x68,0x68,
0x68
},
{ 0x0F,0x18,0x27,0x4F,0x43,0x80,0x80,0x80,0x80,0x80,
0x80,0x40,0x40,0xE8,0xFC,0xFF,0x7C,0x1E,0x0F,0x07,
0xFF,0xFF,0xFF,0x1F,0x0F,0xFF,0xFF,0xFF,0x00,0x20,
0x70,0x70,0xE6,0xCE,0xCE,0xCE,0xCE,0xE4,0x71,0x3F,
0xFF,0xF0,0xF8,0x7C,0x3F,0x0F,0x07,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x00
}
};
//******************************
void glcd_init() // верно
{
// LCD module initialization
PORTB.2=0;
PORTB.0=0; // 1 res
delay_us(15);
PORTB.0=1; // 2 res
delay_ms(2);
PORTB.0=0;
PORTB.1=0; // 3 reset
PORTB.3=0;
PORTA=0b11100010;
PORTB.1=0; // 4 (end)
PORTB.3=0;
PORTA=0b11001110;
PORTB.1=0; // 5 static drive on/off
PORTB.3=0;
PORTA=0b10100100;
PORTB.1=0; // 6 duty select
PORTB.3=0;
PORTA=0b10101000;
PORTB.1=0; // верхнюю строку на 0 (dis start line)
PORTB.3=0;
PORTA=0b11000000;
PORTB.1=0; //NonInvert scan RAM
PORTB.3=0;
PORTA=0b10100000;
PORTB.1=0; // 7 display on/off
PORTB.3=0;
PORTA=0b10101111;
}
void main(void)
{
byte p;//Номер текущей страницы индикатора
byte c;//Позиция по горизонтали выводимого байта
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTB=0xFF;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTC=0xFF;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
PORTB=0;
//============ запуск lcd(инициализация)
glcd_init();
//=============== end of iallisation
for(p=0; p<2; p++) {//Цикл по всем 2-м страницам индикатора
WriteCode(p|0xB8);//Установка текущей страницы для обоих кристаллов индикатора
WriteCode(0x00);//Установка текущего адреса для записи данных в 0
for(c=0; c<61; c++) {//Цикл вывода
WriteData(Logo61[p][c]);//Вывод очередного байта в индикатор
}
}
}
Вот команды дисплея, которыми я пользуюсь:
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
Я читал, вижу даташит на индикатор... Чтение запись... Это всё выставляется портом. Не понятно как с портами связать функцию и что вот она должна делать?????????? Может что передавать, но я пока этого никак не пойму...
Вот последнее что написал и отредактировал:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 06.07.2011
Author : PaRaGoN
Company : Administrator
Comments:
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 40,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#define byte char
#define bit int
void WaitReady(void) {//Ждать готовности индикатора, опрашивая байт статуса
//При необходимости настроить здесь шину данных на ввод
PORTB.1=1; PORTB.3=0; //Чтение флага занятости
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
while(PORTA.7==1); //Ждать сброса флага занятости
PORTB.2=0; delay_ms(1); //Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
}
void Pset(byte x, byte y, bit c) {//Записать одну точку в индикатор (координата 0,0 в левом верхнем углу индикатора)
byte c8;//Временное хранение считаного из индикатора байта
byte m8;//Маска нужного бита в байте
if ((x>60)||(y>15)) return;//Выход за пределы индикатора
PORTB.1=0; PORTB.3=0; PORTA=0b10111000; //&&&WriteCode(0xB8|(y>>3));//Установить нужную страницу индикатора ***0xB8- set Page
PORTB.1=0; PORTB.3=0; PORTA=0; //&&&WriteCode(x);//Установить адрес нужного байта
c8=ReadData();//Фиктивное чтение
c8=ReadData();//Чтение нужного байта из индикатора
m8=1<<(y&0x07);//Вычислить маску нужного бита в байте
if (c==1) //Зажигать точку?
c8|=m8;//Установить нужный бит в байте
else //Или гасить точку?
c8&=~m8;//Сбросить нужный бит в байте
PORTB.1=0; PORTB.3=0; PORTA=0; //x=PORTA; // WriteCode(x);//Снова установить адрес нужного байта
PORTB.1=0; PORTB.3=1; PORTA=c8; //WriteData(c8);//Записать изменённый байт обратно в индикатор
}
void WriteCode(byte b) { WriteByte(b,0); }
void WriteData(byte b) { WriteByte(b,1); }
byte ReadData(void) { return ReadByte(1); }//Прочитать байт данных из индикатора
//Процедура выдачи байта в индикатор
void WriteByte(byte b, bit cd) {
WaitReady(); //Ждать готовности индикатора
//При необходимости настроить здесь шину данных на вывод
PORTB.1=0; PORTB.3=cd; //Выдача байта в индикатор как данных или команды
PORTA=b; //Выдать байт на шину данных индикатора
delay_ms(1); //Это время предустановки адреса (tAW)***** >40ns
PORTB.2=1; delay_ms(1); //***>160ns //Длительность сигнала E=1 (время предустановки данных попало сюда (tDS))
PORTB.2=0; delay_ms(1); //Delay(>(2000ns-40ns-160ns)); //Минимально допустимый интервал между сигналами E=1
}
byte ReadByte(bit cd) {
byte b;
WaitReady(); //Ждать готовности индикатора
PORTB.1=1; PORTB.3=cd; //Будем читать байт как команду или данные
delay_ms(1); //Это время предустановки адреса (tAW) ***>40ns
PORTB.2=1; //Выдать строб в индикатор
delay_ms(1); //***>300ns //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
b=PORTA; //Прочитать данные с шины индикатора (они на ней уже минимум 120нс)
PORTB.2=0; //Сбросить сигнал E
delay_ms(1); //Delay(>(2000ns-40ns-300ns)); //Минимально допустимый интервал между сигналами E=1
return b; //Вернуть прочитанный байт
}
//Данные изображения, побитые по строкам и байты будут на индикаторе вертикально.
//Это просто последовательность байт для записи в индикатор начиная с верхней страницы.
//Полностью соответствуют картинке распределения ОЗУ в документации на модуль.
const byte Logo61[2][61]=//61x16 pixel, каждые 8 вертикальных точек собраны в байт
{
{ 0xF8,0xFC,0xFE,0xFB,0xEF,0x7F,0x1F,0x0F,0x0F,0x3F,
0x1F,0x0F,0xBE,0x0C,0x18,0xE0,0x00,0x00,0x08,0x88,
0xE8,0xE8,0xE8,0x08,0x88,0xE8,0xE8,0xE8,0x08,0x08,
0xC8,0xE8,0xE8,0x68,0x68,0x68,0x68,0xE8,0xC8,0xC8,
0x88,0x08,0x08,0x08,0x08,0x88,0xC8,0xE8,0xE8,0xE8,
0x68,0x68,0x68,0x68,0xE8,0xE8,0xE8,0x68,0x68,0x68,
0x68
},
{ 0x0F,0x18,0x27,0x4F,0x43,0x80,0x80,0x80,0x80,0x80,
0x80,0x40,0x40,0xE8,0xFC,0xFF,0x7C,0x1E,0x0F,0x07,
0xFF,0xFF,0xFF,0x1F,0x0F,0xFF,0xFF,0xFF,0x00,0x20,
0x70,0x70,0xE6,0xCE,0xCE,0xCE,0xCE,0xE4,0x71,0x3F,
0xFF,0xF0,0xF8,0x7C,0x3F,0x0F,0x07,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x00
}
};
//******************************
void glcd_init() // верно
{
// LCD module initialization
PORTB.2=0;
PORTB.0=0; // 1 res
delay_us(15);
PORTB.0=1; // 2 res
delay_ms(2);
PORTB.0=0;
PORTB.1=0; // 3 reset
PORTB.3=0;
PORTA=0b11100010;
PORTB.1=0; // 4 (end)
PORTB.3=0;
PORTA=0b11001110;
PORTB.1=0; // 5 static drive on/off
PORTB.3=0;
PORTA=0b10100100;
PORTB.1=0; // 6 duty select
PORTB.3=0;
PORTA=0b10101000;
PORTB.1=0; // верхнюю строку на 0 (dis start line)
PORTB.3=0;
PORTA=0b11000000;
PORTB.1=0; //NonInvert scan RAM
PORTB.3=0;
PORTA=0b10100000;
PORTB.1=0; // 7 display on/off
PORTB.3=0;
PORTA=0b10101111;
}
void main(void)
{
byte p;//Номер текущей страницы индикатора
byte c;//Позиция по горизонтали выводимого байта
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTB=0xFF;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTC=0xFF;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
PORTB=0;
//============ запуск lcd(инициализация)
glcd_init();
//=============== end of iallisation
for(p=0; p<2; p++) {//Цикл по всем 2-м страницам индикатора
WriteCode(p|0xB8);//Установка текущей страницы для обоих кристаллов индикатора
WriteCode(0x00);//Установка текущего адреса для записи данных в 0
for(c=0; c<61; c++) {//Цикл вывода
WriteData(Logo61[p][c]);//Вывод очередного байта в индикатор
}
}
}
Вот команды дисплея, которыми я пользуюсь:
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
adrenocrome писал(а):Это вариант, когда надо просто запустить дисплюй. Потом, когда оно заработает, для оптимизации можно и поиграться с задержками. Эти 6 порядков невооружённым глазом не заметишь. Если заливать сплошняком дисп 320х240, то тогда конечноА так сидеть, высчитывать сколько там тактов этот nop занимает, сколько времени такт у камня длится именно на твоём резонаторе и подгонять подхар-ки дисплюя.
Согласен. Просто стараюсь всегда максимально приближать задержки к реально требующимся (если нужно >1000 нс, лучше поставить 2 us, чем 1 ms).
Alerr, эти функции - функции установки команды индикатору, установки данных и чтения данных.
Давайте разберем функцию WriteCode (byte b). Видим, что эта функция всего лишь обращается к функции WriteByte, но при условии, что переменная cd = 0. Смотрим функцию WriteByte. Переменная cd у нас выгружается на вывод PORTB.3 - очевидно, это управляющий вывод, который отвечает за запись команды/данных в индикатор. Мы установили на этом выводе 0 - и индикатор понимает, что в данный момент мы пишем именно команду. Далее нужно вывести байт данных на шину данных индикатора, этот байт данных содержит переменная b (это собственно команда). В функции WriteByte мы видим, что переменная b должна выводится в PORTA - стало быть, порт A у нас целиком подсоединен к шине данных ЖКИ. Единственное, чего я не вижу - это собственно присвоения переменной b какого-либо значения.
С остальными функциями все то же самое.
ЗЫ. PORTA сконфигурирован как вход в main - что за ..?
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

Re: Подскажите новичку как соединить жк и atmega.
Вроде понял Вас, но даже когда я присваивал этому b значение 0-программа просто не шла(те же ошибки)
- SubDia
- Держит паяльник хвостом
- Сообщения: 995
- Зарегистрирован: Сб апр 02, 2011 17:59:22
- Откуда: Город-герой Севастополь
Re: Подскажите новичку как соединить жк и atmega.
Нет, ну так дело не пойдет. Вы должны понимать, что b - это не просто какая-то константа. Вначале Вы устанавливаете начальный адрес - адрес страницы, затем адрес столбца, после выгружаете байт данных (те данные, что уже пойдут на индикацию). Она все время будет меняться. Вам нужно всегда знать, в каком месте программы какое значение будет иметь эта переменная.
Откровенно говоря (не обижайтесь только), мне кажется, что Вы слишком крутую задачу себе задали. Взяли бы простенький сегментный ЖК индикатор (у тех же МЭЛТов), потренировались бы на нем - поначалу и там будет куча подводных камней, и соответственно, вопросов.
А так Вы просто сейчас бьетесь над тем, чего не понимаете. Взять исходник от МЭЛТ и вставить в свой код - этого мало, увы..
Откровенно говоря (не обижайтесь только), мне кажется, что Вы слишком крутую задачу себе задали. Взяли бы простенький сегментный ЖК индикатор (у тех же МЭЛТов), потренировались бы на нем - поначалу и там будет куча подводных камней, и соответственно, вопросов.
А так Вы просто сейчас бьетесь над тем, чего не понимаете. Взять исходник от МЭЛТ и вставить в свой код - этого мало, увы..
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )

MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
