7 Segment Display ve Kesmeler (Interrupts) Hafta6-7 · 2018. 10. 23. · Çevrim Tabloları Ve 7...
Transcript of 7 Segment Display ve Kesmeler (Interrupts) Hafta6-7 · 2018. 10. 23. · Çevrim Tabloları Ve 7...
7 Segment Display ve Kesmeler (Interrupts)
Hafta6-7
Dr. Bülent Çobanoğlu-SAÜ 1
Çevrim Tabloları Ve 7 Segment Display Uygulaması
Çevrim / Bakış tabloları ile bir kodu başka bir koda dönüştürmek için
kullanılırlar. Örneğin PIC mikro denetleyiciyi portlarına bağlı 7 Segment
display / gösterge üzerinde hexadecimal (onaltılık tabandaki) sayıları
göstermek, sıcaklık dönüşümü(derece-fahrenayt gibi) yapma, sinus, kosinus
alma gibi işlemlerde dönüşüm/çevrim tabloları kullanılır.
7 Segment display 7 adet çubuk ledin bir rakam oluşturacak şekilde bir araya
gelmesi ile oluşan bir elemandır. 7 segment displayler ortak anot ve ortak
katotlu olmak üzere iki farklı şekilde bulunurlar.
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Çevrim Tabloları Ve 7 Segment Display Uygulaması
7 segment displaylerin içerisinde aslında 8 adet led bulunmaktadır. Her bir segment bu
ledler ile oluşturulmuştur ve göstergenin hangi segmentinin yanmasını istiyor isek o
ledi yakarız.
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
. G F E D C B A
0 b‘ 0 0 1 1 1 1 1 1'
1 b‘ 0 0 0 0 0 1 1 0’
2 b‘ 0 1 0 1 1 0 1 1'
3 b‘ 0 1 0 0 1 1 1 1'
4 b‘ 0 1 1 0 0 1 1 0’
5 b‘ 0 1 1 0 1 1 0 1’
6 b‘ 0 1 1 1 1 1 0 1’
7 b‘ 0 0 0 0 0 1 1 1’
8 b‘ 0 1 1 1 1 1 1 1’
9 b‘ 0 1 1 0 1 1 1 1’
A b‘ 0 1 1 1 0 1 1 1’
b b‘ 0 1 1 1 1 1 0 0’
C b‘ 0 0 1 1 1 0 0 1’
d b‘ 0 1 0 1 1 1 1 0’
E b‘ 0 1 1 1 1 0 0 1’
F b‘ 0 1 1 1 0 0 0 1’
Ortak anotlu display: tüm ledlerin anotları
birleştirilmiştir ve bu uca +5V uygulanır. Katota şase
gelen led yanar. Yanmasını istediğimiz lede +0V (logic 0)
verilir.
Ortak katotlu display: tüm ledlerin katotları
birleştirilmiştir ve bu uç şaseye bağlanır. Yanmasını
istediğimiz lede +5V (logic 1) verilir.
Assembly dilinde çevrim tablosunda uygun kodu seçmek için programsayıcıyı (PCL‐ Program Counter), seçilen kodu ana programa göndermekiçin de RETLW komutunu kullanırız
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Çevrim tablosundaki verilere sıralı olarak erişerek PCL’ye yani o anki adrese
istediğimiz sayıyı ekleyerek istediğimiz adrese / elemana ulaşırız. PCL’nin o anki
değerine ADDWF ile istediğimiz sayıyı ekleriz.
Kullanım Şekli: ADDWF PCL, F
İstediğimiz değeri geri döndürecek komut ise RETLW (RETLW h’3F’ gibi) dir.
RETLW komutu ile alt alta yazılan sayı değerleri dt komutu yanyana yazılabilir.
DIZI
ADDWF PCL, F
dt 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,0x7D, 0x07, 0x7F,...
Birden fazla display bağlantısı
Uygulama-1: 0 dan 9 kadar olan sayıları PORTB uçlarına bağlı 7 segment display’de
gösteren programı 7447 entegresi ile (bakış tablosu kullanmadan) gerçekleştiriniz.
Hazırlayan: Dr.Bülent ÇOBANOĞLU 5
Uygulama 2: 7 segment display de 6 sayısını gösteren programı yazınız.
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
;Assembly
LIST P=16F877
#INCLUDE "P16F877.INC"
ORG 0X00
goto BASLA
BASLA
CLRF PORTB
BANKSEL TRISB
CLRF TRISB
BANKSEL PORTB
MOVLW .6
CALL DIZI
MOVWF PORTB
DON
GOTO DON
DIZI
ADDWF PCL,F
RETLW b'00111111' ;W ya 0 değeri yüklendi
RETLW b'00000110‘ ;W ya 1 değeri yüklendi
RETLW b'01011011‘ ;W ya 2 değeri yüklendi
RETLW b'01001111' ;W ya 3 değeri yüklendi
RETLW b'01100110‘ ;W ya 4 değeri yüklendi
RETLW b'01101101‘ ;W ya 5 değeri yüklendi
RETLW b'01111101' ;W ya 6 değeri yüklendi
RETLW b'00000111‘ ;W ya 7 değeri yüklendi
RETLW b'01111111' ;W ya 8 değeri yüklendi
RETLW b'01101111' ;W ya 9 değeri yüklendi
END
// C programı#include <xc.h> const unsigned char dizi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D}; void main(void) // Ana fonksiyon alanı { TRISB=0x00; // PORTB çıkıs PORTB=0x00;for(;;) // Sonsuz döngüye giriliyor { PORTB=dizi[6]; //7 segment değerini al } }
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
// 0 dan F e ileri sayıcı
#include <xc.h>
#define _XTAL_FREQ 4000000
const unsigned char
dizi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,
0x6F,0x77,0x7C, 0x39, 0x5E, 0x79, 0x71};
unsigned char i;
void main(void) // Ana fonksiyon alanı
{
TRISB=0x00; // PORTB çıkıs
PORTB=0x00;
for(i=0;i<=16;i++) // Sonsuz döngüye giriliyor
{
__delay_ms(1000);
PORTB=dizi[i]; //7 segment değerini al
}
}
Uygulama 3: 0 dan F ye kadar olan sayıları PORB uçlarına bağlı 7 segment display’de 1
sn aralıklarla gösteren programı C dili ile gerçekleştiriniz.
Uygulama 3: 0 dan F ye kadar olan sayıları 1sn gecikmeli PORB uçlarına bağlı 7 segment
display’de gösteren programı ASSEMBLY dili ile gerçekleştiriniz.
LIST P=16F877
#INCLUDE "P16F877.INC"
CBLOCK 0X20
SAY1,SAY2,SAY3,SAYAC
ENDC
ORG 0X00
goto BASLA
BASLA
CLRF PORTB
BANKSEL TRISB
CLRF TRISB
BANKSEL PORTB
CLRF SAYAC
DON
MOVF SAYAC,W
ANDLW 0X0F ; SAYI 15 I GECMESİNCALL DIZI
MOVWF PORTB
CALL BEKLE
INCF SAYAC,F
GOTO DON
DIZI
ADDWF PCL,F
dt h'3F',h'06',h'5B',h'4F',h'66',h'6D',h'7D',h'07'
dt h'7F',h'6F',h'77',h'7C', h'39',h'5E',h'79',h'71'
BEKLEMOVLW d'4' ;1s bekleMOVWF SAY1
BEKLE_250MSMOVLW d'250';250ms bekleMOVWF SAY2
BEKLE_1MSMOVLW d'249'MOVWF SAY3
LOOP NOPDECFSZ SAY3, F GOTO LOOPDECFSZ SAY2,FGOTO BEKLE_1MSDECFSZ SAY1,FGOTO BEKLE_250MSRETURNEND
Uygulama 4: 9 Dan 0 A Geri Sayıcı
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
;Assembly Kodu
LIST P=16F877
INCLUDE "P16F877.INC"
SAYAC EQU h‘20'
CLRF PORTB
CLRF SAYAC
BSF STATUS,5
CLRF TRISB
BCF STATUS,5
BASLA
INCF SAYAC,F
MOVF SAYAC,W
SUBLW d'10' ;W=10-W
BTFSS STATUS,Z
GOTO DISPLAY
MOVLW h'00'
MOVWF SAYAC
GOTO DISPLAY
GOTO BASLA
DISPLAY
CALL DIZI
MOVWF PORTB
GOTO BASLA
DIZI
ADDWF PCL,F
RETLW b'00111111‘ ;0GFEDCBA
RETLW b'00000110'
RETLW b'01011011'
RETLW b'01001111'
RETLW b'01100110'
RETLW b'01101101'
RETLW b'01111101'
RETLW b'00000111';7
RETLW b'01111111'
RETLW b'01101111'
END
// C kodu
#include <xc.h>
const unsigned char
dizi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x0
7,0x7F,0x6F};
void bekle(){
for (int i=0;i<10000;i++) ;
}
void main(void) // Ana fonksiyon alanı
{
char j=9; // Herhangi bir değisken tanımlanıyor
TRISB=0x00; // PORTB çıkıs olarak
yönlendiriliyor
PORTB=0x00;
for(;;) // Sonsuz döngüye giriliyor
{
PORTB=dizi[j]; // 7 segment değerleri alınıyor
j--;
bekle();
if(j<0)
{
j=9;
}
}
}
Uygulama-5: 0 dan 9 kadar olan sayıları PORB uçlarına bağlı 7 segment display’de
gösteren timer gecikmeli (ileri sayıcı) Assembly programını gerçekleştiriniz.
LIST P=16F877
#INCLUDE<P16F877.INC>
SAYAC EQU h'20'
CLRF PORTB
BSF STATUS,5 ; BANKSEL
TRISB
CLRF TRISB
MOVLW b'11010111'
MOVWF OPTION_REG
BCF STATUS,5 ; BANKSEL
PORTB
BASLA
CLRF SAYAC
DON
MOVF SAYAC,W
CALL DIZI
CALL GECIKME
MOVWF PORTB
INCF SAYAC,F
CALL GECIKME
GOTO DONYRD.DOC.Dr.BÜLENT ÇOBANOĞLU
DIZI
ADDWF PCL,F
RETLW b'00111111'
RETLW b'00000110'
RETLW b'01011011'
RETLW b'01001111‘
RETLW b'01100110'
RETLW b'01101101'
RETLW b'01111101'
RETLW b'00000111'
RETLW b'01111111'
RETLW b'01101111‘
GECIKME
CLRF TMR0
DON1
BTFSS INTCON, T0IF
GOTO DON1
BCF INTCON, T0IF
RETURN
END
Uygulama 6: 00-99 arası sayıcı –C Kodu:
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
#define _XTAL_FREQ 8000000#include <xc.h>int A[]={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0X7D,0x07,0x7F,0x6F};void goster(char i){PORTA=0x02; // RA1 aktifPORTB=A[i/10]; // Onlar basamağı__delay_ms(100); // BeklePORTA=0x01; // RA0 aktifPORTB=A[i%10]; // Birler basamağı__delay_ms(100);}void main(){unsigned char i=0;TRISB=0; TRISA=0;ADCON1=0x07;PORTA=0;PORTB=0;for (;;){i++;if (i>99)i=0;goster(i);
}}
Uygulama 7: Timer gecikmeli 0-99 arası
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
#define _XTAL_FREQ 4000000#include <xc.h>unsigned char sayac=0; const unsigned int A[]={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0X7D,0x07,0x7F,0x6F};static void interrupt olay(void){if (sayac==100){sayac=0;}T0IF=0;//TMR0 bayrağını temizleTMR0=0;}void goster(){sayac++;PORTA=0x02; // RA1 aktifPORTB=A[sayac/10]; // Onlar basamağı__delay_ms(50); // BeklePORTA=0x01; // RA0 aktifPORTB=A[sayac%10]; // Birler basamağı__delay_ms(50);}
void main(){TRISB=0; TRISA=0;ADCON1=0x07;PORTA=0;PORTB=0;T0CS=0; //TMR0 kaynağıPSA=0; // ön bölücüPS0=1;PS1=1;PS2=1;TMR0=0;T0IE=1;T0IF=0;GIE=1; // Genel kesme izni veriliyor for (;;){goster();} }
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Uygulama 8: 00-99 a İleri-Geri Sayıcı (Tarama Yöntemi ile)
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Uygulama 8: 00-99 a İleri-Geri Sayıcı (Tarama Yöntemi ile) [1/2]
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Uygulama 8: 00-99 a İleri-Geri Sayıcı (Tarama Yöntemi ile) [2/2]
Uygulama 8: Trafik Işığı Program Parçası
BASLA CLRW
MOVWF DURUM
DON
CALL SINYAL ; DURUMU DEĞİŞTİR.
MOVWF PORTB ; SINYAL DEĞERINI PORTB DE GOSTER
INCF DURUM,W ; DURUMU BİR ARTIR, SONUCU W YA YAZ.
ANDLW 0X03 ; MAKSIMUM 3 ‘E KADAR ARTIR.
MOVWF DURUM ; W İÇERİĞİNİ DURUM DEĞİŞKENİNE AKTAR
CALL GECIKME ; BEKLE :-)
GOTO DON
SINYAL
MOVF DURUM,W ; DURUMU W YA TAŞI.
ADDWF PCL,F
RETLW 0X41 ; DURUM==0 İSE YEŞİL VE KIRMIZI(RB6,RB0)
RETLW 0X23 ; DURUM==1 İSE SARI VE KIRMIZI/SARI (RB5, RB0/RB1)
RETLW 0X14 ; DURUM==2 İSE KIRMIZI VE YEŞİL (RB4,RB2)
RETLW 0X32 ; DURUM==3 İSE KIRMIZI/SARI VE SARI (RB4/RB5, RB1
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
K
S
Y
K
S
Y
B7 B6 B5 B4 B3 B2 B1 B0
0 Y S K 0 Y S K
41 1 1
23 1 1 1
14 1 1
32 1 1 1
Örnek Uygulama 8: Trafik Işığı Programı Tamamı
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
K
S
Y
K
S
Y
B7 B6 B5 B4 B3 B2 B1 B0
0 Y S K 0 Y S K
41 1 1
23 1 1 1
14 1 1
32 1 1 1
#include <xc.h>void main(){unsigned char A[]={0X41, 0X23, 0X14, 0X32 };TRISB=0;PORTB=0;while(1){for (int i=0; i<4;i++){PORTB=A[i];
} } }
KesmelerKesme, mikrodenetleyicinin gerçekleştirdiği işleme bakmaksızın belirli
durumların veya olayların oluşması halinde isteklere/olaylara cevap
verilmesini sağlayan mekanizmadır. Oluşan her kesme olayı ile programın
normal işlenme süreci değiştirilerek program durdurulur ve kesme alt
programı işletildikten sonra ana programın işlenmesi kalınan noktadan
devam eder. Kesme kaynakları;
PIC16F877 Kesme Kaynakları ve Kaydedicileri
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
RB0/INT KESME OLAYI
RB0/INT girişinden harici olarak kesme oluşturulur.
Bu girişe uygulanan interrupt sinyalinin hangi kenarda olacağı OPTION_REG 6. biti (INTEDG) ile belirlenir.
INTCON 7.biti GIE ile kesmelerine izin verilir.
INTCON 4. biti INTE ile kesmeye izin verilir.
INTCON 1. biti INTF bitinin 1 olması kesme oluştuğunu 0 olursa harici kesme oluşmadığının bildirir.
Programda kesme alt programı içerisind
e INTF=0 yapılmalıdır.
OPTION_REG
INTCON
Uygulama:PORTB nin RB0/INT ucundan gelen bir kesme gerçekleşince kesme alt programında PORTD ye bağlı 7 segment displayde “L” karakterini gösterenprogramı Assembly ve C ile yazalım
Yrd.Doç.Dr. Bülent ÇOBANOĞLU
Program Algoritması:• RB0/INT ucunu giriş olarak seç ,
• OPTION_REG kaydedicisinin INTEDG biti ile düşen veya yükselen kenar tetiklemesini seç ,
• INTCON kaydedicisinin GIE ve INTE bitleri 1 yapılarak kesmeye izin verilir,
• Kesme oluşup, program kesme alt programına dallandığında INTF bitini 0 yap.
Örnek: RB0 girişine bağlı butonun harici kesme mekanizması kullanılarak RD0’a bağlı
olan LED Toggle olarak çalıştırması istenmektedir.
#include <htc.h>
#define LED RD0
interrupt kesme(){
if(INTF){ // RB0 kesme bayrağı 1 ise
INTF=0; // Bayrağı sıfırla ve
LED=!LED; // Çıkış Led'ini tersle
}
}
main(){
TRISD0=0; // Led için RD0'ın çıkış yapılması
LED=1; // Led yansın
INTF=0; // RB0 kesme bayrağı
INTE=1; // RB0 kesme yetkisi
INTEDG=0; // Harici tetikleme girişi 1 -> Yükselen, 0->Düşen kenar
GIE=1; // Global kesme yetkisi
while(1); // Sonsuz döngüde kesme bekle
}
Çalışma Sorusu:
1. RB0 pinine bağlı olan bir tuşa her basıldığında
kesme üreten ve PD4-PD7 pinlerine bağlı olan 4
adet led ile 0-9 arasında binary sayan program
kodlarını yazın.
2. Şekilde çalışma devresi verilen Çamaşır makinesinin
programını yazınız.
PORTB nin 4,5,6,7. pinlerinden en az birinde durum değişikliği
olması durumunda RB Port değişimi kesme olayı meydana gelir.
INTCON 7.biti GIE ile kesmelerine izin verilir.
INTCON 3. biti RBIE biti ile kesmeye izin verilir.
INTCON 0. biti RBIF kesme bayrağı biti PORTB nin 4,5,6,7
pinlerindeki değişikliği bildirir.
PORTB Değişim Kesme Olayı
INTCON
Örnek: PORTB nin 4,5,6,7 pinlerindeki butonlardan herhangi birisine basılması ile
kesme alt programı çalışarak kesme olayı hangi pin de olduğunu PORTD nin 0,1,2,3
pinlerindeki LED lerde görülmesi.
Örnek: PORTB nin 4,5,6,7 pinlerindeki butonlardan herhangi birisine basılması ile
kesme alt programı çalışarak kesme olayı hangi pin de olduğunu PORTD nin 0,1,2,3
pinlerindeki LED lerde gösteren Assembly programı.
LIST P=16F877
INCLUDE "P16F877.INC"
ORG 0X00
GOTO BASLA
ORG 0X04
GOTO KESME
BASLA
BSF STATUS,5
MOVLW 0XF0
MOVWF TRISB
CLRF TRISD
BCF STATUS,5
CLRF PORTD
CLRF PORTB
BSF INTCON,RBIE
BSF INTCON,GIE
GOTO BASLA
KESME
BCF INTCON,RBIF
D1 BTFSS PORTB,4
GOTO D1
BSF PORTD,0
D2 BTFSS PORTB,5
GOTO D2
BSF PORTD,1
D3 BTFSS PORTB,6
GOTO D3
BSF PORTD,2
D4 BTFSS PORTB,7
GOTO D4
BSF PORTD,3
RETFIE
END
TMR0 taştığında kesme oluşur.
INTCON 7.biti GIE ile kesmelerine izin verilir.
INTCON 5. biti T0IE biti ile kesmeye izin verilir.
INTCON 2. biti T0IF kesme bayrağı ile kesme belirlenir.
TMR0 Kesmesi
INTCON
Örnek: TMR0 kesme mekanizmasını kullanarak RD0 çıkışında 10 hz’lik bir kare
dalga sinyal elde ediniz.
#include <htc.h>
#define LED RD0
/*TMR0 taştığında çağırılır*/
interrupt KesmeTMR0(){
if(T0IF){ // Kesme oldu ise
TMR0=-200; // TMR0'a başlangıç değerini yeniden ata.
LED=!LED; // LED'ini değille.
}
T0IF=0; // Kesme bayrağını sıfırla.
}
main(){
TRISD0=0; // RD0 çıkış
T0CS=0; // TMR0, Timer olarak çalışsın
T0SE=1; // Yükselen kenar tetikleme
PSA=0; // WDT pasif T/C aktif
PS0=1; // Ön yükleyici 111 => 256'e bölünecek
PS1=1; // OSC=4 MHz, Timer => 1Mhz / 256
PS2=1; // Timer bir sayması 256 usn
TMR0=-200; // TMR0=-200 => 256 usn x 200 =51.200 usn
T0IF=0; // TMR0 kesme bayrağını resetle
T0IE=1; // TMR0 kesmesi aktif
GIE=1; // Global kesme aktif
while(1); // Kesme bekle
}
TMR1 taştığında kesme oluşur.
INTCON 7.biti GIE ile global olarak kesmeye izin verilir.
INTCON 6.biti PEIE ile çevre birim kesmelerine izin verilir.
PIE1 0.biti TMR1IE ile kesmelerine izin verilir.
PIR1 0.biti TMR1IF ile kesme kontrol edilir.
TMR1 Kesmesi
#include <xc.h>
#define LED RD0
/* TMR1 kesme hizmet fonksiyonu (4 Mhz'lik kristalde
0,5sn aralıklarla bu fonksiyona girilir)*/
void main(){
LED=0;
TRISD0=0; // RD0 portu çıkış
TMR1ON=1; // TMR1 aktif
TMR1CS=0; // Dahili clock (timer)
T1CKPS0=1; // Ön Bölücü “11”
T1CKPS1=1; // 1:8 (8 usn)
TMR1H=3036/256; // 65536-62500=3036 say
TMR1L=3036%256; // 62500 sayma x 8 usn = 0.5 sn
TMR1IF=0; // TMR1 kesme bayrağını resetle
TMR1IE=1; // TMR1 kesmesi aktif
PEIE=1; // Çevre birim kesmeleri aktif
GIE=1; // Global kesme aktif
while(1); // Kesme bekle
}
Örnek.TMR1 kesme mekanizmasını kullanarak RD0 çıkışında 0,5 sn aralıklarla değişen bir kare dalga sinyal
oluşturunuz.
void interrupt kesmeTMR1() { if(TMR1IF){ // Kesme geldi mi?TMR1H=3036/256; //0'lanan TMR1 a yeniden 3036 değeri yükleTMR1L=3036%256; // 62500 sayma x 8 usn = 0.5 snLED=~LED; // Çıkış LED'ini tersleTMR1IF = 0; // TMR1 kesme bayrağını sıfırla.}
}
Açıklama:
4MHz, 1µSn dir ve 500.000 sayım için Timer 1’i 62.500’e kadar
saydıracak olursak; Prescaler oranını 1:8 seçdiğimizde
62500*8=500000 yani 0,5 sn lik gecikme demektir. O zaman bu
örnekte TMR1 e başlangıç değeri olarak;
65536-62500=3036 değeri yüklenmelidir.
Not: 3036 sayısının hex karşılığı:0x 0BDC ‘de yüklenebilir.
interrupt Kesme(){
if(T0IF){ // Timer kesmesi var mı?
……….
}
if(INTF){ // RB0 kesmesi var mı?
……..
}
if(TMR1IF) { // TMR! Kesmesi var mı?
..…..
}
if(RCIF) { // Seri port alım kesmesi var mı?
..…..
}
}
Birden fazla kesmenin bir arada kullanılması
Örnek: 2 haneli çoğullamalı displayde 0-99 arası sayıların sayılması istenmektedir.
Sayma işlemi RB0’a bağlı olan bir buton yardımıyla ve RB0 kesmesi ile yapılmalıdır.
Display’lere segment değerlerinin sıra ile gönderimi ise 1msn aralıklar la ve TMR0
kesmesi ile yapılmalıdır.
RA0/AN02
RA1/AN13
RA2/AN2/VREF-/CVREF4
RA4/T0CKI/C1OUT6
RA5/AN4/SS/C2OUT7
RE0/AN5/RD8
RE1/AN6/WR9
RE2/AN7/CS10
OSC1/CLKIN13
OSC2/CLKOUT14
RC1/T1OSI/CCP216
RC2/CCP117
RC3/SCK/SCL18
RD0/PSP019
RD1/PSP120
RB7/PGD40
RB6/PGC39
RB538
RB437
RB3/PGM36
RB235
RB134
RB0/INT33
RD7/PSP730
RD6/PSP629
RD5/PSP528
RD4/PSP427
RD3/PSP322
RD2/PSP221
RC7/RX/DT26
RC6/TX/CK25
RC5/SDO24
RC4/SDI/SDA23
RA3/AN3/VREF+5
RC0/T1OSO/T1CKI15
MCLR/Vpp/THV1
U1
PIC16F877A
A7
QA13
B1
QB12
C2
QC11
D6
QD10
BI/RBO4
QE9
RBI5
QF15
LT3
QG14
U2
7447
R110k
Örnek: Birden fazla kesmenin kullanılması (Çoğullamalı Display)
#include <htc.h>
#define segment PORTD
#define OU1 RC6
#define OU2 RC7
main(){
TRISD=0xF0; // Segmentlerin bağlı olduğu PORTD'nin 4 biti çıkış yap
TRISC6=0; // Display'in 1.Ortak ucu için PORTC'nin 6 bitini çıkış yap
TRISC7=0; // Display'in 2.Ortak ucu için PORTC'nin 7 bitini çıkış yap
T0CS=0; // TMR0, Timer olarak çalışsın
T0SE=1; // Yükselen kenar tetikleme
PSA=0; // WDT pasif T/C aktif
PS0=0; // Ön yükleyici 001 => 4'e bölünecek
PS1=0; // OSC=4 MHz, Timer => 1Mhz / 4
PS2=1; // Timer'ın bir sayması 4 usn
TMR0=-250; // TMR0=-250 => 250 sayıp taşacak yani 4 usn x 250 =1 msn
T0IF=0; // TMR0 kesme bayrağını resetle
T0IE=1 // TMR0 kesmesi aktif
INTF=0 // RB0 kesme bayrağını resetle
INTE=1 // RB0 kesme yetkisi
INTEDG=0; // Harici kesme tetikleme giriş 0 -> Yükselen, 1->Düşen kenar
GIE=1; // Global kesme aktif
while(1); // Kesme bekle
}
/*TMR0 taştığında veya RB0 kesmesi geldiğinde çağırılır*/
interrupt KesmeTMR0(){
static unsigned char sayac=0; //Butona her badıldığında oluşacak sayıyı tutan değişken
static bit durum=0; // Timer taşınca farklı segmente değer gönderimini sağlayacak değişken.
if(T0IF){ // Timer taştı mı? (1 msn oldu mu?)
durum=!durum; // durum değişkeni tersle
if(durum){ // Eğer durum=1 ise display'e sayac'ın birler basamağını gönder
OU1=0; // Soldaki Display' pasif et
segment=sayac%10; // Sayının birler basamağını segmentlere gönder
OU2=1; // Sağdaki displayi aktif et
}else{ // Eğer durum=1 ise display'e sayac'ın birler basamağını gönder
OU2=0; // Sağdaki Display'i pasif et
segment=sayac/10; // Sayının onlar basamağını segmentlere gönder
OU1=1; // Soldaki displayi aktif et
}
TMR0=-250; // TMR0'a başlangıç değerini yeniden ata.
T0IF=0; // Timer Kesme bayrağını sıfırla.
}
if(INTF){ // RB0 kesmesi oldu mu? (Butona basıldımı)
sayac=(++sayac)%99; // Sayma sayısını maksimum 99'a kadar bir arttır.
INTF=0; // RB0 kesme bayrağını sıfırla
}
}
Örnek: Birden fazla kesmenin kullanılması (Çoğullamalı Display)
Seriport’tan bir karakter gönderimi bittiğinde veya karakter alımı
bittiğinde seriport kesmesi oluşur.
INTCON 7.biti GIE ile global olarak kesmeye izin verilir.
INTCON 6.biti PEIE ile çevre birim kesmelerine izin verilir.
PIE1 4. ve 5.bitleri olan RCIE ve TXIE ile kesmelere izin verilir.
PIR1 4. ve 5. bitleri olan TXIF ve RCIF ile kesmeler kontrol edilir.
Seriport Kesmeleri
Seri port kesme işleyişi
YRD.DOC.Dr.BÜLENT ÇOBANOĞLU
Örnek: 2 haneli çoğullamalı displayde 0-99 arası sayıların sayılması istenmektedir.
Sayma işlemi RB0’a bağlı olan bir buton yardımıyla ve RB0 kesmesi ile yapılmalıdır.
Display’lere segment değerlerinin sıra ile gönderimi ise 1msn aralıklar la ve TMR0
kesmesi ile yapılmalıdır. Seriport kesmesi kullanılarak herhangi bir anda seriportttan
s karakterine basılarak sayıcının sıfırlanması sağlanmalıdır.
RA0/AN02
RA1/AN13
RA2/AN2/VREF-/CVREF4
RA4/T0CKI/C1OUT6
RA5/AN4/SS/C2OUT7
RE0/AN5/RD8
RE1/AN6/WR9
RE2/AN7/CS10
OSC1/CLKIN13
OSC2/CLKOUT14
RC1/T1OSI/CCP216
RC2/CCP117
RC3/SCK/SCL18
RD0/PSP019
RD1/PSP120
RB7/PGD40
RB6/PGC39
RB538
RB437
RB3/PGM36
RB235
RB134
RB0/INT33
RD7/PSP730
RD6/PSP629
RD5/PSP528
RD4/PSP427
RD3/PSP322
RD2/PSP221
RC7/RX/DT26
RC6/TX/CK25
RC5/SDO24
RC4/SDI/SDA23
RA3/AN3/VREF+5
RC0/T1OSO/T1CKI15
MCLR/Vpp/THV1
U1
PIC16F877A
A7
QA13
B1
QB12
C2
QC11
D6
QD10
BI/RBO4
QE9
RBI5
QF15
LT3
QG14
U2
7447
R110k
RXD
RTS
TXD
CTS
#include <htc.h>
#define segment PORTD
#define OU1 RC0
#define OU2 RC1
main(){
TRISD=0xF0; // Segmentlerin bağlı olduğu PORTD'nin 4 biti çıkış yap
TRISC0=0; // Display'in 1.Ortak ucu için PORTC'nin 0 bitini çıkış yap
TRISC1=0; // Display'in 2.Ortak ucu için PORTC'nin 1 bitini çıkış yap
T0CS=0; // TMR0, Timer olarak çalışsın
T0SE=1; // Yükselen kenar tetikleme
PSA=0; // WDT pasif T/C aktif
PS0=0; // Ön yükleyici 001 => 4'e bölünecek
PS1=0; // OSC=4 MHz, Timer => 1Mhz / 4
PS2=1; // Timer'ın bir sayması 4 usn
TMR0=-250; // TMR0=-250 => 250 sayıp taşacak yani 4 usn x 250 =1 msn
T0IE=1; // TMR0 kesmesi aktif
INTE=1; // RB0 kesme yetkisi
INTEDG=0; // Harici kesme tetikleme giriş 0 -> Yükselen, 1->Düşen kenar
RCIE=1; // Seriport alım kesmesi aktif
TXIE=1; // Seriport gönderim kesmesi aktif
PEIE=1; // Çevre birim kesmeleri aktif
GIE=1; // Global kesme aktif
UARTBaslat();
printf("\r Sayiciyi sifirlamak icin <s> tusuna basiniz..\n");
while(1); // Kesme bekle
}
Örnek: Birden fazla kesmenin kullanılması (Çoğullamalı Display+ Seriport)
# /*TMR0 taştığında,RB0 kesmesi geldiğinde veya seriporttan karakter geldiğinde çağırılır*/
interrupt KesmeTMR0(){
static unsigned char sayac=0; //Butona her badıldığında oluşacak sayıyı tutan değişken
static bit durum=0; // Her 1 msn'de farklı segmente değer gönderimini sağlayacak değişken.
if(T0IF){ // Timer taştı mı? (1 msn oldu mu?)
durum=!durum; // durum değişkeni tersle
if(durum){ // Eğer durum=1 ise display'e sayac'ın birler basamağını gönder
OU1=0; // Soldaki Display' pasif et
segment=sayac%10; // Sayının birler basamağını segmentlere gönder
OU2=1; // Sağdaki displayi aktif et
}else{ // Eğer durum=1 ise display'e sayac'ın birler basamağını gönder
OU2=0; // Sağdaki Display'i pasif et
segment=sayac/10; // Sayının onlar basamağını segmentlere gönder
OU1=1; // Soldaki displayi aktif et
}
TMR0=-250; // TMR0'a başlangıç değerini yeniden ata.
T0IF=0; // Timer Kesme bayrağını sıfırla.
}
if(INTF){ // RB0 kesmesi oldu mu? (Butona basıldımı)
sayac=(++sayac)%99; // Sayma sayısını maksimum 99'a kadar bir arttır.
INTF=0; // RB0 kesme bayrağını sıfırla
}
if(RCIF){ // seriporttan veri geldi mi?
TXREG=RCREG; // Gelen verinin gözükmesi için yeniden gönder
if(RCREG=='s'|| RCREG=='S') // Gelen karakter s(S) ise
sayac=0; // Sayacı sıfırla
RCIF=0; // Seriport alma bayrağını sıfırla
}
}
Örnek: Birden fazla kesmenin kullanılması (Çoğullamalı Display+ Seriport)