Вивід інформації на LCD-дисплей

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2012
Тип роботи:
Звіт про виконання лабораторної роботи
Предмет:
Програмування

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки, молоді та спорту України Національний університет «Львівська політехніка» ЗВІТ про виконання лабораторної роботи №4 з курсу «Програмування мікроконтролерів СА» Тема: «Вивід інформації на LCD-дисплей» Варіант № 1 Мета роботи: Зібрати у пакеті симуляції Proteus схему на основі МК ATmega32A та написати програму мовою Ci для реалізації вказазаного алгоритму (таблиця 2). Завдання: Таблиця 1. Завдання Непарні номери варіантів реалізують 8-ми розрядний інтерфейс LCD для обміну даними, Парні номери варіантів – 4-ри розрядний. У завданні вказується таймер за допомогою якого потрібно реалізувати відлік інтервалів часу для зазначеного пристрою. При використанні таймера 2 в асинхронному режимі передбачається, що він тактується від годинникового кварца 32768 Гц. Тривалість звукових сигналів вибирається студентом самостійно, дотримуючись вказаних меж. Натиск кожної кнопки супроводжується коротким одинарним сигналом, успішне підтвердження введення даних за допомогою клавіші # супроводжується коротким подвійним сигналом, введення невірних даних за допомогою клавіші # та відміна усієї операції за допомогою клавіші * супроводжується довгим сигналом.  № п/п Таймер відліку часу Частота тактування, МГц Клаві-атура Сиг-нал Порт даних LCD. Виводи керування Алго-ритм  1 T0 7.3728 PORTС PD7 PORTA PB(1-3) 1   Таблиця 2. Варіанти пристроїв № п/п Опис алгоритму роботи пристрою  1 Годинник. Відображає години, хвилини, секунди. Запускається одразу ж при подачі живлення на МК. При співпадінні значень будильника та годинника запускається звуковий сигнал (короткими гудками) тривалістю 0,5-2 хв. Кнопка A – переводить у режим виставлення годин та хвилин годинника. Кнопка B – переводить у режим виставлення годин та хвилин будильника. * Значення годин та хвилин вводиться за допомогою клавіш 0-9. Підтвердження введення за допомогою #, при цьому здійснюється перевірка коректності значень годин та хвилин (від 0 до 59). Кнопка C – відображає значення поточного будильника. Кнопка D – активізує/відключає будильник (літера А) після натиснення кнопки С. Кнопка * – відміна операції, перехід у режим ходу годинника.   / Рис.1. Схема підключення в пакеті Proteus Остаточна версія програми: LCDinit.h (файл ініціалізації дисплей в 8-біт режимі): #include <avr/io.h> #include <avr/pgmspace.h> #include <util/delay.h> #define RS PB0 #define RW PB1 #define E PB2 void LCDinit (void) { _delay_ms(40); //Ініцалізація портів(на вихід) на дисплей DDRA = 0xFF; //Data PORTA = 0x00; DDRB = 0xFF; //Control PORTB = 0x00; //Функція установки: шина 8 біт, 2 стрічки, 5х8 точок PORTB &= ~((1 << RW)|(1 << RS)); PORTA = 0x38; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); _delay_us(50); PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); _delay_us(50); //Функція установки: включити дисплей (курсор) PORTB &= ~((1 << RW)|(1 << RS)); PORTA = 0x0C; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); _delay_us(50); //Функція установки: зсуви екрану та курсору PORTB &= ~((1 << RW)|(1 << RS)); PORTA = 0x04; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); _delay_us(50); //Функція установки: очистити дисплей PORTB &= ~((1 << RW)|(1 << RS)); PORTA = 0x01; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); } //Опитування прапорця зайнятості BF (busy flag) void BF (void) { DDRA = 0x00; //Data PORTA = 0xFF; PORTB &= ~(1 << RS); PORTB |=(1 << RW); do { PORTB &= ~(1 << E); PORTB |= (1 << E); _delay_us(0.15); } while(PINA & (1 << 7)); PORTB &= ~(1 << E); } //Запис команди в LCD void LCD_WriteCommand(unsigned char Command) { BF(); //Опитування прапорця БФ PORTB &= ~((1 << RW)|(1 << RS)); //Порт data налаштовуємо на вихід DDRA = 0xFF; //Data PORTA = 0x00; // Bиводимо команду в порт даних PORTA = Command; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); } //Вивід символу на LCD void LCD_WriteLetter(unsigned char Letter) { BF(); //Опитування прапорця БФ PORTB |= (1 << RS); PORTB &= ~(1 << RW); //Порт data налаштовуємо на вихід DDRA = 0xFF; //Data PORTA = 0x00; // Bиводимо символ в порт даних PORTA = Letter; PORTB |= (1 << E); _delay_us(0.15); PORTB &= ~(1 << E); } // Функція виводу стрічки на екран LCD void LCD_WriteStr(volatile char *str) { for(int i=0;i<255;i++) if (str[i]=='\0') return; else LCD_WriteLetter(str[i]); } // Функція виводу стрічки, записаної у Flash, на екран LCD. void LCD_WriteStrPROGMEM(unsigned char *str, unsigned char n) { for(int i=0;i<255;i++) if (pgm_read_byte(& (str[i]) )=='\0') return; else LCD_WriteLetter(pgm_read_byte( &(str[i]) )); } // Перехід курсору на нову позицію на екрані LCD. void LCD_GotoYX(unsigned char Y, unsigned char X) { if(Y==1) LCD_WriteCommand(((1<<7)|(X-1))); else LCD_WriteCommand(((1<<7)|(0x40+X-1))); } LCD.c (основний файл): #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include "LCDinit.h" #define RS PB0 #define RW PB1 #define E PB2 #define Key_1 0b11101110 #define Key_2 0b11011110 #define Key_3 0b10111110 #define Key_A 0b01111110 #define Key_4 0b11101101 #define Key_5 0b11011101 #define Key_6 0b10111101 #define Key_B 0b01111101 #define Key_7 0b11101011 #define Key_8 0b11011011 #define Key_9 0b10111011 #define Key_C 0b01111011 #define Key_F 0b11100111 #define Key_0 0b11010111 #define Key_E 0b10110111 #define Key_D 0b01110111 PROGMEM unsigned char sixty[60][3] ={ {"00"},{"01"},{"02"},{"03"},{"04"},{"05"},{"06"},{"07"},{"08"},{"09"}, {"10"},{"11"},{"12"},{"13"},{"14"},{"15"},{"16"},{"17"},{"18"},{"19"}, {"20"},{"21"},{"22"},{"23"},{"24"},{"25"},{"26"},{"27"},{"28"},{"29"}, {"30"},{"31"},{"32"},{"33"},{"34"},{"35"},{"36"},{"37"},{"38"},{"39"}, {"40"},{"41"},{"42"},{"43"},{"44"},{"45"},{"46"},{"47"},{"48"},{"49"}, {"50"},{"51"},{"52"},{"53"},{"54"},{"55"},{"56"},{"57"},{"58"},{"59"} }; unsigned char counter = 0; volatile unsigned char symbol_pos = 0; volatile char symbol = -1, type = 0, pinc = 0, E_press = 0, alarm_info = 0, alarm_status = 0, buzzer = 0, buzflag = 0; volatile unsigned char display = 0; typedef struct { unsigned char second, minute, hour; } Time; Time T1 = {10,10,10}; Time T2 = {0,0,0}; Time TA = {0,0,0}; ISR(TIMER0_COMP_vect) { // Таймер Т0 по співпадінню, кожні 10 мсек. counter++; buzzer=(buzzer+1)%10; if (counter == 100) { if(++T2.second == 60) { T2.second = 0; if(++T2.minute == 60) { T2.minute = 0; if(++T2.hour == 24) T2.hour = 0; } } counter = 0; } if(display==0) { LCD_GotoYX(2,5); LCD_WriteStrPROGMEM(sixty[T2.hour],2); LCD_WriteLetter(':'); LCD_WriteStrPROGMEM(sixty[T2.minute],2); LCD_WriteLetter(':'); LCD_WriteStrPROGMEM(sixty[T2.second],2); if (alarm_status == 1) { LCD_GotoYX(2,16); LCD_WriteLetter('A'); if (TA.hour == T2.hour && TA.minute == T2.minute) { if ((buzzer == 0) && (buzflag == 0) && (T2.second < 59)) { PORTD = 0xFF; buzflag = 1; } else if ((buzzer == 0) && (buzflag == 1)) { buzflag = 0; PORTD = 0x00; } } } else { LCD_GotoYX(2,16); LCD_WriteLetter(' '); } } } void main() { initialization(); sei(); unsigned char freePIN=1, key=1; while (1) // основний робочий цикл { if(freePIN == 1) // перевірка чи була натиснута кнопка { // якщо =1, тоді ще не натисалася if(PINC != 0xF0) { PORTD |= 1<<7; // включаємо бузер _delay_ms(100); freePIN = 0; // Визначення натиснутої клавіші // почергова подача 0V на рядки клавіатури A,B,C,D PORTC = 0b11111110; // A-рядок if(PORTC == PINC) { PORTC = 0b11111101; // B-рядок if(PORTC == PINC) { PORTC = 0b11111011; // C-рядок if(PORTC == PINC) { PORTC = 0b11110111; // D-рядок if(PORTC == PINC) key=0; // жодна клавіша не натиснута } } } if(key==1) // визначення натиснутої клавіші { LCD_WriteCommand(0X01); // очистити LCD display = 1; // вимкнення відображення годинника if(PINC == Key_1) { symbol = 1; setup('1'); } if(PINC == Key_2) { symbol = 2; setup('2'); } if(PINC == Key_3) { symbol = 3; setup('3'); } if(PINC == Key_4) { symbol = 4; setup('4'); } if(PINC == Key_5) { symbol = 5; setup('5'); } if(PINC == Key_6) { symbol = 6; setup('6'); } if(PINC == Key_7) { symbol = 7; setup('7'); } if(PINC == Key_8) { symbol = 8; setup('8'); } if(PINC == Key_9) { symbol = 9; setup('9'); } if(PINC == Key_0) { symbol = 0; setup('0'); } if(PINC == Key_A) { type = 1; symbol = -1; symbol_pos = 0; setup('A'); } if(PINC == Key_B) { type = 2; symbol_pos = 0; symbol = -1; setup('B'); } if(PINC == Key_C) { if (pinc == 1) { pinc = 0; LCD_WriteCommand(0X01); display = 0; E_press = 0; type = 0; symbol_pos = 0; T1.hour = 10; T1.minute = 10; } else { pinc = 1; } symbol = -1; setup('C'); } if(PINC == Key_D) { symbol = -1; symbol_pos = 0; if (pinc == 1) alarm_info = 1; setup('D'); } if(PINC == Key_E) { if (type != 0) E_press = 1; symbol = -1; symbol_pos = 0; setup('E'); } if(PINC == Key_F) { display = 0; // вкл. відобр. годинника E_press = 0; type = 0; pinc =0; symbol_pos = 0; T1.hour = 10; T1.minute = 10; LCD_WriteCommand(0X01); } } key=1; _delay_ms(300); PORTC = 0xF0; // відновлюємо порт PORTD &= ~(1<<7); // виключаємо бузер } } else if(PINC == 0xF0) // перевіряємо чи кнопка відпущена { _delay_ms(100); freePIN=1; } } } void setup (unsigned char value) { //Якшо натиснута кнопка Е if (E_press == 1) { if (type == 1) { if (T1.hour < 24 && T1.minute < 60) { T2.hour = T1.hour; T2.minute = T1.minute; symbol_pos = 0; type = 0; T1.hour = 10; T1.minute = 10; LCD_WriteCommand(0X01); E_press = 0; display = 0; PORTD |= 1<<7; _delay_ms(100); PORTD &= ~(1<<7); _delay_ms(100); PORTD |= 1<<7; _delay_ms(100); PORTD &= ~(1<<7); } else { LCD_GotoYX(1,2); LCD_WriteStr("Incorrect time"); _delay_ms(1000); LCD_WriteCommand(0X01); E_press = 0; symbol_pos = 0; T1.hour = 10; T1.minute = 10; } } if (type == 2) { if (T1.hour < 24 && T1.minute < 60) { TA.hour = T1.hour; TA.minute = T1.minute; symbol_pos = 0; type = 0; T1.hour = 10; T1.minute = 10; LCD_WriteCommand(0X01); E_press = 0; display = 0; PORTD |= 1<<7; _delay_ms(100); PORTD &= ~(1<<7); _delay_ms(100); PORTD |= 1<<7; _delay_ms(100); PORTD &= ~(1<<7); } else { LCD_GotoYX(1,2); LCD_WriteStr("Incorrect time"); _delay_ms(1000); LCD_WriteCommand(0X01); E_press = 0; symbol_pos = 0; T1.hour = 10; T1.minute = 10; } } } //Якшо натиснута кнопка С if (pinc == 1) { LCD_GotoYX(1,4); LCD_WriteStr("Alarm Time"); LCD_GotoYX(2,7); LCD_WriteStrPROGMEM(sixty[TA.hour],2); LCD_WriteLetter(':'); LCD_WriteStrPROGMEM(sixty[TA.minute],2); if (alarm_info == 1 && alarm_status == 0) { alarm_status = 1; alarm_info = 0; } else if (alarm_info == 1 && alarm_status == 1) { alarm_status = 0; alarm_info = 0; } if (alarm_status == 1) { LCD_GotoYX(2,16); LCD_WriteLetter('A'); } if (alarm_status == 0) { LCD_GotoYX(2,16); LCD_WriteLetter(' '); } return; } //Якшо уст. годинника і натиснута кнопка цифрова if (type == 1 && symbol != -1) { if (symbol_pos == 5) { symbol_pos = 0; T1.hour = 10; T1.minute = 10; } if (symbol_pos == 1) { T1.hour *= symbol; LCD_GotoYX(2,7); LCD_WriteLetter(value); } if (symbol_pos == 2) { T1.hour += symbol; LCD_GotoYX(2,8); LCD_WriteLetter(value); } if (symbol_pos == 3) { T1.minute *= symbol; LCD_GotoYX(2,10); LCD_WriteLetter(value); } if (symbol_pos == 4) { T1.minute += symbol; LCD_GotoYX(2,11); LCD_WriteLetter(value); } LCD_GotoYX(1,4); LCD_WriteStr("Clock Setup"); LCD_GotoYX(2,9); //LCD_WriteStrPROGMEM(sixty[T1.hour],2); LCD_WriteLetter(':'); //LCD_WriteStrPROGMEM(sixty[T1.minute],2); symbol_pos++; return; } //Якшо уст. будильника і натиснута кнопка цифрова if (type == 2 && symbol != -1) { if (symbol_pos == 5) { symbol_pos = 0; T1.hour = 10; T1.minute = 10; } if (symbol_pos == 1) { T1.hour *= symbol; LCD_GotoYX(2,7); LCD_WriteLetter(value); } if (symbol_pos == 2) { T1.hour += symbol; LCD_GotoYX(2,8); LCD_WriteLetter(value); } if (symbol_pos == 3) { T1.minute *= symbol; LCD_GotoYX(2,10); LCD_WriteLetter(value); } if (symbol_pos == 4) { T1.minute += symbol; LCD_GotoYX(2,11); LCD_WriteLetter(value); } LCD_GotoYX(1,4); LCD_WriteStr("Alarm Setup"); LCD_GotoYX(2,9); //LCD_WriteStrPROGMEM(sixty[TA.hour],2); LCD_WriteLetter(':'); //LCD_WriteStrPROGMEM(sixty[TA.minute],2); symbol_pos++; return; } display = 0; } // Ініціалізація заліза void initialization (void) { // Ініціалізація портів з підт. резистр. // Порт A на вхід DDRA = 0x00; PORTA = 0xFF; // Порт B на вихід DDRB = 0xFF; PORTB = 0x00; // Порт С клавіатура: рядки на вихід, стовпці на вхід DDRC = 0x0F; PORTC = 0xF0; // Порт D на вихід DDRD = 0xFF; PORTD = 0x00; LCDinit(); //Ініціалізація ЛСД // Ініціалізація таймера TIMSK|=(1<<OCIE0); // Дозволити переривання по співпаданню. OCR0=0x48; // Частота 7,3728 МГц, 10ms - 72 такта. TCCR0|=(1<<WGM01)|(1<<CS00)|(1<<CS02); // Ділити частоту на 1024. } / Рис.2. Результати роботи програми Висновок: На даній лабораторній роботі ми освоїли принципи ініціалізації LCD дисплею RC1602A-GGN-CSX (Raystar) (сумісний з HD44780), навчилися працювати з клавіатурою 4×4. Результатом лабораторної роботи стала програма мовою Сі для реалізації годинника з виводом даних на LCD дисплей.
Антиботан аватар за замовчуванням

25.02.2013 16:02-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!