Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

ПРЕКИНИ, ТАЈМЕРИ И LCD НА

PIC16F887 МИКРОКОНТОРЛЕР
Аудиториски вежби 8
Прекини
Прекини
 Што се случува откако ќе настане прекин?
 Тековната инструкција е се довршува
 Адресата на следната инструкција се става на стек
 Се извршува рутината за справување со прекин
(interrupt service routine) која почнува на адресата
0004 (има само еден вектор на прекин)
 Откако ќе завршу рутината се извршува
инструкцијата RETFIE по што адресата на следната
инструкција која требаше да се изврши кога се случи
прекин се вади од стек и таа следна се извршува
Прекини
 Рутината за справување со прекин во програма во
MikroC e во функцијата именувана interrupt
 Секогаш кога ќе настане прекин се повикува оваа
функција
 Но претходно, прекинот треба да биде овозможен
(enabled)
 Сетирање на одредени битови кај регистрите за специјална
намена
Прекини
INTCON (1):
 За овозможување на прекини
 IE – Interrupt Enable
Прекини
INTCON (2):
 GIE - Global Interrupt Enable bit
 PEIE - Peripheral Interrupt Enable bit
 T0IE - TMR0 Overflow Interrupt Enable bit
 INTE - RB0/INT External Interrupt Enable bit
 RBIE - RB Port Change Interrupt Enable bit.
Прекини
 Ако сакате да се справите со одреден прекин ваша
задача е да ја дефинирате функција interrupt
 Постојат различни извори на прекин
 Најчесто за различен извор на прекин на различен
начин се справуваме со прекинот
 Значајна е идентификацијата на типот на прекин
 Вредности на одредени битови од SFR
Прекини
INTCON (3):

 T0IF – Знаменце за прекин при претекување на тајмерот


0 (TMR0 Overflow Interrupt Flag bit )
 INTF – Знаменце за прекин од пинот RB0 (RB0/INT
External Interrupt Flag bit )
 RBIF – Знаменце за прекин од промена на портата B (RB
Port Change Interrupt Flag bit)
Прекини
Прекини
 Пример:
 Прекин од пинот RB0 настанува при промена на
вредноста на пинот од 0 во 1 (или од 1 во 0)
 На секој прекин од пинот RB0 вредноста на
променливата x заголеми ја за 1

Чекор 1: Овозможување на прекин


INTCON=0b10010000
Прекини
Чекор 2: Имплементација на функција interrupt
short x=0;
void interrupt() {
if (INTCON.B1==1){
x++;
INTCON.B1=0; //ресетирај знаменце
}
}
Со повик на функцијата interrupt всушност се
изведува рутината за прекин која се наоѓа на
локација 0x04. На адреса 0x04 се наоѓа првата
инструкција во interrupt функцијата
Тајмери
 Има 4 тајмери кај PIC16F887
 T0/TMRO
 T1/TMR1
 T2/TMR2
 Watch dog timer
 Проблем
 Проценка на времето
 Имплементација
 Работата на тајмерите е тесно поврзана со работата на
прекните
Тајмери: ТМR0
 Тајмерот има главна цел да процени (измери)
изминатото реално време во секунди (ms,us,ns,...)
 Процената на тоа колку секунди се поминати е преку
бројот на такти (или бројот на извршени инструкции)
 Колкав е бројот на циклуси во 1s?
 Познато е дека ако контролерот работи со фреквенција 8MHz
тогаш тој извршува 8 милиони такти во една секунда
 Еден инструкциски циклус се состои од 4 такти
 Во една секунда се извршуваат 2 милиони инструкциски
циклуси (едноциклусни инструкции)
 Се поставува прашање како да се изброи 2
милиони затоа што тајмерите бројат до 255
 Се бројат прекините од TMR0
Примена на TMR0
 Подесување на прекин од тајмерот 0
 Се сетираат одредени битови кај INTCON регистерот за
да се овозможи тајмерот ТМR0 да предизвикува
прекини кога ќе настане прелевање (overflow) кај TMR0
 T0IE - TMR0 Overflow Interrupt Enable bit
 Контролен бит за прекин преку претекување на TMR0 (тајмер
0)
 Регистрирање на прекин
 T0IF - TMR0 Overflow Interrupt Flag bit
 Регистрира претекување на тајмерот TMR0
Примена на TMR0
 TMR0 се зголемува
 После колку такти ќе се зголеми за 1 зависи од прескалерот и од
осцилаторот
 Пример: ако прескалерот 1:4 значи дека после 4 извршени
инструкциски циклуси тајмерот ќе се зголеми еднаш
 Прескалерот е всушност бројач
 Ако TMR0 надмине 255, ќе настане прекин
Примена на TMR0
 Подесување на прескалер
 Најдолните 3 бита од регистерот OPTION_REG :

RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0


7 6 5 4 3 2 1 0

PS2 PS1 PS0 TMR0


0 0 0 1:2
0 0 1 1:4
0 1 0 1:8
0 1 1 1:16
1 0 0 1:32
1 0 1 1:64
1 1 0 1:128
1 1 1 1:256
Примена на TMR0
 Кога ќе се случи прекин се повикува процедурата
“interrupt”
 Кој точно прекин е настанат може да се провери од соодветните
IF битови (на пример T0IF)
 Откако IF битот е регистриран потребно е тој повторно да се
постави на 0 за да не прикажува прекин по справување со
прекинот
Имплементација на Тајмер TMR0
unsigned cnt;
void interrupt() {
cnt++; // Се зголемува бројачот на прекини 1
TMR0 = 96; // се иницијализира повторно TMR0
INTCON = 0xA0; // T0IE =1, T0IF =0
}

void main() {
OPTION_REG = 0x84; // Се поставуваат опции за TMR0 (прескалер)
ANSEL = 0;
ANSELH = 0;
TMR0 = 96; // Тајмерот брои од 96 до 255
INTCON = 0xA0; // Се сетира INTCON за да се овозможи TMR0
cnt = 0; // Бројот на прекини се иницијлизира на 0

do {
if (cnt == 400) {
cnt = 0; // Се ресетира cnt
}
} while(1);

}
Имплементација на Тајмер TMR0
 Со кодот

do {
if (cnt == 400) {
cnt = 0; // Се ресетира cnt
}
} while(1);

 Се имплементира delay или програмата „ќе почека„


одредено време пред излезе од циклусот.
 Колкаво време?
Примена на TMR0
 Од претходно: Во една секунда на контролер со фрекфенција
8МHz се извршуваат 2 милиони едноциклусни инструкции
 Пресметување на број на едноциклусни
инструкции со TMR0
 cnt – број на прекини (кориснички дефинирана
променлива која ги брои прекините)
 P- Прескалерот на тајмерот е подесен на 1:p
 w- колку пати се зголемува TMR0 пред прекин
 Ако Тајмерот почнува да брои од 96, w=256-96=160
 Бројот на инструкциски циклуси кои се извршиле
во даден момент е: cnt*w*p
 Ако ова е блиску до 2 милиони, проценуваме дека
поминала 1 секунда
Примена на TMR0
 Во примерот :
cnt*w*p = 400 * 160 * 32 = 2 048 000
 Блиску е до 2 000 000, но не е доволно – може и подобро

 Подобрување:
cnt*w*p = 250* 250* 32 = 2 000 000

 Почетна вредност на TMR0 треба да е 256-250= 6


 По cnt=250 прекини изминато е блиску до 1 секунда
Имплементација на Тајмер TMR0
void main() {
OPTION_REG = 0x84;
ANSEL = 0;
ANSELH = 0;
TMR0 = 6; // Тајмерот брои од 6 до 255

unsigned cnt; TRISB=0x00;


void interrupt() { PORTB=0x00;
cnt++; cnt = 0; // Почеток на броење
INTCON = 0xA0;
TMR0 = 6;
do {
INTCON = 0xA0; if (cnt == 250) {
} break;
}
PORTB=PORTB+1;
} while(1);

PORTB=0x00;
}
LCD дисплеј
• Една од дополнителните компоненти (излезен
уред)
• HD44780 microcontroller (Hitachi)
• 2x16 Алфанумерички карактери
• Појавување на курсор
• Позадинска светлина
LCD дисплеј
 Еден знак - 5x8 матрица од пиксели
 Зелена позадинска светлина
 Пиксели каде не се гледа позадинската светлина
формираат знакот
 Потенциометар за подесување на прилагодување на
контрастот
LCD меморија
 DDRAM меморија
 Ако се пратат повеќе од 16 знаци за еден од редовите на
дисплејот повеќето (до 40) ќе се зачуваат, но ќе се
прикажат само првите 16
 Команда за поместување ќе овозможува приказ на
другите меморирани знаци
LCD меморија
 CGROM
 Character
Generator RОM;
 Предефинирана
мапа на знаците
 Адреса=ASCII код
LCD Дисплеј
LCD Дисплеј
• Интерфејтот меѓу контролерот и LCD се поставува при
иницијализација и може да биде со 4 или 8 бита
• 8 бита: ASCII кодовите се праќаат преку податочните линии
DB0- DB7
• 4 бита: Кога интерфејсот е со 4 бита се користат само 4
податочни линии (D4-D7)
• Својства
• Брзината на преносот со 4 битови е помала, но тоа не
незначително
• Кога се користат 4 битови се штеди на пинови од
микроконторлерот кои може да се користат за други
цели
• Најчесто се користат 4 битови
LCD дисплеј
 Пинови на LCD
 8 (4) пинови може да се користат за пренос на
податоци/команди
 Адреса на DDRAM - каде?
 Адреса на CGROM – што?
 3 пинови за контрола на работата
 RS –1 се примаат податоци, 0 се примаат команди (Register
Select )
 R/W- Read/Write
 E - 0 – оневозможена работа на LCD, 1 работа на LCD
 Заземјување
 Напојување
 Контраст
Конекција на LCD- дефинирање на
променливи
Променлива: Опис: Пример:
extern sfr sbit LCD_RS: Register Select line. sbit LCD_RS at RB4_bit;
extern sfr sbit LCD_EN: Enable line. sbit LCD_EN at RB5_bit;
extern sfr sbit LCD_D7; Data 7 line. sbit LCD_D7 at RB3_bit;
extern sfr sbit LCD_D6; Data 6 line. sbit LCD_D6 at RB2_bit;
extern sfr sbit LCD_D5; Data 5 line. sbit LCD_D5 at RB1_bit;
extern sfr sbit LCD_D4; Data 4 line. sbit LCD_D4 at RB0_bit;
sbit LCD_RS_Direction at
extern sfr sbit LCD_RS_Direction; Register Select direction pin.
TRISB4_bit;
sbit LCD_EN_Direction at
extern sfr sbit LCD_EN_Direction; Enable direction pin.
TRISB5_bit;
sbit LCD_D7_Direction at
extern sfr sbit LCD_D7_Direction; Data 7 direction pin.
TRISB3_bit;
sbit LCD_D6_Direction at
extern sfr sbit LCD_D6_Direction; Data 6 direction pin.
TRISB2_bit;
sbit LCD_D5_Direction at
extern sfr sbit LCD_D5_Direction; Data 5 direction pin.
TRISB1_bit;
sbit LCD_D4_Direction at
extern sfr sbit LCD_D4_Direction; Data 4 direction pin.
TRISB0_bit;
Пример

// Поставување на конекција со LCD


sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Крај
Контрола
• Едноставна контрола преку соодветна библиотека
во mikroC
• Подесувања
• Функции за печатење на букви или стрингови на
дисплејот
• Други опции
Методи за пристап
• void Lcd_Init();
– иницијализација на LCD дисплејот според претходно
наведените променливи
– Потребно е 15ms за иницијализација
• void Lcd_Out(char row, char column, char
*text);
– Печати текст почнувајќи од соодветна
позиција (ред и колона)
– Пр. Lcd_Out(1, 1, “Prva redica”);
Методи за пристап
• void Lcd_Out_Cp(char *text);
– Печати текст од моменталната позиција на
курсорот
– Пр. Lcd_Out_Cp(“Ovde!");
• void Lcd_Chr(char row, char column, char
out_char);
– Печати карактер на наведената
позиција
– Пр. Lcd_Chr(2, 3, 'i');
Методи за пристап
• void Lcd_Chr_Cp(char out_char);
– Печати карактер од моменталната позиција
на курсорот
– Пр. Lcd_Chr_Cp('e');
• void Lcd_Cmd(char out_char);
– Изврши специјална наредба на LCD
– Пр. Lcd_Cmd(_LCD_CLEAR);
Специјални наредби
Наредба Намена
_LCD_FIRST_ROW Помести го курсорот на првиот ред
_LCD_SECOND_ROW Помести го курсорот на вториот ред
_LCD_THIRD_ROW Помести го курсорот на третиот ред
_LCD_FOURTH_ROW Помести го курсорот на четвртиот ред
_LCD_CLEAR Исчисти го дисплејот
_LCD_RETURN_HOME Врати го курсорот на почетната позиција, со што се
добива ротиран дисплеј според почетната позиција.
_LCD_CURSOR_OFF Исклучи го курсорот
_LCD_UNDERLINE_ON Вклучи го курсорот (долна црта)
_LCD_BLINK_CURSOR_ON Вклучи трепкање на курсорот
_LCD_MOVE_CURSOR_LEFT Помести го курсорот на лево без промена на
прикажаните податоци
_LCD_MOVE_CURSOR_RIGHT Помести го курсорот на десно без промена на
прикажаните податоци
_LCD_TURN_ON Вклучи го дисплејот
_LCD_TURN_OFF Исклучи го дисплејот
_LCD_SHIFT_LEFT Помести го прозорецот за дисплејот на лево без
промена на податоците во меморија
_LCD_SHIFT_RIGHT Помести го прозорецот за дисплејот на ресно без
промена на податоците во меморија
Пример
 Задача: Отпечати текст во двете линии
// Start LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
const int len = 16;
char ch;
int i;
char *text, *text2;
void main() {
ANSEL = 0;
ANSELH = 0;
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Cmd(_LCD_CLEAR);
text = "Demo text ";
Lcd_Out(1,1,text);
text2 = "Second line";
Lcd_Out(2,1,text2);
Delay_1sec();
}
Други излезни визуелни излезни уреди
 GLCD
 Graphic LCD
 Резолуција 128x64
 COGD
 Chip on glass Display
 2x16 serial LCD
 Нема светлина

You might also like