Понедельник, 29.04.2024, 07:11
Главная
Приветствую Вас, Гость
Статистика



Онлайн лист

Онлайн всего: 1
Гостей: 1
Пользователей: 0



Реклама



Главная » Статьи » Микроконтроллеры

Наверх


Микроконтроллер AVR + LCD (HD44780)
Сейчас в интернете множество схем и устройств на основе микроконтроллеров и LCD дисплеев. Одними из распространенных LCD являются дисплеи с контролером HD44780. Это алфавитно-циферный дисплей, встречается с различным количеством строк и символов в строке, но в данном случае это не принципиально.

Думаю рассказывать о возможных способах применения такого дисплея нет необходимости, потому что они велики и каждый найдет свой, будь то экран для отображения результатов каких либо измерений, различной отладочной информации и т.д.

Описание контроллера можно и даже нужно посмотреть здесь.

Теперь перейдем непосредственно к делу. Для простоты собирать буду сначала не в железе а в PROTEUS'е для симуляции, это позволит попробовать не приобретая деталей и не прибегая к пайке, а также отладить программу и получить желаемый результат.

На рисунке ниже: микроконтроллер Atmega16, дисплей lm016l (он как раз таки на основе контролера HD44780):



Для подключения дисплея была использована 4-х разрядная линия данных, значит для передачи данный в контроллер дисплея нам понадобятся только D4-D7. Этот способ подходит в большинстве случаев и требует меньшее количество ног для подключения от микроконтроллера.

Для написания прошивки (программы микроконтроллера) я буду использовать CodeVisionAVR. В нашем случае вместе с этой программой будет проще всего начинать знакомится с дисплеем.

Итак запустим CodeVisionAVR и создадим новый проект с использованием встроенного automatic program generator: для этого в меню File выбираем New, File Type выбираем Project и жмем ОК. В появившемся окошке с вопросом жмем на YES. Перед нами открылся генератор создания программы:



Во вкладке Chip выбираем интересующий нас микроконтроллер Atmega16, в поле clock запишем 8, это частота на которой будет работать микроконтроллер. Далее переходим во вкладку LCD. Здесь нам предлагают выбрать порт к которому будет подключаться дисплей, я выбрал PORTC:



После выбора порта генератор выводит нам информацию о том как дисплей должен быть подключен к микроконтроллеру (соответствие выводов микроконтроллера и дисплея). Именно так и подключаем дисплей. Больше нам сейчас никаких настроек не понадобится, поэтому выбираем File -> Generate, Save and Exit, и сохраняем файлы проекта куда-нибудь в отдельную папочку.

Что мы имеем на этом этапе: генератор создал основной каркас со всеми необходимыми настройками, нам останется лишь дописать несколько команд для вывода информации на экран.


#include <mega16.h>   

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>


// Declare your global variables here

void main(void)
{
// 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=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

PORTB=0x00;
DDRB=0x00;

// Port C 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

PORTC=0x00;
DDRC=0x00;

// Port D 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

PORTD=0x00;
DDRD=0x00;

// 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: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 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: Timer 2 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;

// LCD module initialization
lcd_init(16);

while (1)
{
// Place your code here

};
}



Теперь я уберу из кода лишние комментарии, а строки касающиеся непосредственно настройки микроконтроллера я убера в отдельную процедуру avr_init() для большей наглядности и удобства работы


#include <mega16.h> 
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
void avr_init(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;

}

void main(void)
{

avr_init(); // Основные настрокий микроконтроллера
lcd_init(16); // Инициализация экрана

while (1)
{
// цикл бесконечного выполнения кода

};
}


Дисплей мы подключили и проинициализировали, теперь нужно на него что нибудь вывести. Для работы с дисплеем в нашем распоряжении есть следующие функции:

lcd_clear() - полная очистка дисплея;
lcd_gotoxy(unsigned char x, unsigned char y) - задает положение курсора на экране, х - номер символа, у - номер строки, нумерация начинается с 0 символа и 0 строки. Если положение курсора не задать то информация будет выводится начиная с 0,0 и продолжать дальше заполняя каждую ячейку экрана.

lcd_putchar(char c) - выводит на дисплей один символ;
например lcd_putchar('N') - выведет на экран букву N, но эту же букву можно вывести немного по другому:   lcd_putchar(0x4E), здесь уже в роли параметра в скобках выступает не сам символ, а его адрес в таблице контролера дисплея (подробнее об этом я напишу в следующей статье);

lcd_puts(char *str) - выводит на дисплей строку из SRAM памяти;
lcd_putsf(char flash *str) - выводит на дисплей строку из  FLASH памяти;

Для вывода слова или фразы проще всего использовать следующий вариант: 

lcd_putsf("Naprisar.at.ua");  слово или выражение в кавычках будет выведено на экран именно в таком виде, и не нужно заранее объявлять дополнительные переменные.

С основными функция разобрались теперь пора выводить первую надпись на экран.
Для этого добавим в нашу программу, сразу после lcd_init(16); следующие строки:


lcd_clear(); // Чистим экран 
lcd_gotoxy(2,0); // Смещаем курсор на первой строке для выравнивания текста
lcd_putsf("Test Passed"); // Нашее сообщение
lcd_gotoxy(1,1); // Смещаем курсор второй строки
lcd_putsf("Naprisar.at.ua"); // Нашее сообщение



Код готов, теперь подготовим прошивку, для этого поочередно жмем кнопки изображенные на картинке:


и если ошибок нет то в папке с проектом у нас появился файл с раcширением .hex, это и есть файл прошивки, его можно загрузить в PROTEUS или залить в микроконтроллер. В результате должно получится:

Если сразу что то пошло не так, не спешите расстраиваться и отчаиваться, просто внимательно все проверьте, для симуляции в PROTEUS'e не забудьте указать местоположение прошивки в свойствах микроконтроллера и в строке CKSEL Fuses: выбрать Int.RC 8MHz (тактирование от внутреннего генератора с частотой в 8 МГц, эту частоту мы выбирали в начале в генераторе кода).

Исходники программы и проект PROTEUS'a скачать можно ЗДЕСЬ


Нравится
Категория: Микроконтроллеры | Добавил: Naprisar (02.04.2012)
Просмотров: 18949 | Комментарии: 8 | Теги: AVR, HD44780, ATmega16, микроконтроллер, LCD
Всего комментариев: 8
8 сергей  
0
а как быть если у меня amega32?
данные передаются по порту В, а rs r/w и е по порту А

4 евгений  
0
не) там контроллер другой, по ходу S6B0066U

5 Naprisar  
0
Я на сколько понял, пробежавшись по интернету, S6B0066U это аналог HD44780. А как ведет себя дисплей вообще?? ВЫводит хоть тчо нибудь?? Подключен ли переменный резистор, в выводу контрастности и видны ли при максимальной контрастности на экране вместо букв прямоугольники???

6 Евгений  
0
да я тоже читал про это, но программа по Вашему исходнику не работает. Не сочтите за рекламу, но на этом форуме, в сообщении с фотографией работающего микроконтроллера лежит ссылка на прошивку
http://myrobot.ru/forum/topic.php?forum=9&topic=58&p=2
У того человека дисплей с контроллером  S6B0066U. Жаль в архиве нет исходного файла, там только hex и файлы библиотек, но его hex у меня заработал, мой дисплей начал показывать. Хотя в протеусе моделирую всё на одном дисплее  LM016.  Скорее всего тот человек использовал другую билиотеку, не lsd.h

7 Евгений  
0
т.е lсd.h

3 евгений  
0
У меня не работает на дисплее WH1602B-NYG-CT0.. Видимо руки кривые

1 евгений  
0
Atmega16 c заводским настройками ( 1МГц внутренний генератор) после прошивки вашим кодом работать не будет?

2 Naprisar  
0
Чтобы не заморачиваться с фьюзами, в CodeWizarde можно сразу выбрать частоту 1 МГц а не 8, но как показала практика, даже, и с таки настройками работает встроенном генераторе спокойно

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Наверх