Мікроконтролерна система з рідкокристалічним індикатором для управління комп’ютером

курсовая работа

1.6 Драйвери для мікроконтролера та лістинг програми роботи РКІ

Для забезпечення роботи РКІ панелі потрібно встановити необхідні драйвери та бібліотеки для програмованих компонентів схеми.

· lcd.c, lcd.h, lcd_hw.h: Це загальна бібліотека AVR LCD. Вона базується на роботі Peter Fleury (http://jump.to/fleury). Ця версія злегка модифікована і є більше гнучкою. Вона дозволяє приєднати РК-дисплей до будь-якого контакту мікроконтролера, необхідно лише перемінити значення у файлі lcd_hw.h.

· avr-util.c, avr-util.h: функції для одержання різних затримок за часом.

· uart.c, uart.h: Це бібліотека для інтерфейсу RS232. Вона використає апаратні переривання. Як тільки від компютера приходить символ, виконується функція SIGNAL(SIG_UART_RECV), і дані копіюються із прийомного буфера в буфер рядків. Командна мова для нашої РК-панели побудований так, що кожна команда закінчується символом нового рядка. Коли буде знайдений символ нового рядка, установлюється прапор (uart_rx_linecomplete), а дані стають доступними. Це також означає, що потрібно посилати команди дисплею як найшвидше, а чекати якийсь час (мілісекунду) після кожного рядка. Кожна команда підтверджується результатом, ok, або err (при помилці). Керуюча програма perl може використати результат як селектор для посилання наступної команди.

· analog.c, analog.h: Код аналого-цифрового перетворювача. Він також управляється перериваннями. Коли запускається окреме перетворення аналог-код, програма чекає переривання SIG_ADC, щоб уважати результат з регістра ADC.

· hardwarewd.c, hardwarewd.h: Це сторожовий таймер. Використовується внутрішній дільник (ділимо на 1024), щоб управляти таймером. Таймер - це 16-бітний регістр, від якого ми віднімаємо 8-бітну змінну до переповнення. Для кварцу 4MHz ми будемо відраховувати нашу змінну близько 16 секунд. Програма на perl визначає, що компютер працює, періодично встановлюючи змінну назад у максимальне значення. Якщо вона не може цього зробити (наприклад, компютер завис), то змінна постійно зменшує своє значення, а коли вона досягне 0, реле перемкнеться й викличе апаратне перезавантаження нашого сервера.

· linuxlcdpanel.c: Це основна програма. Вона безупинно перевіряє наявність команд від інтерфейсу RS232 і натискання кнопок.

Тепер перейдемо до написання програми. Для контроля індикатора напишемо програму із декількома ключовими функціями роботи з РКІ: lcd_dat(unsigned char x) - для запису даних х, lcd_com(unsigned char x) - для запису команди х, lcd_init(void) - для початкової ініціалізації індикатора:

#include <avr/io.h> //бібліотека вводу/виводу

#define RS 2 //RS=PD2 - сигнал управління РКІ

#define E 3 //E=PD3 - сигнал управління РКІ

#define TIME 10 //Константа часової затримки для РКІ

//Частота тактування МК - 4Мгц

//Програма формування затримки

void pause (unsigned int a)

{ unsigned int i;

for (i=a;i>0;i--);

}

//Програма передачі команд в РКІ

void lcd_com (unsigned char lcd)

{ unsigned char temp;

temp=(lcd&~(1<<RS))|(1<<E);//RS=0 - це команда

PORTD=temp; //Виводимо на portD старшу тетраду команди, сигнали

RS, E

asm("nop"); //Невелика затримка в 1 такт МК, для стабілізації

PORTD=temp&~(1<<E); //Сигнал запису команди

temp=((lcd*16)&~(1<<RS))|(1<<E);//RS=0 - это команда

PORTD=temp; //Виводимо на portD молодшу тетраду команды, сигналы

RS, E

asm("nop"); //Найбільша затримка в 1 такт МК, для стабілізації

PORTD=temp&~(1<<E); //Сигнал запису команди

pause (10*TIME); //Пауза для виконання команди

}

//Програма запису даних в РКІ

void lcd_dat (unsigned char lcd)

{ unsigned char temp;

temp=(lcd|(1<<RS))|(1<<E);//RS=1 - це данні

PORTD=temp; //Виводимо на portD старшу тетраду asm("nop");

//Невелика затримка в 1 такт МК, для стабілізації

PORTD=temp&~(1<<E); //Сигнал запису даних

temp=((lcd*16)|(1<<RS))|(1<<E);//RS=1 - це данні

PORTD=temp; //Виводимо на portD молодшу тетраду даних, сигнали

RS, E

asm("nop"); //Невелика затримка в 1 такт МК, для стабілізації

PORTD=temp&~(1<<E); //Сигнал запису даних

pause(TIME); //Пауза для вивода даних

}

//Программа ініціалізації РКІ

void lcd_init (void)

{

lcd_com(0x2c);//4-провідний інтерфейс, 5x8 розмір символа

pause(100*TIME);

lcd_com(0x0c);//Показати зображення, курсор не показувати

pause(100*TIME);

lcd_com(0x01);//Очистити DDRAM и установити курсор на 0x00

pause (100*TIME);

}

//Основна програма

int main(void)

{

DDRD=0xfc;//Ініціалізація portD

PORTD=0x00;

pause(1000);//Затримка, щоб РКІ встиг включитися

lcd_init();//Ініціалізація РКІ

lcd_dat(w); //Вивід

lcd_dat(w);

lcd_dat(w);

lcd_dat(.);

lcd_dat(a);

lcd_dat(v);

lcd_dat(r);

lcd_dat(l);

lcd_dat(a);

lcd_dat(b);

lcd_dat(.);

lcd_dat(c);

lcd_dat(o);

lcd_dat(m);

lcd_com(0xc0);//Ставимо курсор на початок 2-го рядка РКІ

lcd_dat(I);//Записуємо

lcd_dat(t);

lcd_dat(");

lcd_dat(s);

lcd_dat( );

lcd_dat(s);

lcd_dat(o);

lcd_dat( );

lcd_dat(e);

lcd_dat(a);

lcd_dat(s);

lcd_dat(y);

while(1)//безкінечний цикл

;

return 1;

}

Для латині і цифр ASCII коди співпадають з зашитими в знакогенератор РКІ, відтак дозволено використовувати lcd_dat(`A). Можно зробити свою бібліотеку для роботи з РКІ, виділивши функції lcd_dat(unsigned char x), lcd_com(unsigned char x), lcd_init(void) в окремий модуль LCD.h и підключати його за необхідністю.

· Ця процедура дуже економить час, варто тільки один раз написати потрібні функції, а потім весь час їх тільки використовувати. Також варто підмітити, что незручно виводити довгу фразу по одній літері, для цього необхідно нашу строку виведення помістити в массив із unsigned char і виводити за допомогою цикла:

· int main(void)

· { unsigned char data [14]= {w,w,w,.,a,v,r,l,a,b,.,c,o,m};

· unsigned char i;

· DDRD=0xfc;//Ініціалізація portD

· PORTD=0x00;

· pause(1000); //Затримка, щоб РКІ встиг включитися

· lcd_init();//Ініціалізація РКІ

· for (i=0;i<14;i++)//Вивід запису політерно

· lcd_dat(data[i]);

Делись добром ;)