CCS-C ile PIC Programlama, Bit ve Byte İşlemleri Dahili Fonksiyonları
Giriş
Bu yazımızda Bit / Byte seviyesi işlemleri yapmak için CCS-C’nin bize sunduğu hazır fonksiyonları anlatacağız. Öncelikle bir noktayı belirtelim;
CCS-C derleyicisinin dahili fonksiyonlarının hiç birini kullanmadan da kod yazabilirsiniz. Dahili fonksiyonlar daha hızlı kod yazmanızı sağlarlar, Optimizasyon (üretilecek ASM kodunun büyüklüğü) önemli ise dahili fonksiyonları kullanmamaya çalışın. Dahili fonksiyonları kullanmadan nasıl kod yazılacağını ilerki yazılarımızda anlatacağız. Hani şu DataSheet’e bakıp kod yazma dedikleri olay
İçindekiler
bit_clear()
bit_set()
bit_test()
rotate_left()
rotate_right()
shift_left()
shift_right()
make8()
make16()
make32()
_mul()
swap()
#fuse
#use delay
Örnek Kodlar
bit_clear()
Bir değişkenin istenilen Bit’ini Sıfır’lamak için kullanılır. Parametre olarak 8,16 veya 32 bitlik değişken alır. Geriyi değer döndürmeyen bu fonksiyonun kullanımı şu şekildedir.
bit_clear(degisken,BitNo)
int x; long y; int32 z; x = 0x1f; y = 0xa501; z = 0x9c54a8; bit_clear(x,0); // x'in 0. bitini sıfırla x= 0x1e olur bit_clear(y,8); // y'nin 8. bitini sıfırla y = 0xa401 olur bit_clear(z,31); // x'in 31. Bit'ini sıfırla x = 0x1c54a8 olur.
Bu fonksiyonun görevini yerine getirecek Ansi C uyumlu kod ise şu şekilde yazılabilir.
degisken & = ~(1<< Bitno);
x= 0×1f iken bit_clear(x,0) komutu x değerini 0×1e yapıyordu. Ansi C kodu ile yapalım
x &= ~(1<<0);
1 sayısını 0 kez sola kaydırırsak yine bir olur, yani kaydırmıyoruz ![]()
0000 0001 (1 sayısı)
~ operatörü Bit düzeyinde değil işlevi görür.
~1 = 1111 1110 ( Bir ler 0, Sıfırlar 1 oluyor)
x & = 1111 1110 = x & 1111 1110
x degerini ve 1111 1110 değerini alt alta yazıp & (And) ler isek
0001 1111 (0×1f)
1111 1110
0001 1110 (0×1e) değerine ulaşmış oluruz
Şöyle bir soru akla gelebilir, (1<<8) veya (1<<22) gibi bir işlemde 1 sayısı int olarak mı long olarak mı veya int32 olarak mı değerlendiriliyor.
Cevap: CCS-C kullandığınız değişkene göre kendisi bunu otomatik ayarlıyor. Şöyle bir örnek verelim;
long f; f = 0xa501; f &amp;amp;amp;=~(1<<8); ifadesi için derleyici sadece BCF 3F.0 kodunu oluşturur
f değişkeni 2 Byte olduğu için RAM’de 0×3e,03f adreslerinde saklanmaktadır. (Derleyicinin hangi değişkeni Hangi Adrese yerleştirdiğini öğrenmek için Compile Araç Çubuğundaki Symbol Map seçeneğine tıklayın)
f = 0xa501; ataması yapıldığında RAM Bölgesinde Adres 3e = 0x01 Adres 3f = 0xa5 olur
F’nin 8. Bit’inin Sıfır’landığında 0xa5 değeri 0xa4 olacağı için asm oalrak BCF 3F.0 kodu doğrudur.
bit_set()
Bu fonksiyon bit_clear() fonksiyonun tersi işlem görür. Yani bir değişkenin istenilen Bit’inin değerini 1 yapmak için kullanılır.
bit_set(degisken,BitNo)
int x; long y; int32 z; x = 0x1f; y = 0xa501; z = 0x9c54a8; bit_clear(x,7); // x'in 7. bitini 1 yap x= 0x9f olur bit_clear(y,2); // y'nin 2. bitini sıfırla y = 0xa401 olur bit_clear(z,31); // x'in 31. Bit'ini sıfırla x = 0x0c54a8 olur.
Eşdeğer Kod
degisken |=(1<< BitNo); // Sağlamasını yapıp sonucu görün
bit_test()
Bir değişkenin istenilen Bit’inin durumunu sorgulamak için kullanılır. Sorgulanan Bit 1 ise geriye döndürülen değer 1, Sıfır ise geriye döndürülen değer 0 olur.
bit_test(degisken,BitNo)
degisken: 8 , 16 veya 32 Bit Integer
Bitno: 0-31 arası değer (Kullandığınız değişken tipine göre)
int x; int32 y; BOOLEAN led; if(bit_test(x,5)) // x'in 5. Biti 1 ise if(!bit_test(x,5)) // x'in 5. Biti 0 ise led = bit_test(y,26); //y'nin 26. Bit'i 1 ise led = 1 olur 0 ise led = 0 olur
Eşdeğer Kod
(1<< BitNo)°isken;
Kullanım örneği
if((1<<5)&amp;amp;amp;x) // x'in 5. bit'i 1 ise
rotate_left()
Bu fonksiyon bir değişkeni veya dizi değişkeni sola döndürmek için kullanılır. Parametre olarak değişkenin adresi ve kaç Byte işlem yapılacağını alır. Geriye değer döndürmez
rotate_left(adres,byte)
adres: Hafıza bölgesi
Byte: Döndürme işlemi Kaç byte üzerinden yapılacak
Döndürme İşlemi Nedir?
Hemen örnekle açıklayalım;
x = 0×81 olsun binary = 1000 0001 değerine karşılık gelir.
x’i sola döndürmek şu demektir. En soldaki biti çıkar diğer bütün bit’leri 1 sola kaydır. Soldan çıkan Bit’i en sağa yerleştir. Yani kısaca en soldaki Bit’i al en sağa koy.
en soldaki biti alıp en sağa koyar isek yeni değer 0000 00011 olur. Hex olarak 0×03 değeri bulunur
int x = 0x81; rotate_left(&amp;amp;amp;x,1); //komutundan sonra x= 0x03 olur
&x = x değişkeninin adresi manasına gelir
long x=0xffaa; rotate_left(x,2); // x = 0xff55 olur
rotate_right()
Bu fonksiyon ise sağa döndürme işlevi yapar. İşleyişi rotate_left() ile aynıdır sadece yön farklıdır. En sağdaki bit çıkarılıp en sola konur.
int x = 0x81; rotate_right(&amp;amp;amp;,1); //komutundan sonra x= 0xc0 olur
&x = x değişkeninin adresi
long x=0xffaa; rotate_right(x,2); // x = 0x7fd5 olur
shift_left()
Sola kaydırma işlemlerinde kullanılan bu fonksiyonun kullanım şekli aşağıdaki gibidir.
shift_left(adres,bytes,deger)
adres: Ram hafıza bölgesi, yani değişkenin adresi
bytes: İşlemin kaç Byte üzerinden yapılacak?
data: 1 veya 0, kaydırma işlemiyle birlikte değişkene eklenecek bit
sola_kaydırma işleminde, en soldaki bit çıkarılıp diğer bitler sola kaydırılır. data parametresinde verilen değer en sağa eklenir. Örnek verelim
int x= 0x81; // binary 1000 0001 shift_left(&amp;amp;amp;x,1,1);
en soldaki biti atalım 0000001 olur en sağa da 1 koyalım 0000 0011 olur.
shift_left(&amp;amp;amp;x,1,1) = 0x03 olur shift_left(&amp;amp;amp;x,1,0) = 0x02 olur (soldaki bit atılıp en sağa 0 konulur)
int dizi[5]; shift_left(dizi,5,1); // 5 byte üzerindne işlem yapılır, dizinin ilk elmanının ilk biti 1 olur
Not: dizinin adı asresi yerine geçer bu yüzden başına & simgesi konmaz.
Bu fonksiyonun geriye döndürdüğü değer en soldan atılan Bit’dir.
int1 test_bit; int x=0x81 // binary = 1000 0001 test_bit = shift_left(&amp;amp;amp;x,1,0)) // test_bit = 1 olur, en solda 1 vardı çünkü
shift_right()
Bu fonksiyonun çalışması aynı shift_left() gibidir, bunda yön sola doğru değil sağa doğrudur. En sağdaki bit çıkartılır en soldan verilen değer girilir.
int x = 0x81; // binary = 1000 0001 shift_right(&amp;amp;amp;x,1,1) = 0xc0 (binary 1100 0000) shift_right(&amp;amp;amp;x,1,0) = 0x40 (binary 0100 0000)
make8()
make8() fonksiyonu 16 veya 32 bit değişkenlerden 8 bitlik değerler almak için kullanılır. Kullanımı şu şekildedir.
make8(degisken,offset)
degisken: 16 veya 32 Bit integer
offset: 0-3 arası değer. (16 için 0-1, 32 için 0-3)
long x=0x1234; long y = 0x12345678; int sekizBit; sekizBit = make8(x,1); //sekizBit = 0x12 olur sekizBit = make8(x,0); //sekizBit = 0x34 olur sekizBit = make8(y,3); //sekizBit = 0x12 olur sekizBit = make8(y,1); //sekizBit = 0x56 olur
make16()
2 adet 8 Bitlik (1 Byte) değerden 16 bitlik (2 Byte) değer oluşturmak için kullanılır. Kullanılışı şu şekildedir;
make16(MSB,LSB);
MSB ve LSB 8 bit Integer
int x,y; long z; x = 0x55; y = 0x aa; z = make16(x,y); // z = 0x55aa olur.
make32()
Parametre olarak verilen 8 bit veya 16 Bit değerlerden 32 bit değer oluşturmak için kullanılır. Kullanılışı şu şekildedir;
make32(deger1,deger2,deger3,deger4)
Parametrelerin ikisi opsiyoneldir, degerlerin 1 kısmı 16 bir kısmı 8 bit olabilir
int x,y,z,t;
long a,b;
int32 c;
x = 0xd1; y= 0×12; z = 0×55; t=0xa9;
a= 0xf301; b =b7c4;
c = make32 (x,y,z,t); // c = 0xd11255a9 olur
c = make32(b,a) // c = 0xb7c4f301 olur
c = make32(x,a); // c = 00d1f301 olur (değer 00 ile 32 bite tamamlanır)
_mul()
Çarpma işlemi oldukça fazla kod üreten bir işlemdir. Bu fonksiyon daha optimize çarpma işlemleri yapmak için kullanılır. Çarpılacak sayıları parametre olarak alır, çarpım sonucunu geri döndürür.
_mul(deger1,deger2)
deger1, deger2 çarpılacak sayılardır. Bu degerler 8 Bit veya 16 Bit olabilir. Her ikisi 8 Bit olduğunda geriye dönen değer 6 Bit diğer durumlarda 32 Bit’tir.
int x=10,y=100; long z=500,sonuc1 int32 sonuc2; sonuc1 = _mul(x,y); // sonuc1 = 1000 olur sonuc2 = _mul(x,z); // sonuc2 =5000 olur
swap()
8 Bitlik 1 sayıda, 4 er bitlik her iki kısma “nibble” denmektedir. Yani 8 bitlik bir sayıda 2 adet nibble vardır. swap() fonksiyonu parametre olarak verilen sayının nibble’larının yerini değiştirir. Şöyleki;
int x=0xa5; swap(x); // x = 0x5a olur.
Eşdeğer Kodu
#fuse
Bir önceki yazımızda kod örneklerinde kullandığımız halde açıklamamıştık. Haklı olarak bazı arkadaşlar sordular. Bizde bu yazıda bahsedelim dedik.
PIC Mikro Denetleyicilerine Program yüklenirken, fuse denilen ayarlarında yüklenmesi gerekir. Bu ayarlar hex kodunu çipe yüklerken kullandığınız programda yapılabilir. Siz kodunuzda bu yarları belirtirseniz çipe yazılımı yüklediğiniz programda bu ayarları yapmazsınız.
Fuse ayarları PIC modeline göre değişiklik göstermektedir. CCS-C de View Menüsüne tıklayıp açılan kısımdan Valid Fuses butonuna basın. Açılacak olan pencerede istediğiniz PIC modelini seçin, o PIC için kullanabileceğiniz FUSE ayarları ekrana gelcektir.
PIC16F877 için FUSE ayarlarına Bakalım
XT: 4 Mhz veya 4 Mhz’den Küçük Kristal Osilatör
HS: 4 Mhz’den Büyük Krsital Osilatör
RC: Direnç / Kapasite Osilatörü Clock Out Var
4 mhz kristal kullanacaksanız #fuse XT daha büyük kullanacaksanız #fuse HS şeklinde ayarlamanız gerekiyor.
NOWDT: WatcDog Timer Kapalı
WDT: WathDog Timer Açık
PUT: Power UP Timer açık
NOPUT: Power UP Timer Kapalı
PROTECT: Kod Okumaya Karşı Korumalı
NOPROTECT: Kod Okumaya Karşı Korumasız
PROTECT_50%: Kod Bölgesinin %50’si korumalı.
BROWNOUT: Brown Out Koruması Aktif
NOBROWNOUT: Brown Out Koruması Aktif Değil
LVP: Düşük voltaj Programlama Açık
NOLVP: Düşük voltaj Programlama Kapalı
CPD: Data EEPROM Kod Korumalı
NOCPD: Data EEPROM Kod Korumalı Değil
WRT: Program Hafızası Yazma Korumalı
NOWRT: Program Hafızası Yazma Korumalı Değil
DEBUG: ICD debugger kullanılacak
NODEBUG: ICD Debugger Kullanılmayacak
Fuse ayarlarının her birinin ne manaya geldiğini ayrıntılı olarak başka bir yazıda işleyeceğiz.
#use delay
CCS-C derleyicisinin 3 adet gecikme fonksiyonu vardır, bunlar delay_ms(), delay_us ve delay_cycles() fonksiyonlarıdır. Bu fonksiyonların düzgün çalışması için. İşlemcinin Saat Frekansı #use delay direktifi ile Derleyiciye bildirilir.
#use delay(clock = 20000000) // İşlemci Çalışma Hızı 20 Mhz)
Eğer Watch-Dog Zamanlayıcısını kullanıyorsanız, gecikme fonksiyonlarında zamanlayıcının sıfırlanması gerekir. Bu gibi durumlarda #use_delay aşağıdaki gibi kullanılır
#use delay(clock = 20000000,restart_wdt) // 20 Mhz, watch-Dog sıfırla
PROTEUS PROJESİ İÇİN ÖRNEK KODLAR
Kodları simule etmek için bir önceki yazımızda verdiğimiz proteus projesini kullanabilirsiniz.
Örnek-1
B portundaki dip-switch’ler D portundaki Led’leri kontrol ediyor.
#include <16f877.h>
#use delay(clock=4000000)
#fuses XT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
void main(void)
{
int PORTB,PORTD,i; // PORTB,PORTD ve i 8 bit integer
while(1)
{
PORTB = input_b(); // B portunu oku değeri PORTB'ye ata
PORTD = 0; // PORTD değişkeni sıfırlanıyor (PORT DEĞİL)
for(i=0;i<8;++i) // 8 adımlık döngü, her adımda i bir artıyor
{
if(!bit_test(PORTB,i)) // PORTB in önce 0. biti test ediliyor
bit_set(PORTD,i); // bit 0 ise (switch = ON) PORTD ilk biti 0
// döngü sayesinde 8 bit kontrol edilir ve ayarlanır
}
output_d(PORTD); // PORTD değişkenini Porta yaz (Ledler)
}
}
Örnek-2
Aynı işi yapan başka bir kod
#include <16f877.h>
#use delay(clock=4000000)
#fuses XT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
void main(void)
{
int PORTB,PORTD,i;
while(1)
{
PORTB = input_b(); // B portu PORTB değişkenine okunuyor
PORTD = 0; //değişken sıfır'lanıyor
for(i=0;i<8;++i) // 8 adımlık döngü her adımda 1 artıyor i
{
//PORTB değişkeninin 8 biti PORTD değişkenine shift ediliyor
shift_left(&amp;amp;amp;PORTD,1,bit_test(PORTB,i));
}
output_d(PORTD); // değer LED'lere aktarılıyor
}
}
Örnek-3
Geçen yazımızda yaptığımız yürüyen ışık.
#include <16f877.h>
#use delay(clock=4000000)
#fuses XT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
void main(void)
{
int PORTB,PORTD,i;
PORTD = 0x01; // önce ilk ledi yakacağız
while(1)
{
output_d(PORTD); // değeri ledlere aktar
delay_ms(250);
rotate_left(&amp;amp;amp;PORTD,1); // bir biti devamlı döndürüyoruz
}
}
Örnek-3
Swap için örnek
#include <16f877.h>
#use delay(clock=4000000)
#fuses XT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
void main(void)
{
int PORTB,PORTD,i;
PORTD = 0xf0; // Led'lerin sadece 4 tanesi yanacak
while(1)
{
// sırasıyla ledlerin ilk 4 ü yanar sonra ikinci dördü yanar
// daha sonra yine ilk dördü yanar.
// değer 0xf0 ve 0x0f arasında dönüşüm yapar sürekli
output_d(PORTD);
delay_ms(250);
swap(PORTD);
}
}
Bir konunun daha sonuna geliş bulunmaktayız, kafanıza takılan bir nokta olursa sormaktan çekinmeyin. Sorularınızı direkt mail yoluyla ( admin@teknobakis.com ) veya yazı altına yorum yaparak sorabilirisiniz.
Bir sonraki dersimizde ölmez sağ kalırsak Derleyicinin Ön İşlemci (Pre-Processor) Komutlarını işleyeceğiz.
“CCS-C ile PIC Programlama, Bit ve Byte İşlemleri Dahili Fonksiyonları” yazısı için 25 Yorum yapıldı
Kardeşim eline emeğine sağlık çok güzel anlatmışsın
kolay gelsin Selamlar
@Kemal
Sağolasın sana da kolay gelsin…
Hocam şimdi daha güzel oturdu bazı konular…
Kodları yarın erken kalkmam gerektiği için tam inceleyemedim. Yarın onlar hakkındaki yorumumu da belirtirim…
İyi geceler…
Hocam dediğiniz gibi ufak işlemlerde pek etkisi görülmüyor ama karışık bir program yazarken bu komutları kullanmak işi baya kolaylaştırıyor…
Bu arada B portundaki dip-switch’ler D portundaki Led’leri kontrol etmek için sanırım en kısa kod;
#include
#use delay(clock=4000000)
#fuses XT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
void main(void)
{
for(;;)
{
output_d(input_b());
}
}
Kolay gele =)
@fxDev
Switchler Pull-up yapıdığı için (normalde 1 on pozisyonunda 0 olur B portuna bağlıpin) ~ simgesini koyduk.
Bir önceki yazımızda aşağıdaki kodu vermiştik
void main(void)
{
while(1)
{
output_d(~input_b());
}
}
merhaba, önceki sorumun cevabı için teşekkürler(global değişkenler, pointer, değer dönderme hakkında).
bir sorum daha olacaktı. konuyla alakası yok gerçi ama merak ettim:
interrupt öncelikleri nasıl acaba? yani PRIORITY komutuyla önceliği belirlemezsem ve iki interrupt çakışırsa hangisi çalışır? timer0,timer1 ve timer2 arasından.
Sen harhangi bir öncelik belirtmezsen öncelik sırası timer1,timer2,timer0 şeklinde oluyor. Ama öncelik belirtip sıralamayı değiştirebilirsin.
#PRIORITY timer0,timer2,timer1
direktifini yazarsan öncelik timer0,tiemr2,timer1 şeklinde olur.
Hocam bu arada kristal falan uğraşmayı sevmiyorum sizce 40 pinli dahili osilatörü bulunan bir pic var mı kullandığınız?
Hocam 16f887′yi nerede buldunuz acaba? Ben dün sorduğumda adam 877′yi kaktırmaya çalıştı da…
Bu arada kristal kullanmanın ya da kullanmamanın yer kaplaması hariç bir farkı var mı?
Dahili kristal kullanırsan hız seçeneğin fazla olmuyor. Harici de istediğini takabilirsin. Dahili osilatör kalite bakımından kristale göre daha kötüdür. Sıcaklıktan daha fazla etkilenir ve çok hassas değildir. Hangi clock kaynağını kullanacağın aslında yapacağın uygulamaya bağlı. Çok hassas timingleri olan bir proje için dahili RC osc. kullanmak pek mantıklı olmayacaktır. Sen kristal kullanmaya da alış mutlaka. Örneğin ben geçenlerde bir test düzeneğinde 185000 baud civarlarında rs232 hızına ihtiyaç duydum, tam hatırlamıyorum ama elimdeki 14,küsür bir kristal işimi görmüş idi. Dahili osilatörle bunu yapmam mümkün değildi.
Bu arada benim sana verdiğim listeyi Microchip’in MAPS programından çikardım. 16f887 kullanmadım hiç.
Hocam sağolasınız bilgileriniz için…
Bu arada yeni dersler tatil nedeniyle aksadı sanırım =)
@FxDev
Aynen öyle oldu, pazartesi dönüyorum inşallah.
Hocam proteus simülasyonunda bazı anlamadığım aletler var.Hatta bunlar PIC’ye bağlı bile değil.Üstüne PIC’ye besleme verilmiyor hiç.Bu konuyu açıklarsanız sevinirim.
@Hasan
gerçek devre olmadığı için PIC’e besleme verilmesine gerek yok Proteus besleme verilmiş gibi simulasyon yapıyor.
Proteus kullanımyla ilgili picproje forumun şu kısmına bakabilirsin.
http://picproje.org/main/modules.php?name=Forums&file=viewforum&f=44
iyi günler ben make32 fonksiyonunu içeren bir header filea ya da make32 foksiyonunun nasıl yapıldığını öğrenmeye ihtiyacım var ikincisi daha çok makbule geçer şimdiden teşekkürler..
@merve
verilen 4 adet 8 bitlik sayıdan 32 bitlik sayı oluşturacak fonsksiyonu şu şekilde yazabiliriz.
int32 bizim_make_32(int x,int y,int z, int t)
{
int32 tmp;
tmp = 0;
tmp = tmp | x;
tmp = tmp << 8;
tmp = tmp | y;
tmp = tmp << 8;
tmp = tmp | z;
tmp = tmp << 8;
tmp = tmp | t;
return tmp;
}
kullanılışı
int32 sayi;
sayi = bizim_make_32(0×01,0×02,0×03,0×04);
bu komuttan sonra
sayi = 0×01020304; (32 bit) olur
Merhaba, güzel çalışma teşekkürler.. Aralarda vermiş olduğun kodların ANSI C kod karşılıklarını nerden bulabiliriz.. (CCS komutlarının ANSI C karşılığı)
İkinci olarak da direk ANSI C ile yazabilir miyiz?
CCS-C ile direk Ansi C kodlama da yapabilirsin. Hiç bir hazır fonksiyonu kullanmak zorunda değilsin. Hazır fonksiyonların ansi c karşılığını içeren bir liste yok. Kullanıcı kendisi yazması gerekiyor. Özellikle istediğin bir komut varsa yardımcı olayım.
mrb hocam…
ben if icerisinde bir islem yapmak istiyorum. eger intcon registerinin 2. biti set (1) ise if blogunun icindeki kodu calistirsin degilse calistirmasin.
yani soyle olsun
if(intcon,2==1)
{calistirilacak kodlar;
}
gibi
bunu nasil yapabilirim. cevap verirseniz cok memnun olurum.
tesekkurler.
#byte INTCON = 0×0B // INTCON tanımlanıyor
#bit T0IF = INTCON.2 // Timer0 kesme bayrağı (2. bit)
if(T0IF) { // INTCON.2 bir mi?
..
..
..
}
interruptlarla ilgili bir yazı hazırlıyorum, bugün yarın yayınlarım orada daha iyi öğrenebilirsin bu konuları.
PIC içerisindeki SFR’lerin (INTCON, TIMER0 vs .vss) CCS-C de nasıl tanımlandığını bilmiyorsan şu yazıya da bir gözat
http://www.teknobakis.com/2008/08/13/ccs-c-dersleri-onislemci-direktifleri-1/#bytebit
kolay gelsin
asm 35 koddan oluşuyor scc c bir kod listesı varmı varsa yayılarmısınız teşekür ederim
yaptığınız çalışmalar için Emrah bey sizi tebrik ederim. bende sizin sayenizde ilk pic programını oluşturdum entegreye yükledim çalıştığını da gördüm çok teşekkür ederim. daha çok eksiğim var ama ufak bir yardım rica edecektim sizden.
diyelim ki 16F877 nin D portuna sırayla çalışan ledler yerleştirtik. D portundaki ledler çalışırken B portunun da D portundan bağımsız bir şekilde sonsuz döngü halinde çalışmasını istiyorum. yani iki ayrı program oluşturmak istiyorum. buna benzer ufak bir program yazarsanız veya açıklama yapabilirseniz çok sevinirim. şimdiden teşekkür ederim.
@hasulhas
her iki portu aynı döngüde işleme sokarsan istediğin olur. Daha profesyonel bir şekilde yapmak istersen timer kesmesi kullanabilirsin mesela. RTOS kullanarak ta ya yapabilirsin ama bu senin için erken biraz.
Sen söylediklerime göre bir şeyler yaz, yapamazsan tekrar yardımcı olurum. Kolay gelsin…