Пожалуйста тыкнете носом в ошибку =)
Спойлер
Код: Выделить всё
/*
* ATMega8_GLCD.cpp
*
* Created: 29.03.2014 14:01:14
* Author: Администратор
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/delay.h>
#define GLCD_DATA_DDR DDRD
#define GLCD_DATA_PORT PORTD
#define GLCD_CTRL_DDR DDRC
#define GLCD_CTRL_PORT PORTC
#define GLCD_CTRL_A0 _BV(0)
#define GLCD_CTRL_RW _BV(1)
#define GLCD_CTRL_E _BV(2)
#define GLCD_CTRL_RES _BV(3)
#define GLCD_SET_A0 GLCD_CTRL_PORT |= GLCD_CTRL_A0
#define GLCD_SET_RW GLCD_CTRL_PORT |= GLCD_CTRL_RW
#define GLCD_SET_E GLCD_CTRL_PORT |= GLCD_CTRL_E
#define GLCD_SET_RES GLCD_CTRL_PORT |= GLCD_CTRL_RES
#define GLCD_RESET_A0 GLCD_CTRL_PORT &= ~GLCD_CTRL_A0
#define GLCD_RESET_RW GLCD_CTRL_PORT &= ~GLCD_CTRL_RW
#define GLCD_RESET_E GLCD_CTRL_PORT &= ~GLCD_CTRL_E
#define GLCD_RESET_RES GLCD_CTRL_PORT &= ~GLCD_CTRL_RES
void WaitReady(void) //Ждать готовности индикатора, опрашивая байт статуса
{
GLCD_DATA_DDR = 0x00; //При необходимости настроить здесь шину данных на вxод
GLCD_SET_RW;
GLCD_RESET_A0; //Чтение флага занятости
_delay_us(1); //Это время предустановки адреса (tAW)
GLCD_SET_E;
_delay_us(1); //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
while(GLCD_DATA_PORT & 1<<7); //Ждать сброса флага занятости
GLCD_RESET_E;
_delay_us(2); //Минимально допустимый интервал между сигналами E=1
}
void WriteByte(char b, bool cd) //Процедура выдачи байта в индикатор
{
WaitReady(); //Ждать готовности индикатора
GLCD_DATA_DDR = 0xFF; //При необходимости настроить здесь шину данных на вывод
GLCD_RESET_RW;
if (cd) //Выдача байта в индикатор как данных или команды
{
GLCD_SET_A0;
}
else
{
GLCD_RESET_A0;
}
GLCD_DATA_PORT = b; //Выдать байт на шину данных индикатора
_delay_us(1); //Это время предустановки адреса (tAW)
GLCD_SET_E;
_delay_us(1); //Длительность сигнала E=1 (время предустановки данных попало сюда (tDS))
GLCD_RESET_E;
_delay_us(2); //Минимально допустимый интервал между сигналами E=1
}
char ReadByte(bool cd)
{
char b;
WaitReady(); //Ждать готовности индикатора
GLCD_SET_RW;
if (cd) //Будем читать байт как команду или данные
{
GLCD_SET_A0;
}
else
{
GLCD_RESET_A0;
}
GLCD_DATA_DDR = 0x00;
_delay_us(1); //Это время предустановки адреса (tAW)
GLCD_SET_E; //Выдать строб в индикатор
_delay_us(1); //Минимально допустимая длительность сигнала E=1 (время доступа (tACC) попало сюда)
b = GLCD_DATA_PORT; //Прочитать данные с шины индикатора (они на ней уже минимум 120нс)
GLCD_RESET_E; //Сбросить сигнал E
_delay_us(2); //Минимально допустимый интервал между сигналами E=1
return b; //Вернуть прочитанный байт
}
void WriteCode(bool b)
{
WriteByte(b,0);
}
void WriteData(char b)
{
WriteByte(b,1);
}
char ReadData(void) //Прочитать байт данных из индикатора
{
return ReadByte(1);
}
void LCDinit(void)
{
GLCD_RESET_E; //Начальное значение сигнала индикатору
GLCD_RESET_RES; //Выдать сигнал RES=0 индикатору
_delay_us(11); //Задержка на время больше 10 мкс
GLCD_SET_RES; //Снять сигнал RES
_delay_ms(2); //Задержка на время больше 1 мс
WriteCode(0xE2); //Reset
WriteCode(0xEE); //ReadModifyWrite off
WriteCode(0xA4); //Включить обычный режим
WriteCode(0xA8); //Мультиплекс 1/16
WriteCode(0xC0); //Верхнюю строку на 0
WriteCode(0xA0); //NonInvert scan RAM
WriteCode(0xAF); //Display on
}
void Pset(char x, char y, bool c) //Записать одну точку в индикатор (координата 0,0 в левом верхнем углу индикатора)
{
char c8; //Временное хранение считанного из индикатора байта
char 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); //Записать изменённый байт обратно в индикатор
}
//Данные изображения, побитые по строкам и байты будут на индикаторе вертикально.
//Это просто последовательность байт для записи в индикатор начиная с верхней страницы.
//Полностью соответствуют картинке распределения ОЗУ в документации на модуль.
const char 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
}
};
int main(void)
{
LCDinit();
for(char p=0; p<2; p++)
{ //Цикл по всем 2-м страницам индикатора
WriteCode(p|0xB8); //Установка текущей страницы для обоих кристаллов индикатора
WriteCode(0x00); //Установка текущего адреса для записи данных в 0
for(char c=0; c<61; c++) //Цикл вывода
{
WriteData(Logo61[p][c]); //Вывод очередного байта в индикатор
}
}
while(1)
{
}
}
Спасибо!