Как подключить LСD дисплей на базе HD44780 к ATmega16 или его цифровой аналог LM016L 16×2 в Proteus
При работе с Arduino, Atmega, PIC или с другим микроконтроллером часто возникает необходимость вывести какие-либо текстовые данные на дисплей. С цифрами проще, можно использовать 7 сегментный индикатор, а для вывода текста необходимо использовать LCD-дисплеи (ЖКИ). В данной статьи мы рассмотрим подключение LCD-дисплея на базе контроллера HD44780 к ATmega16.
Для подключения LCD-дисплея на базе HD44780 к ATmega16 нам нужно использовать 12 выводов, можно и все 16, но не на всех контроллерах это удастся сделать, ибо физически невозможно, а программно — да:
- 1 — Vss, земля -> GND
- 2 — Vdd, питание -> +5 В
- 3 — Vo (Vee), управление контрастностью напряжением -> выход потенциометра
- 4 — RS, выбор регистра
- 5 — R/W, чтение/запись -> земля (режим записи)
- 6 — E, он же Enable, cтроб по спаду
- 7-10 — DB0-DB3, младшие биты 8-битного интерфейса; не подключены
- 11-14 — DB4-DB7, старшие биты интерфейса
- 15 — A, питание для подсветки -> +5 В
- 16 — K, земля для подсветки -> GND
Пример программы в Atmel Studio 7
LCD.h
#ifndef LCD_H_ #define LCD_H_ #define LCDDATAPORT PORTB // Порт и пины, #define LCDDATADDR DDRB // к которым подключены #define LCDDATAPIN PINB // сигналы D4-D7. #define LCD_D4 3 #define LCD_D5 4 #define LCD_D6 5 #define LCD_D7 6 #define LCDCONTROLPORT PORTB // Порт и пины, #define LCDCONTROLDDR DDRB // к которым подключены #define LCD_RS 0 // сигналы RS, RW и E. #define LCD_RW 1 #define LCD_E 2 #define LCD_STROBEDELAY_US 5 // Задержка строба #define LCD_COMMAND 0 #define LCD_DATA 1 #define LCD_CURSOR_OFF 0 #define LCD_CURSOR_ON 2 #define LCD_CURSOR_BLINK 3 #define LCD_DISPLAY_OFF 0 #define LCD_DISPLAY_ON 4 #define LCD_SCROLL_LEFT 0 #define LCD_SCROLL_RIGHT 4 #define LCD_STROBDOWN 0 #define LCD_STROBUP 1 #define DELAY 1 void lcdSendNibble(char byte, char state); char lcdGetNibble(char state); char lcdRawGetByte(char state); void lcdRawSendByte(char byte, char state); char lcdIsBusy(void); void lcdInit(void); void lcdSetCursor(char cursor); void lcdSetDisplay(char state); void lcdClear(void); void lcdGotoXY(char str, char col); void lcdDisplayScroll(char pos, char dir); void lcdPuts(char *str); void lcdPutsf(char *str); void lcdPutse(uint8_t *str); void lcdLoadCharacter(char code, char *pattern); void lcdLoadCharacterf(char code, char *pattern); void lcdLoadCharactere(char code, char *pattern); #endif /* LCD_H_ */
LCD.c
// Подключение LCD на базе HD44780 к ATmega16 (LM016L LCD 16x2) // сайт http://micro-pi.ru #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/eeprom.h> #include <avr/interrupt.h> #include "LCD.h" /* Отправляет младшую половину байта byte в LCD. Если state == 0, то передаётся как команда, если нет, то как данные. */ void lcdSendNibble(char byte, char state) { // Пины управления - на выход LCDCONTROLDDR |= 1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E; // Пины данных - на выход LCDDATADDR |= 1<<LCD_D4 | 1<<LCD_D5 | 1<<LCD_D6 | 1<<LCD_D7; // Режим записи, RW = 0 LCDCONTROLPORT &= ~(1<<LCD_RW); // Устанавливаем 1 в RS if (state) { // если отдаём данные LCDCONTROLPORT |= 1<<LCD_RS; } else { LCDCONTROLPORT &= ~(1<<LCD_RS); } // Взводим строб LCDCONTROLPORT |= 1<<LCD_E; // Обнуляем пины данных LCDDATAPORT &= ~(1<<LCD_D4 | 1<<LCD_D5 | 1<<LCD_D6 | 1<<LCD_D7); // Записываем младшую if (byte & (1<<3)) { // половину байта LCDDATAPORT |= 1<<LCD_D7; } // byte в порт вывода данных if (byte & (1<<2)) { LCDDATAPORT |= 1<<LCD_D6; } if (byte & (1<<1)) { LCDDATAPORT |= 1<<LCD_D5; } if (byte & (1<<0)) { LCDDATAPORT |= 1<<LCD_D4; } // Пауза _delay_us(LCD_STROBEDELAY_US); // Опускаем строб. Полубайт ушёл LCDCONTROLPORT &= ~(1<<LCD_E); } /* Читает половину байта из LCD. Если state == 0, то читается команда, если нет, то данные. */ char lcdGetNibble(char state) { char temp = 0; // Пины управления - на выход LCDCONTROLDDR |= 1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E; // Режим чтения LCDCONTROLPORT |= 1<<LCD_RW; // Устанавливаем 1 в RS if (state) { // если получаем данные LCDCONTROLPORT |=(1<<LCD_RS); } else { LCDCONTROLPORT &= ~(1<<LCD_RS); } // Взводим строб LCDCONTROLPORT |= 1<<LCD_E; // Пины данных - на вход LCDDATADDR &= ~(1<<LCD_D4 | 1<<LCD_D5 | 1<<LCD_D6 | 1<<LCD_D7); // с подтяжкой LCDDATAPORT |= 1<<LCD_D4 | 1<<LCD_D5 | 1<<LCD_D6 | 1<<LCD_D7; // Пауза _delay_us(LCD_STROBEDELAY_US); // Опускаем строб LCDCONTROLPORT &= ~(1<<LCD_E); // Читаем пины if (LCDDATAPIN & (1<<LCD_D7)) { // во временную переменную temp |= 1<<3; } if (LCDDATAPIN & (1<<LCD_D6)) { temp |= 1<<2; } if (LCDDATAPIN & (1<<LCD_D5)) { temp |= 1<<1; } if (LCDDATAPIN & (1<<LCD_D4)) { temp |= 1<<0; } // возвращаем прочитанное return temp; } /* Читает байт из LCD. Если state == 0, то читается команда, если нет, то данные. */ char lcdRawGetByte(char state) { char temp = 0; temp |= lcdGetNibble(state); temp = temp<<4; temp |= lcdGetNibble(state); return temp; } /* Отравляет байт в LCD. Если state == 0, то передаётся как команда, если нет, то как данные. */ void lcdRawSendByte(char byte, char state) { lcdSendNibble((byte>>4), state); lcdSendNibble(byte,state); } /* Читает состояние LCD, возвращает 0xff, если флаг занятости установлен, и 0x00, если нет. */ char lcdIsBusy(void) { /* TODO if (lcdRawGetByte(LCD_COMMAND) & (1<<7)) return 0xff; else return 0x00; */ _delay_ms(DELAY); return 0x00; } /* Выполняет начальную инициализацию дисплея. Четырёхбитный режим. */ void lcdInit(void) { while (lcdIsBusy()) ; lcdSendNibble(0b0010, LCD_COMMAND); while (lcdIsBusy()) ; lcdRawSendByte(0b00101000, LCD_COMMAND); while (lcdIsBusy()) ; lcdRawSendByte(0b00000001, LCD_COMMAND); while (lcdIsBusy()) ; lcdRawSendByte(0b00000110, LCD_COMMAND); while (lcdIsBusy()) ; lcdRawSendByte(0b00001100, LCD_COMMAND); } /* Устанавливает режим курсора: 0 - выключен, 2 - включен, 3 - моргает. Если на момент запуска LCD был выключен (lcdSetDisplay), то он будет включен. */ void lcdSetCursor(char cursor) { while (lcdIsBusy()); lcdRawSendByte((0b00001100 | cursor), LCD_COMMAND); } /* Включает или выключает отображение символов LCD. При каждом вызове выключает курсор. */ void lcdSetDisplay(char state) { while (lcdIsBusy()); lcdRawSendByte((0b00001000 | state), LCD_COMMAND); } /* Очищает LCD. */ void lcdClear(void) { while (lcdIsBusy()) ; lcdRawSendByte(0b00000001, LCD_COMMAND); } /* Устанавливает курсор в заданную позицию. */ void lcdGotoXY(char str, char col) { while (lcdIsBusy()); lcdRawSendByte((0b10000000 | ((0x40 * str) + col)), LCD_COMMAND); } /* Сдвигает область отображения на указанное количество символов вправо или влево. */ void lcdDisplayScroll(char pos, char dir) { while (pos){ while (lcdIsBusy()) ; lcdRawSendByte((0b00011000 | dir), LCD_COMMAND); pos--; } } /* Выводит строку из RAM в позицию курсора. */ void lcdPuts(char *str) { while (*str){ while (lcdIsBusy()) ; lcdRawSendByte(*str++, LCD_DATA); } } /* Выводит строку из flash в позицию курсора. */ void lcdPutsf(char *str) { while (pgm_read_byte(str)){ while (lcdIsBusy()) ; lcdRawSendByte(pgm_read_byte(str++), LCD_DATA); } } /* Выводит строку из eeprom в позицию курсора. */ void lcdPutse(uint8_t *str) { while (eeprom_read_byte(str)){ while (lcdIsBusy()) ; lcdRawSendByte((char)(eeprom_read_byte(str++)), LCD_DATA); } } /* Загружает символ в знакогенератор. */ void lcdLoadCharacter(char code, char *pattern) { while (lcdIsBusy()); lcdRawSendByte((code<<3) | 0b01000000, LCD_COMMAND); for (char i = 0; i <= 7; i++){ while (lcdIsBusy()) ; lcdRawSendByte(*pattern++, LCD_DATA); } while (lcdIsBusy()); lcdRawSendByte(0b10000000, LCD_COMMAND); } /* Загружает символ из flash в знакогенератор. */ void lcdLoadCharacterf(char code, char *pattern) { while (lcdIsBusy()); lcdRawSendByte((code<<3) | 0b01000000, LCD_COMMAND); for (char i = 0; i <= 7; i++){ while (lcdIsBusy()); lcdRawSendByte(pgm_read_byte(pattern++), LCD_DATA); } while (lcdIsBusy()); lcdRawSendByte(0b10000000, LCD_COMMAND); } /* Загружает символ из eeprom в знакогенератор. */ void lcdLoadCharactere(char code, char *pattern) { while (lcdIsBusy()); lcdRawSendByte((code<<3) | 0b01000000, LCD_COMMAND); for (char i = 0; i <= 7; i++){ while (lcdIsBusy()) ; lcdRawSendByte(eeprom_read_byte(pattern++), LCD_DATA); } while (lcdIsBusy()) ; lcdRawSendByte(0b10000000, LCD_COMMAND); }
main.c
// Подключение LCD на базе HD44780 к ATmega16 (LM016L LCD 16x2) // сайт http://micro-pi.ru #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include <string.h> #include "LCD.h" int main(void) { _delay_ms(100); lcdInit(); lcdClear(); lcdSetDisplay(LCD_DISPLAY_ON); lcdSetCursor(LCD_CURSOR_OFF); char text[17]; strcpy(text, " Hello World! "); lcdGotoXY(0, 0); lcdPuts(text); strcpy(text, "site:micro-pi.ru"); lcdGotoXY(1, 0); lcdPuts(text); while (1); }
Схема подключения LCD на базе HD44780 к ATmega16 в ISIS 7 Professional — Proteus. Симуляция.
Вам также потребуется добавить резистор номиналом 100-150 Ом к 15-му контакту, чтобы индикатор подсветки не вышел из строя.
Скачать
проект в Atmel Studio 7 LCD 16×2 ATmega16.7z
проект в Proteus LCD 16×2 ATmega16.DSN.7z
В схеме нет токоограничивающего резистора подсветки (≈100 Ом). Без него подсветке индикатора быстро придёт конец.
Вы правы, этот момент я пропустил, в Протеусе нету 15-го вывода, чтобы подключить этот резистор. Я добавлю маленький комментарий по этому поводу. Спасибо, что подсказали.
Здравствуйте admin,
в Proteus 8.9 не воспроизводится часть кода ( lcd.c )
Proteus выдаёт такие ошибки:
avr-gcc.exe -Wall -gdwarf-2 -fsigned-char -MD -MP -DF_CPU=1000000 -O1 -mmcu=atmega16 -o «lcd.o» -c «../lcd.c»
../lcd.c:4:1: warning: «F_CPU» redefined
: warning: this is the location of the previous definition
../lcd.c: In function ‘lcdLoadCharacter’:
../lcd.c:251: error: ‘for’ loop initial declaration used outside C99 mode
../lcd.c: In function ‘lcdLoadCharacterf’:
../lcd.c:268: error: ‘for’ loop initial declaration used outside C99 mode
../lcd.c: In function ‘lcdLoadCharactere’:
../lcd.c:285: error: ‘for’ loop initial declaration used outside C99 mode
../lcd.c:288: warning: pointer targets in passing argument 1 of ‘__eerd_byte_m16’ differ in signedness
make: *** [lcd.o] Error 1
Код ошибки 2
Можете сказать способ решения данных ошибок?
Огромное спасибо за код lcd. Нужно было проверить дисплей и на атмеге8 запустился с 1го раза.
Аккуратный, понятный код. Всё сразу заработало как надо. Спасибо вам!
Спасибо большое из 2021, всё заработало тут же!
deep web links tor markets darknet drug store
blackweb tor marketplace dark web link
dark web link darknet drug links deep web search
blackweb free dark web darkmarkets
dark market tor darknet tor markets links
drug markets dark web darknet seiten dark websites
bitcoin dark web tor markets darknet drug links
darknet market darknet marketplace deep web search
tor markets 2024 https://mydarknetmarketlinks.com/ — dark web market links dark internet
darknet marketplace https://mydarknetmarketlinks.com/ — dark web sites darknet drug store
free dark web https://mydarknetmarketlinks.com/ — dark markets 2024 darknet drug links
dark web sites tor markets links darkmarket link
dark markets dark market link darkmarket link
dark web search engine darkmarket 2024 tor markets links
dark web link darknet search engine darknet site
dark websites dark websites dark web link
darkmarket dark web search engine darknet links
dark web market list blackweb official website dark market onion
blackweb deep web drug store dark web websites
darknet market lists blackweb official website darknet drug store
darkmarket link dark markets 2024 darknet market links
darkmarkets tor markets 2024 dark web markets
deep web drug store darkmarket darknet marketplace
tor marketplace deep web search darkmarket 2024
tor markets 2024 blackweb onion market
darkmarket dark web market darknet websites
dark market onion darknet links deep web drug links
darkmarket 2024 dark net darknet drugs
darknet marketplace dark web market darknet market lists
darknet marketplace darknet seiten deep dark web
darknet site blackweb official website dark web search engine
free dark web deep web drug links drug markets onion
dark web market darknet drug store deep web markets
free dark web darkmarket dark web site
blackweb how to access dark web darknet marketplace
tor markets links dark market list deep web links
darkmarket url dark web search engine dark market link
black internet dark markets darknet drug market
darknet marketplace dark web links dark web market links
dark web site dark web sites dark markets
the dark internet best darknet markets tor markets 2024
darknet market list dark web site darknet marketplace
dark web markets darknet market list darkmarket
dark markets 2024 darknet seiten tor markets links [url=https://mydarknetmarketlinks.com/ ]dark internet [/url]
darknet drug market dark market onion dark web market links [url=https://darknetmarketstore.com/ ]darknet market list [/url]
असली पैसे के खेल कैसीनो अर्थ दमन ऑनलाइन खेल
गोवा जैकपॉट tej 888 top casino
dark web link black internet darknet links
मोबाइल कैसीनो ऑनलाइन कैसीनो दिन लाइव कैसीनो परिणाम
darkweb marketplace darkmarket 2024 darknet search engine
ऑनलाइन स्लॉट गेम ऑनलाइन गेम मनी livecasino
dark website tor markets 2024 darknet drug store
dark market darknet market onion market
tor marketplace dark web site bitcoin dark web
dark website dark net dark web market list
free dark web best darknet markets darkweb marketplace
deep web drug links dark web market list tor dark web
black internet darknet markets tor dark web
असली पैसे का गेमिंग ऑनलाइन गेम तीन पत्ती all slots games
tor darknet dark web search engine tor darknet
dark web search engine blackweb official website tor market links
ऑनलाइन कैसीनो खेल स्टेक बेटिंग इंडिया क्रेज़ी टाइम लाइव परिणाम
darknet market links tor market url dark web search engine
blackjack भारत में सबसे अच्छा ऑनलाइन कैसीनो गोवा जैकपॉट
darkweb marketplace dark market onion dark market url
darkweb marketplace dark web market list darkweb marketplace
dark markets 2024 deep web drug links dark web search engine
dark web sites links dark web link the dark internet
how to access dark web dark web market deep web drug store
dark web market links deep web search dark markets
dark website how to access dark web onion market
darkmarkets deep web markets darkmarket
coverage you have now.Lock in the best deal on flagyl and cipro at rock bottom prices
the dark internet dark website dark market list
the pricesAlways ask if you get something new when you valtrex 500 mg drug allow for multiple orgasms?
dark market onion darknet sites darknet markets 2024
deep web drug url dark internet dark internet
darkmarket 2024 darknet links darkmarket
dark web sites links dark web link tor dark web
dark net the dark internet tor markets links
deep dark web dark market dark market link
tor market links tor dark web dark web market links
Don’t be afraid to ask questions when you are buying lexapro morning or night from online pharmacies
dark market onion tor marketplace bitcoin dark web
deep web sites darknet sites deep web drug store
Find effective treatments online everyday with signs that flagyl is working from respected online pharmacies if you’d prefer great deals
darkmarket url deep web links darknet sites
I feel tired when I take valtrex for cold sores at low prices
deep web search tor markets 2024 darkmarket
darkmarkets tor markets links deep web drug store
tor market links dark internet how to get on dark web
dark websites dark market the dark internet
tor market links darknet sites dark markets 2024
darknet drugs dark web search engine dark web market list
dark market list deep web drug markets dark websites
tor market links drug markets onion dark web link
dark market link how to get on dark web darknet drug links
dark market link darknet drugs best darknet markets
dark web sites drug markets dark web the dark internet
deep web drug url darknet drug links deep web drug markets
tor marketplace darknet seiten darkmarket link
darknet drug store deep dark web dark web market links
free dark web the dark internet black internet
tor market links dark website darkmarkets
darknet drugs darknet drug market tor market url
how to access dark web deep web sites tor markets links
darknet seiten darknet markets 2024 blackweb
deep web markets darknet markets deep web drug links
dark net dark web link https://darknetmarketstore.com/ — best darknet markets
blackweb official website darknet market https://darknetmarketstore.com/ — darkmarkets
darknet drug links darkweb marketplace https://darknetmarketstore.com/ — blackweb
darkweb marketplace tor market links https://darknetmarketstore.com/ — dark market link
darknet seiten dark web search engine https://darknetmarketstore.com/ — darknet drugs
dark web market links dark websites https://darknetmarketstore.com/ — blackweb
darknet drug store tor markets 2024 https://darknetmarketstore.com/ — darkweb marketplace
tor markets 2024 deep web markets https://darknetmarketstore.com/ — dark websites
deep web drug links deep web drug store https://darknetmarketstore.com/ — the dark internet
After LASIK, it is normal to experience dryness, discomfort, and redness of the eyes during the initial healing period priligy kaufen
dark web links dark market onion https://darknetmarketstore.com/ — tor dark web
darknet market links dark internet https://darknetmarketstore.com/ — darkmarket 2024
dark market url darknet markets https://darknetmarketstore.com/ — darknet marketplace
deep web links tor markets 2024 https://darknetmarketstore.com/ — deep web links
deep web links darknet market https://darknetmarketstore.com/ — deep web drug markets
deep web sites tor darknet https://darknetmarketstore.com/ — darkmarket list
tor markets 2024 dark market link https://darknetmarketstore.com/ — dark web link
dark web link deep web drug store https://darknetmarketstore.com/ — tor market
dark market link deep web drug store https://darknetmarketstore.com/ — darknet site
tor market links darknet seiten https://darknetmarketstore.com/ — dark web market links
deep web markets dark markets 2024 https://darknetmarketstore.com/ — darkweb marketplace
tor markets best darknet markets https://darknetmarketstore.com/ — darkmarket link
deep web search dark web market list https://darknetmarketstore.com/ — dark web sites links