#include <avr/io.h>
#define TIME 10 //Константа временной задержки для ЖКИ
#define RS 6 //RS=PA6 - сигнал управления ЖКИ
#define E 5 //E=PA5 - сигнал управления ЖКИ
/*
дисплей HD44780 и контроллер attiny24A
---------------------------------------------------
выводам D5-D8 дисплея соответствуют выводы A0-A3 МК
на вывод RS дисплея подается низкий логический уровень
*/
//Программа для формирования задержки
void pause (unsigned long int a)
{
unsigned long int i;
for (i=a;i>0;i--);
}
//Программа передачи команд в ЖКИ
void lcd_com (unsigned char lcd)
{
unsigned char temp;
temp = ((lcd >> 4)&~(1<<RS))|(1<<E); // RS=0 – это команда
PORTA = temp; // Выводим на portА старшую тетраду команды, сигналы RS, E
pause(TIME*10); // Небольшая задержка для стабилизации
PORTA = temp&~(1<<E); // Сигнал записи команды
pause(TIME*100); // задержка между циклами записи
temp=(((lcd<<4)>>4)&~(1<<RS))|(1<<E);// RS=0 – это команда
PORTA=temp; // Выводим на portА младшую тетраду команды, сигналы RS, E
pause(TIME*10); // Небольшая задержка для стабилизации
PORTA = temp&~(1<<E); // Сигнал записи команды
pause (100*TIME); //Пауза для выполнения команды
}
//Программа записи данных в ЖКИ
void lcd_dat (unsigned char lcd)
{
unsigned char temp;
temp=((lcd>>4)|(1<<RS))|(1<<E); //RS=1 – это данные
PORTA=temp; //Выводим на portА старшую тетраду данных, сигналы RS, E
pause(TIME*10); //Небольшая задержка для стабилизации
PORTA = temp&~(1<<E); //Сигнал записи данных
pause(TIME*100); // задержка между циклами записи
temp=(((lcd<<4)>>4)|(1<<RS))|(1<<E); //RS=1 – это данные
PORTA=temp; //Выводим на portА младшую тетраду данных, сигналы RS, E
pause(TIME*10); //Небольшая задержка для стабилизации
PORTA = temp&~(1<<E); //Сигнал записи данных
pause(TIME*100); //Пауза для вывода данных
}
//Программа иниализации ЖКИ
void lcd_init (void)
{
lcd_com(0x28); // 4-проводный интерфейс, 2 строки, 5х8 символ
pause(400*TIME);
lcd_com(0x08); // отключили дисплей
pause(400*TIME);
lcd_com(0x01); // Очистить DDRAM и установить курсор на 0x00
pause(400*TIME);
lcd_com(0x06); // инкремент адреса, сдвиг экрана отключен
pause(400*TIME);
lcd_com(0x0E); // Показать изображение, курсор показывать
pause(400*TIME);
}
int main(void)
{
DDRA=0xEF;
PORTA=0x00;
/*
задержки выставлены по протеусу. 60*TIME соответствует 20мс при 8МГц. Такой задержки
должно хватить для выполнения любой операции
*/
pause(60*TIME); // задержка после установления напряжения питания
/*
троекратная команда установки 8-битного режима для раздупления дисплея. Вместо 0x30 подается
0x03, т.к. у меня выводам D5-D8 дисплея соответствуют выводы D0-D3 МК
*/
PORTA = 0x03;
pause(60*TIME);
PORTA = 0x03;
pause(60*TIME);
PORTA = 0x03;
pause(60*TIME);
PORTA = 0x02;
pause(60*TIME); // установка 4-битного режима, далее дисплей работает в нем
lcd_init();
lcd_dat('w'); //Вывод "w"
while(1); // ожидание лучших времен
}
видно, не правильно проходит инициализация, т.к. на дисплее не выводится даже курсор. задержки между командами ставил бешеные, команды вроде по даташиту. что не так?
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
там возле каждого вывода "лампочки" горят. я по ним ориентируюсь. ошибку в инициализации нашел. я подавал на D4-D7 команды установки 8-битного режима, а строб. импульс - нет) тепрерь дисплей работает. выдает всякий мусор. ищу дальше. исправленный кусок кода:
int main(void)
{
DDRA=0xEF;
PORTA=0x00;
/*
задержки выставлены по протеусу. 60*TIME соответствует 20мс при 8МГц. Такой задержки
должно хватить для выполнения любой операции
*/
pause(60*TIME); // задержка после установления напряжения питания
/*
троекратная команда установки 8-битного режима для раздупления дисплея. Вместо 0x30 подается
0x03, т.к. у меня выводам D5-D8 дисплея соответствуют выводы D0-D3 МК
*/
PORTA = ((0x03)&~(1<<RS))|(1<<E);
pause(TIME*10);
PORTA = ((0x03)&~(1<<RS))&~(1<<E);
pause(60*TIME);
PORTA = ((0x03)&~(1<<RS))|(1<<E);
pause(TIME*10);
PORTA = ((0x03)&~(1<<RS))&~(1<<E);
pause(60*TIME);
PORTA = ((0x03)&~(1<<RS))|(1<<E);
pause(TIME*10);
PORTA = ((0x03)&~(1<<RS))&~(1<<E);
pause(60*TIME);
PORTA = ((0x02)&~(1<<RS))|(1<<E);
pause(TIME*10);
PORTA = ((0x02)&~(1<<RS))&~(1<<E);
pause(60*TIME); // установка 4-битного режима, далее дисплей работает в нем
upd: работало все правильно) это был не мусор, а глюк в протеусе. дисплей, повернутый на 90 градусов продолжает выводить текст горизонтально) из-за этого невозможно разобрать буквы
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
вместо того, чтобы изобретать велосипед (ваша функция pause), который тем более не всегда поедет (включите оптимизицию и увидите результат), лучше бы воспользовались стандартной функцией _delay_ms()
битва с дураками проиграна, победители торжествуют. слава победителям!
для использования _delay_ms() нужно подключать библиотеку без оптимизации тогда программа (я выкладывал часть для работы с дисплеем) занимает около 6кБ. шиться будет тинька24. не влезет. если включить оптимизацию, программа станет весить в разы меньше, но при этом работать она перестанет. не умею я еще писать код, понятный компилятору...
а так, без лишних библиотек и оптимизации, код занимает около 90% памяти. меня устраивает
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
slavokhire5 писал(а):для использования _delay_ms() нужно подключать библиотеку без оптимизации тогда программа (я выкладывал часть для работы с дисплеем) занимает около 6кБ. шиться будет тинька24. не влезет. если включить оптимизацию, программа станет весить в разы меньше, но при этом работать она перестанет. не умею я еще писать код, понятный компилятору...
а так, без лишних библиотек и оптимизации, код занимает около 90% памяти. меня устраивает
не занимайтесь ерундой, осваивайте WinAVR и пишите нормальные ПРАВИЛЬНЫЕ программы. не поступайте, как герой анекдота "я соленые огурцы не ем - у меня голова в баллон не пролазит". без оптимизации программы для МК - это НОНСЕНС! то, что после оптимизации ваша программа не работает, свидетельствует о грубых в ней ошибках. поверьте: такая программа и без оптимизации вас подведет обязательно!
битва с дураками проиграна, победители торжествуют. слава победителям!