Boş vaktim oldukça CCS C ile uğraşıyorum. Artık bundan sonra çalışmalarımı yoğunlaştıracağım. Bİraz C ye bakayım dedim ama sanki bugün programda bir değişiklik olmuş. Önceden derlemiş olduğum programlarımı şimdi derleyemiyorum. Bir çuval dolusu hata veriyor.
Mesela en basitinden Pic Wizart penceresindeki Example Blink programını ekliyorum onu bile derlemiyor.
Aldığım hata budur.
Sorun neden kaynaklanabilir.
(http://s15.postimg.cc/5ga0xn2qz/Ads_z.png) (http://postimg.cc/image/c6qi72pwn/full/)
hosting images (http://postimg.cc/)
Bir proje klasörü oluşturup tüm dosyaları oraya kopyalamayı deneyin; main.c, main.h, 16F877A.h, vs.
Kodunuzda da bu dosyaları eklerken çift tırnak kullanın; <main.h> yerine "main.h" gibi.
hocam malesef sorun çözülmedi aynı sorunu yaşıyorum.
Sorunun neden kaynaklandığını hiçbir şekilde bilmiyorum. Mesela sedar çiçeğin kitabındaki kod örneklerini birebir uyguluyorum derlemiyor.
Blink programını ekliyorum.
(http://s14.postimg.cc/ikm0tkfxd/Ads_z2.png) (http://postimg.cc/image/vc0702pp9/full/)
upload images (http://postimg.cc/)
Sonra compile tuşuna bastığımda main.h dosyası açılıyor.
(http://s17.postimg.cc/yqzdd1zun/Ads_z.png) (http://postimg.cc/image/6qv9srwe3/full/)
image hosting (http://postimg.cc/)
Program dosyalarını tek bir klasör içinde topluyorum. Dediğiniz gibi eklentileride tırnak içerisine aldım. Hatta belki Programın dosyaları silinmiştir diye silip yeniden kurdum ama sorun düzelmedi.
Başka ne problem olabilir.
CCS'in ide'sini kullanmadığımdan pek bir şey diyemiyorum. Proje oluşturduktan sonra ilgili dosyaların eklendiğine emin misiniz? Sol tarafta proje içindeki dosyaları gösteren bir yer olması lazım.
gordugum kadarıyla klasör isimlerinizde turkce karakter yer almakta duzeltip tekrar deneyin ayrıca denetleyici baslık dosyasını bulamıyor
yok hocam başka bir problem var.
Klasör adları main olarak geliyor zaten ben birdaha değiştirmiyorum.
Dosyalar ekleniyor ama sol tarafta eklenen dosyaların gösterildiği kısım yok. ne problem var gerçekten çok merak ediyorum. Canımı sıkmaya başladı bu iş.
C yi komple bilgisayardan kaldırdım yeniden kurdum ama değişen birşey olmadı.
Yardımlarınızı bekliyorum.
View sekmesini kontrol edin, kapanmış olabilir. Bu arada eve bağlanıp bir proje oluşturmayı deneyeyim.
Ekleme:
Project sekmesinden Create dedim, açılan pencereden dosyaların olduğu klasördeki main.c'yi seçtim.
Target bölümünden mikrodenetleyiciyi seçip Apply dedim. Derlemede bir sorun çıkmadı.
hocam ekledim onu. Kapatmışım herhalde.
Versiyonla alakalı olduğunu düşünüyorum. Bende 4.124 yüklü. Başka ne problem olabilir. daha bakmadım yer denemediğim program kalmadı.... :( :(
Hocam komple sil register dosyalarını falan baştan kur compilerlar garip hatalar verebiliyorlar bazen :(
Hocam yok deli olacam >:( Ne oldu bu programa bilmiyorum. Sorunun çözümü nedir bilmiyorum. Kaç defa programı silip kurdum. Önceden 4.124 yüklüydu. Silip 4.106 yı yükledim yine aynı problemle karşı karşıyayım. Daha ne sorun olabilir anlamıyorumki Sankide inadıma bana, sana C ne lazım diyor... :( :(
Son günlerde bilgisayarda önemli değişiklikde yapmadım. Bir iki defa mplabı kurup silmiştim. Birde Geçen hafta bilgisayar ekran kartını görmüyor diye bios güncellemesi yaptım. onun dışında herşey aynı :(
Project menüsünden Project options kısmından aşağıdaki klasörlerin doğru PATH tanımlarını yapmanız gerek, aksi halde gerekli sürücüleri bulamadığı için derleme hataları oluyor mesela 16F877.h dosyasını görmüyor ve derlemiyor
(http://s8.postimg.cc/5cug62ibp/rrr.jpg)
Alıntı yapılan: CaFFeiNe - 10 Şubat 2012, 19:05:21
Project menüsünden Project options kısmından aşağıdaki klasörlerin doğru PATH tanımlarını yapmanız gerek, aksi halde gerekli sürücüleri bulamadığı için derleme hataları oluyor mesela 16F877.h dosyasını görmüyor ve derlemiyor
(http://s8.postimg.cc/5cug62ibp/rrr.jpg)
Hocam Sağolun ya çıldırmak üzereydim. Sonunda sizin sayenizde çözdüm. Bilmiyordum açıkçası öyle yapılması gerektiğiniz. Sizin tanıttıklarınızı bende tanıtınca sorun çözüldü :)
Bundan sonra çalışmalarımı hızzlandıracam yavaş yavaş elim alışıyor.
ben zırt pırt usb ile başka bilgisayarlarda kullandığım için her bilgisayarda usb sürücü farklı isimlendirilebiliyor, D,E,F gibi bu sebepten hepsini ekliyorum
d:\pic\devices
d:\pic\drivers
e:\pic\devices
e:\pic\drivers
f:\pic\devices
f:\pic\drivers
böylece sorun yaşamıyorum
main olan dosya adın.Sen justice_for_all nin dediği gibi klasör adını değiştir "Yeni Klasör" olanı "project" felan yap .
Klasör ( folder ) adını değiştirecen dosya adını değil.
Anladım hocam. Şimdi sorun kalmadı ya ilgilenenlere teşekkürler
Ferhat,
imkanın varsa 4.128 yükle. forumda linki vardı. dier eski versiyonlarda bazı sorunlar yaşadım. örneğin, lcdyi proteusta çalıştırmak için lcd.c kütüphanesinden bazı satırları silmen gerekiyor haberin olsun. yeni versiyonda bunu düzeltmişler.
Hocam Şuanda yine 4.124 ü yükledim. Varsa eğer indirebileceğim bir link verebilirmisiniz?
Tamamdır hocam indirdim ben.
Arkadaşlar. Programda giirş çıkış tanımlamaları yaparken iki adet hata veriyor.
Yazdığım komut budur.
set_tris_b(0x00);
output_b(0x00);
Aldığım hata ise budur. Tanımlayıcıların yapılmadığını söylüyor ama ne tanımlaması yapılacak bilmiyorum.
(http://s15.postimg.cc/vvlbfxgbv/Ads_z.png) (http://postimg.cc/image/lyaamv8pz/full/)
free image hosting (http://postimg.cc/)
Fikri olan varmı?
Hocam o port yönlendirme kodlarını void main() içine yazdınız değil mi?Tüm kodu koyarsanız daha iyi olur.
Sorun aynen dediğiniz gibiymiş. Void main() içerisine almamışım. Bilmiyorum hep basic dillerine alıştığım için yapısı bana çok ters geliyor. Alışmam biraz uzun vakit alacak. Umarım bu başlık altında yazdıklarım, sorduklarım başınızı ağrıtmaz.
void SystemInit()
{
enable_interrupts(INT_ext); // INT_EXT kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
ext_int_edge(h_to_l);
SETUP_TIMER_1 (T1_DISABLED); setup_timer_2 (T2_DISABLED,0,1); // T1 zamanlayıcısı devre dışı// T2 zamanlayıcısı devre dışı
setup_CCP1 (CCP_OFF); setup_oscillator(OSC_4MHZ);
set_tris_a (0x21);set_tris_b(0x0f);/set_tris_C (0X03); set_tris_d(0); set_tris_e (0xff);
output_a(0);
}
main()
{
systemInit();
while(true)
{
//kodlar..............
}
}
gibi bir şey yaptım. keil vari bu daha güzel oldu, hatta bunu sevdim. neyi nereye yazdığımı nasıl yazdığımı düşünmüyorum artık.
Alıntı yapılan: omereliusuk - 14 Şubat 2012, 13:04:22
void SystemInit()
{
enable_interrupts(INT_ext); // INT_EXT kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
ext_int_edge(h_to_l);
SETUP_TIMER_1 (T1_DISABLED); setup_timer_2 (T2_DISABLED,0,1); // T1 zamanlayıcısı devre dışı// T2 zamanlayıcısı devre dışı
setup_CCP1 (CCP_OFF); setup_oscillator(OSC_4MHZ);
}
main()
{
systemInit();
while(true)
{
}
}
gibi bir şey yaptım. keil vari bu daha güzel oldu, hatta bunu sevdim. neyi nereye yazdığımı nasıl yazdığımı düşünmüyorum artık.
Hocam bu böyle bişeymi oldu
Goto main
Systeminit:
.
.
.
.
.
Return
main:
Gosub Systeminit
while 1=1:wend
End
Basic de bu iş böyle olurdu herhalde
Anlamadığım bir nokta var.
C de kod işleme sırası nasıldır. Mesela Basicde dallanma komutları veya döngü komutlar olmadığı sürece program hep yukarıdan aşağıya doğru işler. Ama C de öyle değil anladığım kadarıyla.
Program herzaman main fonksiyonundanmı koşmaya başlıyor. Yani verdiğiniz örnekte SystemInit fonksiyonu Void main fonksiyonundan üstte olduğu için soruyorum. Dediğim gibi Basic ile C nin yapısı çok çok farklı...
Alıntı yapılan: Mucit23 - 14 Şubat 2012, 12:50:41
Sorun aynen dediğiniz gibiymiş. Void main() içerisine almamışım. Bilmiyorum hep basic dillerine alıştığım için yapısı bana çok ters geliyor. Alışmam biraz uzun vakit alacak. Umarım bu başlık altında yazdıklarım, sorduklarım başınızı ağrıtmaz.
sen ne diyorsun. ben bir "gosub" bir de "while(x)" öğreninceye kadar akla karayı seçmiştim (kendim evde öğreniyorum.). basicten geçince çok zor bu konular. ama alışınca yazım meclisten dışarı eşekten uçağa binmiş gibi oldum(basic eşek c uçak oluyor<>).
bir fonksiyonu çağırmak istiyorsan onu çağırmadan önce tanımlamalısın. bu kadar basitmiş. ben de daha önce yazıyorum yazıyorum olmuyor.
gosub (){// main den daha önce tanımlandığı için main buna gidebiliyor.
return (1);}
main()
{
while(1)// şart her zaman doğru olduğu için aradaki işlem sürekli yürütülür.
{
gosub();// gosub fonksiyonuna gider.
}
/// buraya hiç bir zaman ulaşamayacaktır. çünkü şart her zaman doğru olduğu için sürekli gosub fonksiyonuna gidip gelir.
}
umarım yardımcı olmuşumdur.
Alıntı YapAnlamadığım bir nokta var.
C de kod işleme sırası nasıldır. Mesela Basicde dallanma komutları veya döngü komutlar olmadığı sürece program hep yukarıdan aşağıya doğru işler. Ama C de öyle değil anladığım kadarıyla.
C de program yukardan aşağıya
derlenir. Çalışma sırasıda bundan dolayı Yukardan aşağıyadır.
int Toplama(int A,int B) //Toplama Adında bir fonksiyon ve bu fonksiyonda gerekli olan A ve B değerleri
{
Toplama=A+B //A ile B yi topla Fonksiyon değeri olarak döndür
} //Fonksiyon Sonu
main
{
int Sonuc //Sonuc adında integer
Sonuc=Toplama (3,8) //3 iel 8 i toplama fonksiyonuna parametre olarak gönder --Sonuc=8
}
Yazım Hatalı Olabilir işleyişi irdeliyoruzaslında derlenirken yukardan aşağıya derlenir ama fonksiyon çağrılmadan işletilmez yani Toplama(x,y) yazılmadığı sürece bu program blogu çalışmaz.
Çağrıldığı zaman Basic de olduğu gibi (Gosub) işini yapar ve döner. Ama basic (pic basic proton gibi) de bir altprograma parametre gönderip oradan değer alamazsınız..
(bazı basic dillerinde parametreli fonksiyon ve altprogram çağılabiliyoruz)
C'de ana program int main işlevidir. C ve C++ için bu işlevin doğrusu void main değil int main'dir. Diğer işlevler ana programdan çağrılabilir.
#include <stdio.h>
void birSeyYap();
void baskaBirSeyYap();
int main()
{
printf ("ana işlevin içindeyiz\n");
birSeyYap();
printf("gene ana programa donduk\n");
}
void birSeyYap()
{
printf("bir seyler yapiyorum\n");
baskaBirSeyYap();
}
void baskaBirSeyYap()
{
printf("baska bir islem yapıyorum\n");
}
Program başlatıldığı zaman ilkönce main işlevinin içinden çalıştırılmaya başlanır. Eğer başka bir işlevi çağırmışsak oradan çalışmaya devam eder. O işlevin içinden de başka bir işlev çağırırsak diğer işlevi çağırır. İşlevin yürütülmesi bittiği zaman ana programa geri döner.
Arkadaşlar çok teşekkür ederim. Şimdi biraz daha yerine oturdu. Fonksiyon oluşturma işini anladım ve Program işleyişini anladım. Şimdi gerçekten hoşuma gitmeye başladı. :)
Alıntı yapılan: Mucit23 - 14 Şubat 2012, 14:01:09
Arkadaşlar çok teşekkür ederim. Şimdi biraz daha yerine oturdu. Fonksiyon oluşturma işini anladım ve Program işleyişini anladım. Şimdi gerçekten hoşuma gitmeye başladı. :)
tabi geri deger dondurmeli bir fonksiyon olusturdugumuz zaman derleyicinin hata vermemsi ve degerin geri donmesi için return eklenir
muhittin hocamın kodunu ornek alırsak
int Toplama(int A,int B) //Toplama Adında bir fonksiyon ve bu fonksiyonda gerekli olan A ve B değerleri
{
Toplama=A+B //A ile B yi topla Fonksiyon değeri olarak döndür
return (toplama); // veya return (a+b) gibi
} //Fonksiyon Sonu
main
{
int Sonuc //Sonuc adında integer
Sonuc=Toplama (3,8) //3 iel 8 i toplama fonksiyonuna parametre olarak gönder --Sonuc=8
}
@Caffeine hocam çok teşekkür ederim yardımınız için.Aynı sorun benim de başıma geldi ama çözdüm sayenizde :)
hazır yeri gelmişken bir soruda ben sorayım.
CCS ile 8, 16 yada 32 bit birsayıyı desimal basamaklarına ayırmak için özel bir komut var mı?
basic ile DIG komutunu kullanarak kolayca yapabiliyoruz.
D1=Dig SAYI,2
D2=Dig SAYI,1
D3=Dig SAYI,0
CCS ile ancak hesaplama yaparak ayarıyabiliyorum. bunun için iki ayrı örnek kod var.
1. bu:
int SAYI[4];
int16 ADC1;
SAYI[0]=(ADC1/1000)%10; //BİNLER
SAYI[1]=(ADC1/100)%10; //YÜZLER
SAYI[2]=(ADC1/10)%10; //ONLAR
SAYI[3]= ADC1 %10; //BİRLER
2. şu:
int bir=0,on=0,yuz=0,bin=0;
int16 ADC1;
BIR=0;
ON=0;
YUZ=0;
BIN=0;
WHILE(ADC1>=1000) {ADC1=ADC1-1000, BIN ++;}
WHILE(ADC1>=100) {ADC1=ADC1-100, YUZ ++;}
WHILE(ADC1>=10) {ADC1=ADC1-10, ON ++;}
WHILE(ADC1>=1) {ADC1=ADC1-1, BIR ++;}
basicdeki DIG komutuna benzer birşey yok mu?
Merhaba arkadaşlar.
boş vaktim oldukça CCC C ile ilgileniyorum çalışmalar yapıyorum. Ençokda ARM için C öğrenmek istiyorum. Fakat ben Biryandanda ARM ile uğraşmak istiyorum. Elimde MCBSTM32C board var.
(http://s15.postimg.cc/bju9esxor/mcbstm32c.jpg) (http://postimg.cc/)
image hosting png (http://postimg.cc/)
Board üzerinde STM32F107VC Mikrodenetleyicisi var. TFT si felan duruyor. Ben bu boarda Keil ile gelen example yazılımlarını keilde derleyip Jtag üzerinden Keil UlinkMe yardımıyla yükleyip çalıştırabiliyorum. (Blink Vs okadar ilerlemedim daha :D ) Yapabildiğim sadece bu kadar.
Elimde hiç Ekitap vs yani kaynak yok. Mesela STM32F serisi işlemcilerde portlara nasıl erişilir. Giriş çıkışlar nasıl ayarlanır. Diğer tüm donanımlar ve keil üzerinde kullanımını öğrenebileceğim bildiğiniz bir e kitap varmıdır.
Barış Samancının LPC2000 kitabı var. Mesela o kitapda çok güzel anlatılmış. Bilmediğim bir konu da şudur. Philips LPC işlemcilerinin komut yapısı ile ST işlemcilerinin komut yapısı aynımıdır. Yani ikiside ARM çekirdekli. Örnek veriyorum İki işlemcidede X portunun X. bitine erişebilmek için kullanılacak komutlar iki işlemcide farklılık gösterirmi?
Mikrodenetleyicinin Manual pdf dökümanını indirip okumaya başlayın. Ben de MCB1700 NXP LPC1768 mikro su için var. Manual i 800 sayfa:) hepsini okudum.
STM32F107 nin manuali 1096 sayfaymış :o Ben şimdilik örnek programlar üzerinde oynarayak idare edeyim.
C:\Keil\ARM\Examples\ST\*
burada bazı örnekler var. belki işine yarar.
Biliyorum hocam onları ;)
Merhaba Arkadaşlar
CCS C de LCD komutlarını toplu bir halde bulabileceğim bir kaynak gösterebilirmisiniz.
Örneğin LCD bir değişken yazdırmak için, LCD yi silmek, kursörü taşıma vs gibi komutları bilmiyorum.
Bazı komutları öğrendim Aslında ama hane sayısı belli olmayan (int8,int16,int32,float vs..) bir sayıyı ekrana basamadım bir türlü.
Alıntı yapılan: Mucit23 - 24 Şubat 2012, 10:23:36
Merhaba arkadaşlar.
boş vaktim oldukça CCC C ile ilgileniyorum çalışmalar yapıyorum. Ençokda ARM için C öğrenmek istiyorum. Fakat ben Biryandanda ARM ile uğraşmak istiyorum. Elimde MCBSTM32C board var.
(http://s15.postimg.cc/bju9esxor/mcbstm32c.jpg) (http://postimg.cc/)
image hosting png (http://postimg.cc/)
Board üzerinde STM32F107VC Mikrodenetleyicisi var. TFT si felan duruyor. Ben bu boarda Keil ile gelen example yazılımlarını keilde derleyip Jtag üzerinden Keil UlinkMe yardımıyla yükleyip çalıştırabiliyorum. (Blink Vs okadar ilerlemedim daha :D ) Yapabildiğim sadece bu kadar.
Elimde hiç Ekitap vs yani kaynak yok. Mesela STM32F serisi işlemcilerde portlara nasıl erişilir. Giriş çıkışlar nasıl ayarlanır. Diğer tüm donanımlar ve keil üzerinde kullanımını öğrenebileceğim bildiğiniz bir e kitap varmıdır.
Barış Samancının LPC2000 kitabı var. Mesela o kitapda çok güzel anlatılmış. Bilmediğim bir konu da şudur. Philips LPC işlemcilerinin komut yapısı ile ST işlemcilerinin komut yapısı aynımıdır. Yani ikiside ARM çekirdekli. Örnek veriyorum İki işlemcidede X portunun X. bitine erişebilmek için kullanılacak komutlar iki işlemcide farklılık gösterirmi?
Forumda Bülent Hoca'nın örneklerini inceleyebilirsin. Fikir sahibi olmanda yardımcı olur. Portlara erişmek için GPIOx-ODR , GPIOx-IDR gibi registerlar var.
Burayı incelersen yardımcı olabilir.--> http://www.keil.com/dd/docs/datashts/st/stm32f10xxx.pdf (http://www.keil.com/dd/docs/datashts/st/stm32f10xxx.pdf)
Sayfa 138 ' den itibaren başlıyor portlarla ilgili kısım. Biraz incelersen çok yardımı olur.
CCS C kısmına gelecek olursak ,
lcd_gotoxy(2,1);printf(lcd_putc,"Deneme=%3f ",x);
buradaki lcd_gotoxy(a,b); // burada a kısmı sütunu , b kısmı satırı belli eder. yukarıdaki örnekte 1.satır , 2.sütundan itibaren yazılmaya başlanır.
printf(lcd_putc,"Deneme=") // burada " buraya yazılan mesaj direk olarak gözükür. ascII olarak "
printf(lcd_putc,"deger=%f",x) //burada "deger=" sıkmı lcd'ye yazılır. Sonrasındaki %f kısmı ise sonra bir değişkenin float cinsinden yazılacağını gösterir.
Buradaki %f ,%d kısımlarını aşağıda açıklıyorum.
%d --> işaretli 8 bit tamsayı gösterir.
%c --> karakterleri gösterir.
%s --> string ifadeleri gösterir.
%f --> ondalıklı sayıları gösterir.
%x --> hexadesimal 8 bit sayıları gösterir. Harfler küçük yazılır.
%X --> hexadesimal 8 bit sayıları gösterir. Harfler büyük yazılır.
%u --> 8 bit işaretsiz tam sayı gösterir.
%Ld --> 16bit ve 32bit işaretsiz tam sayı gösterir.
%Lu --> 16bit ve 32bit işaretli tam sayı gösterir.
%Lx --> hexadesimal 16bit ve 32bit sayıları gösterir.Harfler küçük yazılır.
%LX --> hexadesimal 16bit ve 32bit sayıları gösterir.Harfler Büyük yazılır.
...
Bu böyle devam eder gider :)
Bu tanımlamaları Serdar Hoca'nın kitabından aldım. İyi bir kaynak birçok sorunuzun cevabını bulabilirsiniz.
İyi çalışmalar dilerim...
Alıntı YapBuradaki %f ,%d kısımlarını aşağıda açıklıyorum.
%d --> işaretli 8 bit tamsayı gösterir.
%c --> karakterleri gösterir.
%s --> string ifadeleri gösterir.
%f --> ondalıklı sayıları gösterir.
%x --> hexadesimal 8 bit sayıları gösterir. Harfler küçük yazılır.
%X --> hexadesimal 8 bit sayıları gösterir. Harfler büyük yazılır.
%u --> 8 bit işaretsiz tam sayı gösterir.
%Ld --> 16bit ve 32bit işaretsiz tam sayı gösterir.
%Lu --> 16bit ve 32bit işaretli tam sayı gösterir.
%Lx --> hexadesimal 16bit ve 32bit sayıları gösterir.Harfler küçük yazılır.
%LX --> hexadesimal 16bit ve 32bit sayıları gösterir.Harfler Büyük yazılır.
Teşekkür ederim aradığım buydu. Elim alışana kadar sürekli elimin altında olması gerekiyor.
Sorun değil eğer ccs c öğrenmek istiyorsanız Serdar Çiçek CCS C ile Pic Programlama kitabını edinmenizi öneririm. Sadece örnek kod olarak değil birçok donanımıda anlatması nedeniyle güzel bir kitap.
İyi çalışmalar dilerim.
Arkadaşlar Merhaba
Ds18B20den okuduğum sıcaklık bilgisini 2 det byte tipi değişkene bölmek istiyorum. Sıcaklık bilgisi float tipi değişkende 27.2 gibi değerlerle geliyor. CCS de buna özel bir fonksiyon varmı. Yada nasıl yapabilim.
Aynı şekilde 2 adet byte tipi değişkeni nasıl tek bir 16 bitlik değişkende birleştireceğimide öğrenmek isterim. CCS de make komutları var. Bunlar ne işe yarıyor. Buna benzer bir kullanımı var gibi.
"mucit23" ccs c de 18b20 nasıl okuyosun kütüpkanesi falan varmı?
Alıntı yapılan: Mucit23 - 13 Ağustos 2012, 17:06:29
Arkadaşlar Merhaba
Ds18B20den okuduğum sıcaklık bilgisini 2 det byte tipi değişkene bölmek istiyorum. Sıcaklık bilgisi float tipi değişkende 27.2 gibi değerlerle geliyor. CCS de buna özel bir fonksiyon varmı. Yada nasıl yapabilim.
Aynı şekilde 2 adet byte tipi değişkeni nasıl tek bir 16 bitlik değişkende birleştireceğimide öğrenmek isterim. CCS de make komutları var. Bunlar ne işe yarıyor. Buna benzer bir kullanımı var gibi.
Öncelikle şuna cevap vereyim .
2 adet 8 bitlik değişkeni 16 bit yapmak istiyorsun. Bu çok basit kağıt kalemle nasıl yapıyorsan öyle yapacaksın. Komutlarla uğraşmadığımdan bilmiyorum pek.
Örneğin x ve y adında 8 bit değişkenlerimiz olsun. Ve z adında 16 bitlik bir değişken olsun . x ve y değişkenlerini 16 bit yapıp z değişkenine atalım. x düşük değerlikli y büyük değerlikli 8 bit olsun.
unsigned char x,y;
unsigned long int z;
void islem(void)
{
z=y<<8; // y değişkenini 8 bit sola öteleyerek z değişkenine yaz.
z=z|x; // x değişkenini z değişkeni ile veyalar.
}
yada şu şekildede yapabilirsin.
void islem(void)
{
z=(y*256)+x;
}
Hatam varsa özür dilerim. CCS C de program yazmıyorum artık ufak tefek unutulmuşlar olabilir.
Diğer sorunu tam anlayamadım.
Birleştirme işi tamam. Anladım onu.
Diğer sorum ise şöyle söyleyebilirim. Bir adet float tipi değişken var. İçerisinde sıcaklık bilgisi var. 27.4,30.5 gibi Ben bu değeri iki adet byte tipi değişkende saklamak istiyorum. Benim aklıma şöyle bir yöntem geldi.
Sıcaklık değeri 27.1 olduğunu varsayarsak ben bu değeri 10 ile çarparsam 271 sayısını elde ederim.
Sonra bu sayıyı 10 a bölerim 27 sayısını birinci değişkene atarım.
virgülden sonraki haneyi ise Mod alarak bulurum. Örneğin 10'a bölümden kalanı alıp diğer değişkene yerleştiririm. Başka bir önerisi olan varmı?
virgülden kurtarır High ve Low byte olarak 2 bayt da saklarım
örnek
35.5*10=355
355=0000000001100011
Birletirme yi yukarda gördük zaten
Alıntı yapılan: muhittin_kaplan - 13 Ağustos 2012, 18:51:45
virgülden kurtarır High ve Low byte olarak 2 bayt da saklarım
örnek
35.5*10=355
355=0000000001100011
Birletirme yi yukarda gördük zaten
Hocama katılıyorum.
Arkadaşlar CCS de 8 bitlik bir değişkenin i ninci bitini alıp herhangi bir pine nasıl yazarım.
örnek
Data Adında bir değişken olsun. Ben bu değişkenin 5. bitini Portb nin 0 bitine yazmak istiyorum.
Datayı Sağa 4 kaydırır (0. bit e denk gelir)
Data=Data>>4
PortB=PortB | (Data & 00000001)
Kolayı varmı bilmiyorum CCS de
(Belkide Yanlıştır Kontrol gerektirir. Oruç Hali)
output_bit(pin_b0,(i,5));
i nin 5 .ci bit i
Alıntı yapılan: necati - 14 Ağustos 2012, 12:01:30
output_bit(pin_b0,(i,5));
Bende tam bu komutla uğraşıyordum
Pin_b0 ı anladım
i değişkeni de sanırım almak istediğimiz bitin değerini tutuyor. Peki Bu 5 değeri nedir. Neden i ile 5 parantez içerisine alınmış. Bu komutun çalışmasını ve kullanımını anlatabilirmisiniz.
i değişkeninin 5 inci bitini portb.0 ınıa output yap dır herhalde
çalıştıramadım bir türlü. :(
Alıntı yapılan: muhittin_kaplan - 14 Ağustos 2012, 12:07:04
i değişkeninin 5 inci bitini portb.0 ınıa output yap dır herhalde
Hocam dediğiniz gibi olmuyor çıkışın 1 olması için herhangi bir bitin bir olması yeterli oluyor.
Biraz karmaşık şu şekilde yapabilirsin. CCS C ' de komutu varmı bilmiyorum .
örnegin 2 degişkenimiz olsun 1'er bytelik. 5 . Bitin durumuna göre ledi yakıp söndürelim D0 pinindeki.
unsigned char deger=0xAA;
unsigned char islem=0;
int1 lojik=0;
...
...
...
islem=deger&0x20;
if(islem==0)lojik=0;
else lojik=1;
output_bit(pin_d0(lojik));
...
...
Yanlışım varsa düzeltin. Bence bu şekilde istediğin biti alacak (ve işlemi) ile maskele değişken degeri 0 ise lojik 0 değil ise lojik 1 ' dir.
Alıntı yapılan: Mucit23 - 14 Ağustos 2012, 11:34:13
Arkadaşlar CCS de 8 bitlik bir değişkenin i ninci bitini alıp herhangi bir pine nasıl yazarım.
örnek
Data Adında bir değişken olsun. Ben bu değişkenin 5. bitini Portb nin 0 bitine yazmak istiyorum.
int data=0x35; // Örnek.
int1 y=0;
while(1)
{
y=bit_test(data,5);
output_bit(pin_b0,y);
}
Hocam bit_test ile bir değişkenin istenen bitinin değerini öğrenirsiniz.
Herşeyin komutuda var ne güzel... :)
Yapmışken tam yapmışlar :D
Alıntı yapılan: vitruvius - 14 Ağustos 2012, 13:46:44
int data=0x35; // Örnek.
int1 y=0;
while(1)
{
y=bit_test(data,5);
output_bit(pin_b0,y);
}
Hocam bit_test ile bir değişkenin istenen bitinin değerini öğrenirsiniz.
Teşekkür ederim aradığım buydu.
mesaj birleştirme:: 14 Ağustos 2012, 19:15:54
Birisi çıkıpta arkadaş bukadarda sorumu olur.Birazda interneti arastir demesinden korkuyorum. Ama inanın sormadan önce bir sürü internette örnek aradim. Mesela bugün 74Hc595 için bir sürü doğru dürüst çalışan kutuphane aradim.Ccs nin kendi kutuphanesini bile calistiramadimki en son kendi kendime böylesine çalışmasını ve kullanımını iyi bildiğim bir entegre için hazır kod aramak ayıp olur deyip oturup kendim haberleşme için kutuphane yazdım. Ancak bu şekilde çalıştırdım 74Hc595 i...
Her Çıkmaza girdigimde hemen proje ye koşuyorum ama dediğim gibi sormadan öncede bir sürü araştırıyorum.
Başlıktan da anlaşılacağı üzre bunlar benim alıştırma turlarim. Hızlı ilerliyebilmem için bazı basamaklari 3er 4er atlamam gerekiyor. Bu sırada fazla soru soruyorum ama zamanla sorular azalacak ins:)Bu konuda beni mazur görün.
Bugünlük soru kotamı doldurmuş olabilirim ama acelesi yok yarında bi çözüm onerisinde bulunsanız olur. Yarın ihtiyacım olacak aklimdayken sormak istiyorum.
8 bitlik bir degiskeni 1 bit sola kaldırırken en soldaki bite ne oluyor acaba.
Benim amacım solda dışarıda kalan biti alıp başka bir degiskenin sağından vermek.
2 adet kaskat bağlı shift register içerisinde bilgi nasıl kayiyorsa bende aynısını 2 veya daha fazla değişken arasında yapmam lazım.
Yarın kayan yazı gibi birşey yapmaya çalışacağım .
Mesaj birleştirme özelliği... Anket yakında sonuçlanıyor, gereken yapılır umarım.
<< ile sola kaydırma yapılırsa en soldaki bit yok olur gider. Sağ taraftan 0 gelir. Bunun haricinde kaydırma yapmak için iki adet daha komut vardır. Shift_left ve rotate_left. Sizin aradığınız galiba rotate_left komutu. Serdar Çiçek'in kitabı varsa sayfa 177'de güzel bir örnekle anlatmış, yoksa anlatmaya çalışırım.
Hocam kitap var inceleyeyim. Aklıma takılan olursa sorarım yine. Teşekkürler.
mesaj birleştirme:: 15 Ağustos 2012, 14:47:04
Hocam merhaba Serdar çiçeğin kitabına baktım177. sayfada kesme registerleri anlatılıyor. Eminmisiniz sayfa 177 den?
mesaj birleştirme:: 15 Ağustos 2012, 16:32:20
Oldum olası şu kayan yazılardan nefret ettmişimdir.
Vitruvius yapamadım :(
Boş bir vaktinde anlatırsan sevinirim dediğim mevzuyu...
Sanırım aradığın bu
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ü
Emrah Aydın'ın sitesinden alıntı
Arkadaşlar Merhaba
CCS de uygun şekilde kesmeyle matris display nasıl taranır. Ben kesmeyle taramaya çalışıyorum ama bir türlü verimli tarama yapamadım. Timer0 bölücü oranını 1/1 yapmama rağmen dikkatli bakılınca ekranda titremeyi hissediyorum
Buna rağmen İşlemcim 18F4550, HS osc Seçili Ve CPUDIV 2, usb için PLL DIV ise 5 Seçili. Yani kristal frekansı 2 ye bölünüyor ve işlemci 10mips hızda çalışıyor. (Çalışması lazım)
Anlamıyorum Timer0 bölücü oranı 1/1 olmasına rağmen hala titreme oluyor.
PicMulticalc diye bir program var. Onda hesaplamaları yapıyorum. Ama hiçbirşey hesaplarıma uymuyor. Nerede hata yapıyorum
Yazılımı bu şekilde.
#include <18F4550.h>
#device ADC=8 //8 Bit okuma yapılıyor
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV2,VREGEN,NOBROWNOUT // 8MHZ
#use delay(clock=40000000)
//#include <lcd_driver.c>
//#include <One_Wire.c>
//#include <DS1820.c>
//unsigned int16 Tam_Deger;
//float Sicaklik;
unsigned int8 Data,i,z,x,SDATA[2];
//unsigned int8 S1DATA[2],S2DATA[2],S3DATA[2],S4DATA[2],S5DATA[2],S6DATA[2],S7DATA[2],S8DATA[2];
unsigned int1 y;
unsigned int8 sayac=0;
Void Data_Gonder();
Void Tpic_Gonder();
//74HC595 Pin Tanımlamaları
#define HC_Data PIN_D3
#define HC_Clck PIN_D7
#define HC_Ltch PIN_D5
//Tpic6B595 Oin Tanımlamaları
#define Tpic_Data PIN_D2
#define Tpic_Clck PIN_D6
#define Tpic_Ltch PIN_D4
#define Tpic_Enbl PIN_D0
unsigned int karakter[]={};
#int_timer0
Void timer0_Kesme()
{
sayac++;
if(sayac>8)
{
sayac=1;
}
switch (sayac)
{
case 1:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b01111111;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 2:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b10111111;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 3:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11011111;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 4:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11101111;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 5:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11110111;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 6:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111011;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 7:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111101;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 8:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111110;
Data_Gonder();
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
}
set_timer0(99);
}
Void Data_Gonder()
{
z=7;
for (i=0;i<8;i++)
{
y=bit_test(data,z);
output_bit(HC_Data,y);
output_high(HC_Clck);
delay_us(1);
output_low(HC_Clck);
z--;
}
output_high(HC_Ltch);
delay_us(1);
output_low(HC_Ltch);
}
Void Tpic_Gonder()
{
for (x=0;x<3;x++)// Kaç adet Tipic bağlı
{
z=7;
for (i=0;i<8;i++)
{
y=bit_test(SDATA[x],z);
output_bit(Tpic_Data,y);
output_high(Tpic_Clck);
delay_us(1);
output_low(Tpic_Clck);
z--;
}
}
output_High(Tpic_Ltch);
delay_us(1);
output_Low(Tpic_Ltch);
}
void main(void)
{
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_adc(ADC_OFF);
SETUP_ADC_PORTS(NO_ANALOGS);
setup_spi(false);
setup_timer_0(T0_INTERNAL|T0_DIV_1|T0_8_BIT);
set_timer0(99);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_high(Tpic_enbl);
port_b_pullups(False);
delay_ms(100);
for(;;) //Sonsuz Döngü;
{
}
}
Program deneme programıdır. 3 Adet matrixdisplay var ve satırları 74595 ile tarıyorum. Sütünlarda ise Tpic6B595 ler var.Çalışıyor onlar bir problem yok. Ama tarama işini düzgün yapamadım. Bu konuda yardımınıza ihityacım var. Tarama işlemini nasıl yapayım??
#int_TIMER0
void TIMER0_isr(void)
{
disable_interrupts(INT_TIMER0);
set_timer0(250);
for (i=0;i<8;i++){
sayi=binler;
data_al();
data[0]=deger;
sayi=yuzler;
data_al();
data[1]=deger;
sayi=onlar;
data_al();
data[2]=deger;
sayi=birler;
data_al();
data[3]=deger;
sayi=snyonlar;
data_al();
data[4]=deger;
sayi=snybirler;
data_al();
data[5]=deger;
write_expanded_outputs(data);
output_c(tara[i]);
delay_us(600);
output_c(0xff);}
enable_interrupts(INT_TIMER0);}
ben taramayı bu sekilde yapıyorum ve osc yi 20mhz kullanıyorum hiç bir sıkıntı olmuyor (setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32))
kaç mhzlik kristal kullanıyorsun?.Programda konfg. 8mhz için yapılmış sanırım.
o sadece eskiden kalan bir açıklama. 20 mhz kristal takılı.
Alıntı yapılan: halilgalic - 18 Ağustos 2012, 23:12:41
#int_TIMER0
void TIMER0_isr(void)
{
disable_interrupts(INT_TIMER0);
set_timer0(250);
for (i=0;i<8;i++){
sayi=binler;
data_al();
data[0]=deger;
sayi=yuzler;
data_al();
data[1]=deger;
sayi=onlar;
data_al();
data[2]=deger;
sayi=birler;
data_al();
data[3]=deger;
sayi=snyonlar;
data_al();
data[4]=deger;
sayi=snybirler;
data_al();
data[5]=deger;
write_expanded_outputs(data);
output_c(tara[i]);
delay_us(600);
output_c(0xff);}
enable_interrupts(INT_TIMER0);}
ben taramayı bu sekilde yapıyorum ve osc yi 20mhz kullanıyorum hiç bir sıkıntı olmuyor (setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32))
Merhaba
Ben taramayı tek bir kesmede değilde kaç adet satır var ise okadar kesmede yapmayı düşünmüştüm.
Bu işlerde benim mantığım şu şekilde yürür.
Diyelim görüntünün kesintisiz düzgün çıkması için her ledin 2ms aktif olarak beklemesi gerekir.
O halde Timer kesmesini 2ms ye ayarlarım. Yani her 2 ms de bir kesme oluşur.
Her kesmeye gittiğimde eski satırı veya sütünü kapatır, Yeni karakter bilgisini verir ve aktif olması gereken satır ve sütünu aktif ederim.
Bir sonraki kesmeye kadar aktif kalır.
Bir sonraki kesmede önceki satır veya sütünü kapatıp yeni karakter bilgisini verdikten sonra aktif olması gereken satırı açar kesmeden çıkarım. Bunu genelde kesme içerisinde bir sayac tutarak yaparım.
Genelde çok verimli çalışır ama nedense CCS de bu verimi bir türlü yakalayamadım. Baktımda sizin yazılımda kesme içerisinde delaylar koymuşsunuz. Bu yanlış değilmidir. Üstelik her veri ekranda 600us kalıyor. Bu süre az değilmi.
aslında bande sana yakın bi mantık kullanıyorum.Ben bazen iç mekan için dotmatrix(hazır piyasada bulunanlar) kullanıyorum bazende kendi tasarımım dotmatrıxler var 10-20-30cm boylarında onu kullanıyorum bu dotların taramada tepki süreleri birbirini tutmuto yani hazır olanlarla benim ledli dotlar aynı olmuyo bende bunu artık bir kaç deneme yanılma ile yapıyorum ve titremeyi bu şekilde gideriyorum.600us bu şekil bulunmuş bir değer olabilir.Bu mantığa(timerli) göre yazdığım bi programım ver belki işinize yarayabilir .
http://www.upload.gen.tr/d.php/www/01klheme/DOT.rar.html (http://www.upload.gen.tr/d.php/www/01klheme/DOT.rar.html)
Merhaba
Verdiğiniz program için teşekkür ederim. Bi inceleyeyim
Yanlız şu 4550 ve CCS de anlamsız bir durum var izninizle açıklayayım
OSC Configuration ile ilgili...
Aşağıdaki tabloyu inceleyin. 18F4550 nin OSC blok şeması
(http://s15.postimg.cc/k07rp5ipn/Ads_z.png) (http://postimg.cc/)
upload pictures (http://postimg.cc/)
İşlemciye 20Mhz kristal bağlı olduğunu düşünelim.
Ben bu halde iken PLLDIV bölücüsünü 5 olarak seçiyorum. Dolayısıyla 20Mhz kristal 4Mhz ye düşüyor ve USB çarpanı 4 mhz yi 96 mhz ye çıkartıyor.4 numaralı kutudan çıkan 96mhz sinyali USB bölücüsüde 2 ye bölüm 48 mhzde usb donanımını çalıştırıyor. Buraya kadar sıkıntım yok.
Aklıma takılan kısım ise şurası. İşlemci Kristal Tipi HS,XT,EC veECIO seçildiğinde 2 numaralı bölücü, HSPLL, XTPLL, ECPLL ve ECPIO seçildiğinde ise 3 numaralalı kutu içerisindeki bölücü çalışması gerekir. Buraya kadarda problem olmaması gerekir.
Fakat şöyle bir sıkıntı varki Ben CCS de 4550 nin sigortalarında OSC tipini HSPLL olarak seçsemde CPUDIV bölücüsüne max. 4 değerini verebiliyorum. 6 değerini yüklersem CCS hata veriyor.
18F4550.h klasöründe ise sigortalar verilmiş
//////// Fuses: PLL1,PLL2,PLL3,PLL4,PLL5,PLL6,PLL10,PLL12,[color=red][b]CPUDIV1,CPUDIV2[/b][/color]
//////// Fuses: [color=red][b]CPUDIV3,CPUDIV4[/b][/color],NOUSBDIV,USBDIV,XT,XTPLL,EC_IO,EC,ECPLL_IO
//////// Fuses: ECPLL,INTRC_IO,INTRC,INTXT,INTHS,HS,HSPLL,NOFCMEN,FCMEN
//////// Fuses: NOIESO,IESO,PUT,NOPUT,NOBROWNOUT,BROWNOUT_SW,BROWNOUT_NOSL
//////// Fuses: BROWNOUT,BORV45,BORV43,BORV27,BORV21,NOVREGEN,VREGEN,NOWDT
//////// Fuses: WDT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32,WDT64,WDT128,WDT256
//////// Fuses: WDT512,WDT1024,WDT2048,WDT4096,WDT8192,WDT16384,WDT32768
//////// Fuses: CCP2B3,CCP2C1,NOPBADEN,PBADEN,NOLPT1OSC,LPT1OSC,NOMCLR,MCLR
//////// Fuses: NOSTVREN,STVREN,NOLVP,LVP,ICSP1,ICSP2,NOXINST,XINST,DEBUG
//////// Fuses: NODEBUG,PROTECT,NOPROTECT,CPB,NOCPB,CPD,NOCPD,WRT,NOWRT,WRTC
//////// Fuses: NOWRTC,WRTB,NOWRTB,WRTD,NOWRTD,EBTR,NOEBTR,EBTRB,NOEBTRB
Sigortalardanda anlayacağınız üzere CPUDIV6 şeklinde bir sigorta tanımlı değil. Elbette bundan dolayı hata veriyor. 3 numaralı kutu içerisindeki bölücüyü nasıl kullanabilirim? Osilatör tipini HSPLL seçmek yetmiyormu yoksa başka ayarlardamı yapmak gerekiyor. 1. Sorum buydu.
Diğer bir sorum ise hızla ilgili. Farzedelim yine 20 mhz kristal bağlı. PLLDIV 5 olarak seçili ve 20 mhz 5 bölünüp 4 olarak USB çarpanından 96MHZ olarak çıkıyor. Biz bu 96 MHZ ile işlemciyinin clock kaynağını beslemek istiyoruz.
OSC tipi HSPLL seçili olduğu için yukarıdaki resimdeki 3 numaralı bölücü aktif. Şimdi Ben bu bölücüde bölücü orannı 2 verirsem 96MHz 2 ye bölünüp 48 MHZ olarak çıkar. Bu bölücüden sonra başka bir bölücü görünmüyor yani ben bu şekilde ayarlasam işlemci çekirdeğine 48 Mhz gidecek. Peki işlemci Bu hazda çalışabilecekmi. 48mhz az bir frekans değil 18F serisi için.
Merak ettiklerim var bu yüzden konuyu güncel tutmak istiyorum. 1. Sorum neysede 2. Sorumu çok merak ediyorum. Gerçektende bu hızda çalışabilirmi işlemci.
mucit 48mhz e çalışır.
şimdi baktım Datasına normalde 6 yada bölünebiliyor. ((CPUDIV1:CPUDIV0) 1,1 olduğunda Datasheet Table 2.3 )
Eğer 4mhz lik bir kristal kullanıp 2 ye bölersek ((CPUDIV1:CPUDIV0) ile) PLL aktifse 48mhz de çalışır.
Bu işler çok kafamı karıştırdı hocam. Şu clock işlerinde bir türlü dizginleri elime alamadım.
Şu CPUDIV1:CPUDIV0,FOSC3:FOSC0,PLLDIV2:PLLDIV0 registerlerini işlemci sigortalarıyla hiç uğraşmadan kendim elle set edemezmiyim arkadaş. İşlemcim çalışıyor Ama kaç mhz çalışıyor bü türlü anlayamıyorum. Elimin altında osiloskop var. İşlemci çalışma frekansını, Timer kesmesi frekansını nasıl öğrenebilirim
Timer kesmesi alt programım bu şekilde
#int_timer0
Void timer0_Kesme()
{
sayac++;
if(sayac>8)
{
sayac=1;
}
switch (sayac)
{
case 1:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b01111111;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 2:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b10111111;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 3:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11011111;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 4:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11101111;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 5:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11110111;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 6:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111011;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 7:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111101;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 8:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
Data=0b11111110;
Data_Gonder();
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
}
set_timer0(99);
}
İlginç bir durum daha var.
Taramaya hangi satırdan başlarsam o satırın parlaklığı diğerlerine göre az oluyor... Bunun sebebi nedir hala çözmekle uğraşıyorum.
CCS benim sabrımı sınıyor sankide..
Çok anlamasamda aklıma geleni yazayım.
Kesme fonksiyonunuzun çalışma süresi kadar bir boşluk ledlerinizde bahsettiğiniz sönüklük ve pır pır ı oluşturuyor olabilir mi?
case x:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif ............... ledler 0
Data=0b11111101;
Data_Gonder(); //...............................led 0 da geçen süreler, fonksiyon dallanmaları dahil...
SDATA[0]=255;
Tpic_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif ................ledler 1
}
Merhaba
Öncede satırlarıda Shift Register ile tarıyordum ama onu iptal ettim. İşlemcinin bir portunu satırları taramak için ayırdım. Sütünlarda ise Tpic6B595 ler var. Şuanda kesmede tek yaptığım işlem sütün bilgilerini yollayıp satırları taramak. Kesme alt programında her kesmeye gittiğinde işlemcinin 1 pinini toggle yapıyorum. Sonra bu pini osiloskopla ölçüyorum. Gelen palsların pozitif uzunluğunu 1,5 - 2 ms ye ayarladığımda hiç titreme kalmıyor. İlginç bir şekilde kesmede tarama bölümleri pasif edip, Sadece bir pini toggle yaptığımda kesme frekansı en az 5 katına çıkıyor. Demekki kesmedeyken seri olarak bilgi gönderme işlemleri çok uzun sürüyorki kesmeyi yavaşlatıyor. Bu sorun olabilir.
Kodlar budur. Sizce bir problem varmı?
#include <18F4550.h>
#device ADC=8 //8 Bit okuma yapılıyor
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT // 48MHZ
#use delay(clock=20000000)
//#include <lcd_driver.c>
//#include <One_Wire.c>
//#include <DS1820.c>
//unsigned int16 Tam_Deger;
//float Sicaklik;
unsigned int8 Data,i,z,x,SDATA[2];
//unsigned int8 S1DATA[2],S2DATA[2],S3DATA[2],S4DATA[2],S5DATA[2],S6DATA[2],S7DATA[2],S8DATA[2];
unsigned int1 y;
unsigned int8 sayac=0;
Void Data_Gonder();
//Tpic6B595 Oin Tanımlamaları
#define Tpic_Data PIN_D2
#define Tpic_Clck PIN_D6
#define Tpic_Ltch PIN_D4
#define Tpic_Enbl PIN_D0
#int_timer0
Void timer0_Kesme()
{
output_toggle(pin_a0);
sayac++;
if(sayac>8)
{
sayac=1;
}
switch (sayac)
{
case 1:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(254);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 2:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(253);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 3:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(251);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 4:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(247);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 5:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(239);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 6:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(223);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 7:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(191);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
case 8:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(127);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
}
}
set_timer0(99);
}
Void Data_Gonder()
{
for (x=0;x<3;x++)// Kaç adet Tipic bağlı
{
z=7;
for (i=0;i<8;i++)
{
y=bit_test(SDATA[x],z);
output_bit(Tpic_Data,y);
output_high(Tpic_Clck);
delay_us(1);
output_low(Tpic_Clck);
z--;
}
}
output_High(Tpic_Ltch);
delay_us(1);
output_Low(Tpic_Ltch);
}
void main(void)
{
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_adc(ADC_OFF);
SETUP_ADC_PORTS(NO_ANALOGS);
setup_spi(false);
setup_timer_0(T0_INTERNAL|T0_DIV_2|T0_8_BIT);
set_timer0(99);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_high(Tpic_enbl);
port_b_pullups(False);
delay_ms(100);
for(;;) //Sonsuz Döngü;
{
SDATA[0]=255;
SDATA[1]=0;
SDATA[2]=0;
}
}
Mesela demiştim ya Ekranı taramaya hangi satırdan başlarsam o satırın parlaklığı düşük oluyordu.
Aşağıda bir resim çektim. Açıkça belli oluyor problem..
(http://s14.postimg.cc/mw0zdu38h/20120822_210904.jpg) (http://postimg.cc/image/ltqsvakf1/full/)
photo upload (http://postimg.cc/)
Yine CCS ile ilgili aklıma takılan bir soruyu sormak istiyorum
#use delay(clock=20000000) şeklinde bir tanımlama ile işlemci çalışma frekansını belirtiyoruz. Peki buraya yazmamız gereken frekans işlemci ana çekirdeğinin çalışma frekansımı yoksa bağlanan kristalin çalışma frekansımı olacak. Örneğin 20 Mhz osc Bağlı fakat bu PLL ile 48 mhz çıkartılıp işlemci çekirdeğine veriliyor.... Ben buraya 48Mhz mi yazmam gerekiyor?
ccs c de örnek program bile derlemedim ancak..
#use delay ..kullandığınız kristalin değerini zaman geciktirmelerinde kullanılmak üzere derleyiciye bildiriyor... Bu durumda kristalinizin değerini yazmanız gerekiyor.
timer0_Kesme() fonksiyonunuz içindeki switch kullanımını main içindeki for( ; ; ) içine alsanız, hatta for içinde bir fonksiyon olarak kullansanız, kesme zamanınızı daha sağlıklı kontrol etme şansı yakalamaz mısınız? Yanlış bilmiyorsam akış, kesme oluştuğunda alt fonksiyondan çıkmadan kesme fonksiyonunuza dallanmayacaktır.
Sonuçta (kesmenizin süresi) + (kesme fonksiyonunuzun içindeki kodlarınızın işlenme süresi) kontrolsüzlüğünden çıkmış olursunuz.
pice donanımsal olarak taktığmız osilatör değerini girmeliyiz.120 tane 595 sürmem gerekti kendi 595 programımı yazım sonra yavaş çalıştığını gördüm ve ccs c nin kendi kütüphanesindekinde bulunan #include <74595.c> kullandım ve kat kat daha hızlı çalıştı gördüm.aynı kütüphaneyi tpic595 içinde kullanabililirsin bence bi dene
Evet onuda bir deniyeyim.
Kesme sorunu vs onları bir şekilde hallederim. Aslında bu sorunlar bir yandanda bana tecrübe kazandırıyor. Daha C dilinde dünkü çoçuğum... :o
Alıntı yapılan: a_a_sezen - 23 Ağustos 2012, 16:16:55
ccs c de örnek program bile derlemedim ancak..
#use delay ..kullandığınız kristalin değerini zaman geciktirmelerinde kullanılmak üzere derleyiciye bildiriyor... Bu durumda kristalinizin değerini yazmanız gerekiyor.
timer0_Kesme() fonksiyonunuz içindeki switch kullanımını main içindeki for( ; ; ) içine alsanız, hatta for içinde bir fonksiyon olarak kullansanız, kesme zamanınızı daha sağlıklı kontrol etme şansı yakalamaz mısınız? Yanlış bilmiyorsam akış, kesme oluştuğunda alt fonksiyondan çıkmadan kesme fonksiyonunuza dallanmayacaktır.
Sonuçta (kesmenizin süresi) + (kesme fonksiyonunuzun içindeki kodlarınızın işlenme süresi) kontrolsüzlüğünden çıkmış olursunuz.
Tarama işlemini kesme içerisinde yapmak zorundayım çünkü ana programdan bağımsız bir şekilde kesintisiz olması gerekmekte. Ana programda yapmam gereken çok daha önemli işlerim var.
Ekranın yarısının parlaklığının az olmasını çözdüm.
Ancak logic analyser vasıtasıyla sorunu anlayabildim. İlginç bir şekilde kesme içerisinde sanki birdaha kesme oluşması gibi bana bir algı bıraktı.
Kesme alt programı bu şekilde
#int_timer0
Void timer0_Kesme()
{
output_toggle(pin_a0);
switch (sayac)
{
case 0:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(254);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=1;
}
case 1:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(253);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=2;
}
case 2:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(251);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=3;
}
case 3:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(247);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=4;
}
case 4:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(239);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=5;
}
case 5:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(223);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=6;
}
case 6:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(191);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=7;
}
case 7:
{
Output_high(Tpic_Enbl); //tpic6B595 Çıkışlar Pasif
output_b(127);
Data_Gonder();
Output_low(Tpic_Enbl); //tpic6B595 Çıkışlar Aktif
sayac=0;
}
}
set_timer0(99);
}
Basicde kesme içerisinde tekrar kesme oluşmamasıiçin kesme etiketinden önce kesmeleri kapatıyorduk. Acaba CCS de demi bu durum geçerli yoksa kendisi yapıyormu? Belkide bu sebebten dolayı kesme tutarsız çalışıyor
----------------------------------------
Ayrıca ufak bir sorumdaha olacak. Dikkate alırsanız sevinirim.
Bir değişkenin herhangi bir bitine başka bir 1 bit boyutundaki değişkeni yazmak istiyorum.
Örnek vereyim.
unsigned int8 data;
unsigned int1 y;
bu şekilde iki adet değişkenimiz olsun
Data değişkenin herhangi bir bitine y değişkenini yazmak istiyorum. Y bir ise data değişkenin ilgili biti 1 değilse 0 olacak.
Bu konuda bana bi ipucu verebilirmisiniz
Mucit23
bu kodu incele işini görmesi gerekir.
unsigned int8 data=1,i,temp;
int1 y=1;
// datanin kacinci bitine yazmak istiyorsak i ona esitleyelim
// data degiskenin 5 ci bitine y yi yazalim
temp=0x01;
for(i=5;i>0;i--)temp<<=1;
if(y) data|=temp;r
else data&=~temp;
Sadogan Teşekkür ederim...
Ufak bir problemin daha var
CCS de mod almaya çalışıyorum
Onda=Sicaklik%10;
Bu şekilde bir kullanıma izin vermiyor. Doğrusu nasıl olmalı
Edit;
Çözdüm arkadaşlar. Değişken tipine hata veriyormuş..
Merhaba Arkadaşlar
Basicde menü yapmak kolay. Menü içerisinde döngüler oluşturuyorum. Program neredeyse orada dönüyor. C de durum nasıl. Bugün birkaç menü yapmaya çalışacağım.
Mesela Bir butona basınca alt bir fonksiyona yönelip orada işlemciyi döngüye sokup döngü içerisinde menü işlemlerini yapabiliyorum. Sanırım bunun bir zararı olmuyor fakat menüden çıkmak istediğimde o sonsuz döngüden nasıl sıyrılacağımı bilmiyorum. Yine if ile başka bir fonksiyonamı atlanır.
Bana Basicdeki mantığın C deki karşılığını anlatacak olan varmı? c'de program yazarken basic mantığından arınmak istiyorum..
'break' deyimi butun dongulerden cikmaya yarar.
Merhaba,
C de döngüden herhangi bir anda çıkmak, döngüyü kırmak için break komutunu kullanabilirsin. Etiket belirleyip goto komutuyla da atlama yapılabilir. Menü içinse alt bir fonksiyon oluşturup şart sağlanırsa o fonksiyonu çağırırsın.Bu durumda fonksiyon işlenir ve bitince program kaldıgı yerden devam eder.
void alt(){
.......
}
main(){
.........
if(sart) alt();
........
}
Anladım.
Ozaman break komutu döngünün dışına çıkarıyor. Şart ne olursa olsun. Bir iki deneme yapalım bakalım. Mantığını anlamaya başladım.
mesaj birleştirme:: 22 Aralık 2012, 20:34:50
Bir sorum daha olacak
LCD de özel karakter tanımlaması yapmaya çalışıyorum. Benim gibi daha önce çok fazla kişi sormuş Herkezde iyi kötü cevap bulmuş.
Benim kullandığım kütüphane aşağıdaki gibi
//Buradaki ayar bendeki Deneme Kartina göredir, istenilirse baska Pinlere cevrilebilinir.
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#define LCD_E PIN_B3
#define LCD_RS PIN_B2
//#define LCD_RW PIN_B6 //Bendeki Deneme Kartinda LC_RW PIC'in GND Pinine bagli.Bu nedenle bu satiri iptal ediyoruz...
//#define USE_LCD_RW 1 // Ayni sebepden bu satirida iptal ediyoruz !!
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
Kütüphaneyi değiştirmeden lcd hafızasına nasıl karakterler yerleştirip kullanırım.
Bir sorum daha olacak. Bunu öğrenmem gerekiyor.
bir fonksiyona string göndermeye çalışıyorum
Şöyle bir fonksiyon tanımladım.
lcd_yaz(char c)
{
printf(lcd_putc,c);
}
Ben bu fonksiyona lcd_yaz("ali ayşe memet"); şeklinde gönderme yaptımmı aynı stringin içerideki fonksiyona ulaşmasını sağlamam lazım. Amacım fazla printf fonksiyonu kullanmamak.
Derlemeye çalıştığımda şöyle bir hata alıyorum..
(http://s8.postimg.cc/j13fc7hid/Ekran_Al_nt_s.png) (http://postimg.cc/)
picture sharing (http://postimg.cc/)
Bunu nasıl yaparım. Nerde Hata yapıyorum.
eger lcd_yaz fonksiyonu herhangi bir deger dondermiyorsa (ki oyle olmasi gerek)
void lcd_yaz(char c)
{
printf(lcd_putc,c);
}
olmasi gerek.
Not:en onemli detay ise fonksiyonu cagirmadan once tanimlamalisin veya fonksiyonu tanimlamadan once cagirmak zorundaysan once prototip olarak tanimlamak zorundasin.Yani
programin ust kismina
void lcd_yaz(char c);
tanimlamasini yapman gerek.
Aslında hocam fonksiyona hata vermiyor. Fonksiyonu çağırdığım zaman resimdeki hatayı alıyorum.
lcd_yaz("Merhaba"); Şeklinde kullanıyorum. acaba kullanım hatasımı yapıyorum.
Birde değişken türü ile ilgili olabilirmi ?
evet kullanim hatasi fonksiyon tanimini char olarak tanimlamissin ama cagirirken string deger vermissin.
lcd_yaz('M');
olarak verebilirsin.
pek hocam string göndermek için ne yapmak gerekir
https://www.picproje.org/index.php?topic=26465.5; (https://www.picproje.org/index.php?topic=26465.5;)
char deneme[]={"MERHABA"};
void lcd_yaz(char* c)
{
printf(lcd_putc,c);
}
lcd_yaz(&deneme);
dersen olmasi gerek.
Yok hocam buda işe yaramadı. Dediklerinizi harfiyen uyguladım..
hata mi veriyo ki?
void lcd_yaz(char * s)
{
while(*s)
printf(lcd_putc,*s++);
}
lcd_yaz("aasasd");
Bu şekilde çalışması lazım.
Alıntı yapılan: justice_for_all - 22 Aralık 2012, 23:55:33
hata mi veriyo ki?
Hocam yazım hatası yapmışım. Düzeltince oldu ama char deneme isimli değişkeni global tanımlayamıyorum. Ozaman hata alıyorum.
Alıntı yapılan: kantirici - 22 Aralık 2012, 23:59:19
void lcd_yaz(char * s)
{
while(*s)
printf(lcd_putc,*s++);
}
lcd_yaz("aasasd");
Bu şekilde çalışması lazım.
Bunuda bir deneyelim
Edit; Kantirici denedim fakat olmadı
lcd_yaz("aasasd"); Bu şekilde kabul etmiyor.
char deneme[]="deneme";
lcd_yaz(deneme);
Böyle yapınca oluyor fakat ekrana yazmıyor. Sanırım While düzgün çalışmıyor burada..
fonksiyon disinda tanimladigin zaman global olur zaten.tabi yine kendi icinde global olur baska dosyalarda bu degiskeni kullanamazsin demek istedigin buysa.
Bu şekilde denermisin.
void lcd_yaz(const char * s)
{
while(*s)
printf(lcd_putc,*s++);
}
lcd_yaz("aasasd");
Kafayı yedirtecek bu ccs bana... >:(
cpp de ne güzel istediğim gibi istediğim yere string gönderiyordum. Bu nekadar sıkıntılıymış.
@justice_for_all,
az önce ne yaptıysam oldu. şimdi aynısını tekrar yazıyorum kabul ediyor fakat görüntü ekrana gelmiyor...
@Kantirici :) :)
Hocam sizin hiçbir yöntem işe yaramadı.
Bence while(*s) burada çalışmıyor. lcd_yaz("aasasd"); Bu şekilde bir kullanımı hiçbir şekilde kabullenemiyor ccs
benim yaptigim fonksiyonda
lcd_yaz("deneme");
olarak deneyin bide.
Oldu çok şükür.
Hocam yine benden kaynaklı bir problem. Değişkeni global olarak char deneme[]=""; şeklinde tanımlıyordum
Başka yerlerde değer vermek istediğimde yine aynı şekilde string yüklüyordum. sadece deneme="merhaba"; demek yeterliymiş.
Teşekkürler
@Kantirici, Sanada Teşekkür ederim ilgin için.
Arkadaşlar LCD özel Karakter meselesini çözemedim henüz.
LCD nin Gram Hafızasına data yazıp onları kullanmam için sırayla ne yapmalıyım.
Özel Karakter işini hallettim.
C yapısı hakkında birşey sormak istiyorum
Diyelim iki adet menü fonksiyonu var bu fonksiyonlarda menü kodlarımı çalıştırıyorum.
void menu1()
while(true)
{
.
.
.
}
void menu2()
while(true)
{
.
.
.
}
Şeklinde..
Diyelim bir butona bastığım zaman diğer menü fonksiyonuna geçmek istiyorum. Benim yaptığım işlem butona basılınca diğer fonksiyonu çarğımak . İşlemci zaten 2. fonksiyonda döngüye girip çıkamıyor. Ayı şekilde 2 menüdende ana main fonksiyonuna dallanmak istiyorum.
Şimdi ben 2 menüden ana program döngüsüne gitmem için ne yapmam gerekir. Ana program döngüsü üstüne bir etiket koyup goto ile orayamı gideyim.
Bir diğer aklıma takılan ise stack taşması. Diyelim bu şekilde fonksiyondan fonksiyona atladım. İşlemcide stack taşması meydana gelmezmi
Menü için "CASE" yapısı daha uygun.
char ButonDeger=0;
void main(void)
....
....
....
{
while(1)
{
if(Buton)
{
ButonDeger+;
if(ButonDeger==1){ menu1();}
if(ButonDeger==2){ menu2();}
if(ButonDeger<=3){ ButonDeger=0;}
} // if buton sonu
} // while sonu
void menu1()
{
}
void menu2()
{
}
Bir başka örnek
Kod çalışıyor. Kodun bir bolumu yayınlandı. Fikir vermesi acısından.
void main(void)
{
unsigned int i;
PORTC=0x00;
TRISC=0x00; // PORTC çıkıs
PORTB=0x00;
TRISB=0x00; // GLCD için çıkıs
ADCON1=0x06;
TRISA=0xFF;
PORTA=0x00;
OK=1;
Azalt=1;
Artir=1;
nokia_init();
init_DS1302();
while(1)
{
Tarihgoster();
Saatgoster();
nokia_gotoxy(2,0);
nokia_printchar("Saat");
nokia_gotoxy(36,0);
nokia_printchar(time);
nokia_gotoxy(2,1);
nokia_printchar("Tarih");
if(OK==1) // menuye girme kismi
{
Menu();
}
DelayMs(500);
DelayMs(500);
DelayMs(500);
DelayMs(500);
}
}
void Menu(void)
{
unsigned char ayar1,ayar2;
unsigned char menuCikis=1;
ayar1=1;
ayar2=0;
nokia_clean_ddram();
DelayMs(500);
nokia_gotoxy(2,0);
nokia_printchar(" SAAT - TARIH ");
nokia_gotoxy(2,1);
nokia_printchar(" AYARLAMA ");
nokia_gotoxy(2,3);
nokia_printchar(">1.Saat Ayar" );
nokia_gotoxy(2,4);
nokia_printchar(" 2.Tarih Ayar" );
while(menuCikis)
{
if(Azalt==1)
{
nokia_gotoxy(1,4);
nokia_printchar(" ");
nokia_gotoxy(1,3);
nokia_printchar(">");
ayar1=1;
ayar2=0;
}
if(Artir==1)
{
nokia_gotoxy(1,3);
nokia_printchar(" ");
nokia_gotoxy(1,4);
nokia_printchar(">");
ayar2=1;
ayar1=0;
}
if(OK==1)
{
if(ayar1==1) // Saat ayarlama
{
SaatAyar();
DelayMs(500);
DelayMs(250);
menuCikis=0;
}
if(ayar2==1) // Tarih ayarlama
{
TarihAyar();
DelayMs(500);
DelayMs(250);
menuCikis=0;
}
} // OK tus sonu
} // while(menuCikis) Sonu
nokia_clean_ddram(); // Ekrani Temizlemek için kullaniliyor.
} // Menu Fonksiyon sonu
// ******************* Saat Ayar *************************
void SaatAyar(void)
{
unsigned char dakAy=0;
unsigned char saatAy=1;
nokia_clean_ddram();
while(saatAy) // saat ayarlama bölümü
{
nokia_gotoxy(2,0);
nokia_printchar("Saat");
nokia_gotoxy(2,1);
Saatgoster();
if(Artir)
{
DelayMs(250);
DelayMs(250);
saat1++;
if(saat1==10){saat1=0;saat10++;}
if(saat10==2 && saat1==4){saat10=0;saat1=0;}
saat=((saat10<<4)&0xF0) | (saat1&0x0F);
write_DS1302(HOUR,saat); // saat güncellendi
nokia_clean_ddram();nokia_gotoxy(2,1); Saatgoster();while(Artir);
}
if(Azalt)
{
DelayMs(250);
DelayMs(250);
saat1--; // birler hanesini azalt
if(saat10==0 && saat1==255){saat10=2;saat1=3;}
if(saat1==255){saat1=9;saat10--;}
saat=((saat10<<4)&0xF0) | (saat1&0x0F);
write_DS1302(HOUR,saat); // saat güncellendi
nokia_clean_ddram();nokia_gotoxy(2,1);Saatgoster();while(Azalt);
}
if(OK==1)
{
DelayMs(250);
DelayMs(250);
saatAy=0;
dakAy=1;
}
while(dakAy)
{
nokia_gotoxy(2,1);
Saatgoster();
nokia_gotoxy(2,0);
nokia_printchar("Dakka");
if(Artir) // dakika ayarlama bölümü
{
DelayMs(250);
DelayMs(250);
dakika1++; // birler hanesini arttır
if(dakika1==10){dakika1=0;dakika10++;}
if(dakika10==6 && dakika1==0){dakika10=0;dakika1=0;}
dakika=((dakika10<<4)&0xF0) | (dakika1&0x0F);
write_DS1302(MINUTE ,dakika); // dakika güncellendi
nokia_clean_ddram();nokia_gotoxy(2,1); Saatgoster();while(Artir);
}
if(Azalt) // dakika ayarlama bölümü
{
DelayMs(250);
DelayMs(250);
dakika1--; // birler hanesini azalt
if(dakika10==0 && dakika1==255){dakika10=5;dakika1=9;}
if(dakika1==255){dakika1=9;dakika10--;}
dakika=((dakika10<<4)&0xF0) | (dakika1&0x0F);
write_DS1302(MINUTE ,dakika); // dakika güncellendi
nokia_clean_ddram();nokia_gotoxy(2,1);Saatgoster();while(Azalt);
}
if(OK==1)
{
DelayMs(250);
DelayMs(250);
saatAy=0;
dakAy=0;
}
} // while(dakAy) Sonu
} // while(SaatAy) Sonu
}
Mucit23 umarım işini görür.
Mantığını anladım. Burada program farklı yerlerde dönmüyor. Hep Main programı içerisinde çalışıyor ama menü aktif iken menü kodları işletiliyor.
edit:
Fakat biraz düşününce pek mantıklı gelmiyor bu bana. Çok dallı budaklı bir menü yaparsak herşey birbirine girer. Çok karmaşık olur. Çok karmaşık menülerde nasıl bir yol izlenmeli
Selam,
Co operative multitask,multitask,statemachine gibi program akışını istediğiniz şekilde yönlendiren
tasarımlar var onları inceleyin,bu konuların mantığını çözdüğünüzde o dediğinizi çok kolay yaparsınız.
Menü işini kavradım. Yalnız multi task olayını pek anlayamadım. O konuya tekrar bakacam.
Bi matematiksel problemim var.
adc_x=(read_adc()*220);
lcd_gotoxy(1,2);
printf(lcd_putc,"R=%ld",adc_x);
adc_x değerini unsigned int32 olarak tanımlamışım. Kodu çalıştırdığımda ADC değeri 1023 iken ekranda 28452 değerini görüyorum. Burada yaptığım işlem ADC değerini 220 ile çarpmak. Normalde 225060 çıkması gerekir. Neden böyle bir sonuçla karşılaşıyorum. Acaba 16F serisinde bu tür yüksek boyutlu işlemler yapılamıyormu?
read_adc() fonksiyonu muhtemelen 16 bit döndürüyordur, cast etmeniz lazım.
Hocam anlayamadım "cast" terimi nedir? Ne yapmam gerekiyor.
220'nin başına (int32) eklemeyi deneyin:
adc_x=(read_adc() * (int32)220);
https://www.picproje.org/index.php/topic,26367.msg248222.html#msg248222 (https://www.picproje.org/index.php/topic,26367.msg248222.html#msg248222)
Evet dediğiniz gibi yapınca sorun çözüldü. Teşekkür ederim.
Arkadaşlar Merhaba
CCS de usart ile bilgisayardan data almaya çalışıyorum. Usar kesmesi kullandım. Haberleşme hızım 19200, Programımı yazdım denemelerimi yapıyorum fakat bir terslik var.
Bilgisayardan her data geldinğinde işlemci resetleniyor. Bazen donuyor. Bazen ise düzgün bir şekilde alıyor.
Yazdığım program şudur.
#include <16F877A.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=8000000)
#include <lcd_driver.c>
#use rs232 (baud=19200, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
char rx_data="-";
#int_rda // RX ucuna veri gelince meydane gelen kesme
void usart_kesme ()
{
disable_interrupts(int_rda); // int_rda kesmesini pasif yap
rx_data=getc();
enable_interrupts(int_rda);
}
void main()
{
set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x80);
set_tris_d(0x00);
set_tris_e(0x00);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_e(0x00);
setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
enable_interrupts(GLOBAL);
enable_interrupts(int_rda);
lcd_init();
delay_ms(100);
printf(lcd_putc,"\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Xbee Denemesi");
while(true)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"Gelen Data=%c",rx_data);
if(rx_data=='A')
{
output_high(pin_b0);
}
if(rx_data=='B')
{
output_low(pin_b0);
}
}
}
Tahminimce kesme gelince işlemciye birşeyler oluyor. Sorun nerde olabilir.
#use rs232 (baud=19200, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1,ERRORS)
bide boyle denermisin.
evet hocam biraz düzeldi. Çok nadir oluyor. Mesela çık hızlı datalar gönderirsem ekran bazen saçmalıyor. Ama eskisi gibi olmuyor artık.
CCS de pwm modülünü set ediyorum. 4Mhz de 250Hz olarak ayarladım. Herşey güzel pwm çıkıyor ama normalde ben pwm duty registelerine 0-1000 arası bir değer yazabilmem gerekir.
Ama set_pwm1_duty fonksiyonuna 124 değerini yüklediğimde duty değeri %100e ulaşmış oluyor.
CCS neden böyle yapıyor?
Normalde ben direk registerlere(CCP1_CON, CCP1L, PR2 vs...) değer vererek yapmak isterim bu işi. Bunu bu şekilde direk registere nasıl ulaşırım ccs de?
#byte blabla = 0x00ff
istediğin registera ulaşman için register 8 bit ise #byte 16 bit ise #word atadoğın isim = register maptaki adres
Hocam anladım. Istediğim registerin adresine nerden ulaşırım
datasheetten register map yazın hocam o listede var
CCP1CON.4=ham_DUTY.0
CCP1CON.5=HAM_DUTY.1
CCPR1L=HAM_DUTY>>2
Basicde yaptığım bu işlemin aynısını C de nasıl yaparım
valla hocam kendi tanımladığınız bir sayının 1. bitini nasıl alıyorsunuz bilmiyorum ama değişkeni pointer olarak tanımlarsanız olur heralde diğer kısma gelirsek;
#bit hambit1 = CCP1CON.4 şeklinde
@Mucit23 hocam CCS C'de işlemler genelde built-in fonksiyonlarla yapılıyor. Siz ne yapmak istediğinizi yazın, ona göre anlatalım...
Bit düzeyinde işlemleri de genelde lojik olarak yapacaksınız. Bit düzeyinde işlem yapmak çok zor değil.
Hocam yapılan işlem basit aslında
Basicde duty registerinin değerini bunlarla belirliyorum.
CCP1CON.4=ham_DUTY.0
CCP1CON.5=HAM_DUTY.1
CCPR1L=HAM_DUTY>>2
Yapılan işlem basit aslında
Ham_Duty değişkeninin 0. bitini CCP1CON registerinin 4. bitine, Ham_Duty Değişkeninin 1. Bitininde CCP1CON registerinin 5. Bitine yazmak istiyorum. Tabi CCP1CON registerinin diğer bitlerini bozmayacam.
Hamduty Değerişkeninin geri kalan 2-7. bitinide 2 bit sağa kaydırıp CCPR1L ye yazmam gerekiyor. Bu kolay.
PWM için bitleri tek tek ayarlamanıza gerek olmayacak. Doğrudan duty değerini yükleyebileceksiniz. Diğer işlemleri built-in fonksiyonlar hallediyor. Mesela şurada anlatımlı bir örnek var:
http://ccspic.com/ccs-c-dersleri/ccs-c-dersleri-pwm-uygulamalari.html (http://ccspic.com/ccs-c-dersleri/ccs-c-dersleri-pwm-uygulamalari.html)
Duty ayarlamak için
set_pwm?_duty(DUTY_DEGERI); // ? yerine CCP modülü numarası gelecek
// örneğin:
set_pwm1_duty(97); // CCP1 modülü için PWM duty değerini 97 yapar...
İyi çalışmalar hocam...
Hocam duty ayarlamak ccs nin hazır fonksiyonlarını kullanmak istemiyorum.Normalde pwm duty registerine 10bite yakın bir değer verebiliyorum. Ccs buna müsade etmiyor(yada ben beceremedim ) 127 değerinde duty fullenmis oluyor.Şuan verdiginiz örnekten yola çıkarak pwm duty ayarlayabilyorum .
Bu yüzden bende direk registerlerle oynayarak yapayım dedim. Sadece bir deneme yapmak istiyorum. Yukarıdaki işlem hakkında fikri olan varmı?
Yapmaya çalıştığınız kısmın kodlarını koyarsanız neden 127 değerinde olduğunu söyleyebiliriz. Onu anladıktan sonra istediğiniz şekilde yaparsınız.
Ek: Register'larla doğrudan işlem yapmak için header dosyasını otomatik oluşturma: https://www.picproje.org/index.php/topic,34076.msg238850.html#msg238850 (https://www.picproje.org/index.php/topic,34076.msg238850.html#msg238850)
Hocam Amacım CCS ile 250Hz 10 bitlik çözünürlüğe sahip pwm sinyali almak.
Normalde 250 Hz için Timer2 bölücüsünü 1/16 yapıp Pr2 Registerine 249 Değerini vermemiz gerekir. Öyle yapıyorum zaten ama bu sefer pwm duty değeri pr2+1 de %100 oluyor. 500hz için pr2 ye 124 değerini vermem gerekiyor. Duty değeri ise yine pr2+1 de yani 125 değerinde %100 oluyor..
Ama 250Hz de iken Duty değeri 0-1000 arası değişebilmesi lazım. Basicde bunu yapıyorum. Amacım aynısını CCS de yapmak.. Bu yüzden direk registerlere değer vererek duty ayarlamak istiyorum..
setup_timer_2(T2_DIV_BY_16,249,2);
set_pwm1_duty(125);
PWM ayarlarım böyle. bu şekilde 250 hz %50 duty alıyorum.
set_pwmx_duty, overloaded fonksiyon; yani fonksiyona geçtiğiniz değerin tipine göre farklı işlem görülüyor. Bu durumda, bir set_pwmx_duty(int8 y) fonksiyonu, bir de set_pwmx_duty(int16 y) fonksiyonu mevcut. Siz 8 bit'lik değer geçtiğinizde sadece CCPRxL (8 bit), 16 bit'lik değer geçtiğinizde ise CCPRxL ile birlikte diğer register'dan gelen iki bit de hesaba katılıyor. Değişken değil de yaptığınız gibi sabit değer vermek isterseniz, sabitin 16 bit olduğunu belirtmeniz lazım. 125L ya da 125UL yazdığınızda 16 bit olarak görmesi lazım.
Register'larla da basic'de yaptığınız gibi yapabilirsiniz. Yukarıdaki fonksiyon da başka bir şey yapmıyor :).
Hay Allah razı olsun sizden bunu öğrenmem lazımdı.
Bende diyorum neden hep 8 bit sınırı içinde kalıyor diye.
duty=999;
set_pwm1_duty(duty);
Bu şekilde oldu.
CCS de 32 bit çarpım yapamıyorum.
Amacım ADC değerini 1 arrtırıp 250 ile çarpıp 256 ya bölmek, Bu şekilde 0-1023 arası değişen adc değerini 0-1000 arasına alacağım.
unsigned int16 adc_value;
unsigned int32 ham;
adc_value=read_adc()+1;
ham=(adc_value*250)/256;
Bu değeri ekrana yazdığımda 65535 in üstüne çıkamadığını görüyorum. Problem nedir?
Hocam bildiğiniz gibi kullandığınız PIC 8-bit mimariye sahip. adc_value değeri 16-bit olduğundan işlemleri yazılım emülasyonu ile yapılıyor. Önce 250 ile çarptığınızda değer 16-bit'e sığmıyor dolayısıyla sadece 16-bitlik kısmı alınıyor. Sonra bu değer 256 ile çarpılıyor ve 16-bit -> 32-bit dönüşümü yapılıyor. Bunun için ya iki değeri de 32-bit kullanın, ya da önce bölüp sonra çarpın. Bu durumda taşma olmayacaktır.
ham=(adc_value/256)*250;
Evet Teşekkür ederim sorun çözüldü.
ikisinide 32 bit yaptım
ham=(int32)(adc_value*250)/256;
yada boyle yapabilirsin.
set_adc_channel(0); // RE0/AN5 ucundaki sinyal A/D işlemine tabi tutulacak
delay_ms(20); // Kanal seçiminde sonra bu bekleme süresi verilmelidir
voltaj=0;
bilgi=read_adc(); // ADC sonucu okunuyor ve bilgi değişkenine aktarılıyor
delay_ms(500);
voltaj=(0.0048875855*bilgi)*1000;
amper=(voltaj/83.3)/2.5;
for(i=0;i<4;i++)delay_ms(25);
printf(lcd_putc,"\namper=%f",amper);
simulasyonda sorunsuz çalışıyor gerçekte amp değer sabit duruyor .yardım
Alıntı yapılan: xman - 20 Şubat 2013, 21:30:10
set_adc_channel(0); // RE0/AN5 ucundaki sinyal A/D işlemine tabi tutulacak
delay_ms(20); // Kanal seçiminde sonra bu bekleme süresi verilmelidir
voltaj=0;
bilgi=read_adc(); // ADC sonucu okunuyor ve bilgi değişkenine aktarılıyor
delay_ms(500);
voltaj=(0.0048875855*bilgi)*1000;
amper=(voltaj/83.3)/2.5;
for(i=0;i<4;i++)delay_ms(25);
printf(lcd_putc,"\namper=%f",amper);
simulasyonda sorunsuz çalışıyor gerçekte amp değer sabit duruyor .yardım
Simülasyonda uyarılar penceresine uyarı simgeli herhangi bir mesaj var mı? Hangi MCU kullanıyorsunuz? Frekans kaç ? Daha detaylı bilgi verebilir misiniz?
simulasyon ve ccsc de herhangi hata yok bi tane warning var ccsc de ınterrupts disabled durring call to prevent re-enterancy: (@delay_ms1)
işlemci 16f877a 4mhz
arkadaşlar pekı pwm ile pek bilgim yok
bir ledi veya mosfetlrr sürüecem ledleri mesela yakıp söndürmek istiyorum
yani ledler tam sönmeden bidaha yanmaya başlıyacak
0-100 desek tam yanma ve sönme zamanına ben ledleri
2ile 98 arasında yanıp sönmesini sağlamak istesem?
Doğru anladım mı bilmiyorum fakat bir ledin şiddetini zamanla arttırıp azaltmaksa istediğin, bunu PWM'in
doluluk oranını değiştirerek yapabilirsin. Tabii öncesinde PWM ile ilgili biraz alıştırma yapman gerekebilir.
Arkadaşlar Merhaba..
Göstericilerle başım dertte.
Text Basan bir fonksiyon yazmaya çalışıyorum. Yarım yamalak fonksiyonu yazdım ve yazdığım kadarıylada doğru bir şekilde çalışıyor. Sorunum şudur.
Fonksiyonun içerisine char dizisi gönderemiyorum. Kullandığım yapı bu şekilde
void PutText (unsigned int x, unsigned int y, char *c, int1 fill);
void PutText(unsigned int x, unsigned int y, char *c, int1 fill){
unsigned int a=0,b=0,temp=0;
unsigned int cdata=0;
while (*c!='\0')
{
temp=*c-32;
for(b=0;b<5;b++)
{
cdata=Font1[temp][b];
for(a=0;a<8;a++)
{
PutPixel(x+b,y+a,(cdata>>a) & 0x01);
}
}
*c++;
}
}
Kullanımıda bu şekilde
PutText(0,0,*"Deneme",1);
İsiste yaptığım debug sonucunda Fonksiyonun içerisinde gönderdiğim dizinin gitmiyor. Sorun hakkında yardımınız ihtiyacım var.
Yukarıdaki PutText(0,0,*"Deneme",1); komutunda gönderdiğim "Deneme" şeklindeki char dizisinin başına *göstericisini kullanmasam ccs kabul etmiyor. Ya bunu yapacam Yada * yerine (char) şeklinde gönderdiğim dizinin cinsini belirteceğim. Bunun dışında hata veriyor.
Benim Sadece "Deneme" şeklindeki bir dizi yazmam oraya char şeklinde gitmiyormu?
Diğer bir sorum ise gösterici adresiyle ilgili.
Text basan bir fonksiyon yazdığımızda fonksiyonun içerisine string yerine stringin başlangıç adresini gösteren göstericiyimi göndermek gerekir. Bu şekilde fonksiyon içerisinde gösterici adresi arttırılarak adresteki char değerler alınabilir. Bu yeni aklıma geldi açıkçası dün akşam bayağı bir uğraştım ama bunu denemedim. İncelediğim örneklerde hep yukarıda verdiğim kodlara benzer bir yapı kullanılmış.
Yukarıda yaptığım örnekte nerede hata yapıyorum?
Arkadaşlar olabilecek bütün kombinasyonları yaptım fakat çalıştıramadım. ccs de gosterici yapısını anlayamıyorum. Diger c derleyicilerinden farklı çalıştığını düşünmeye başladım.
Anlamıyorum pointer adresini arttıramıyorum. Bana gostericilerin nasıl çalıştığını anlatırsanız gerçekten sevinirim. Özellikle pointer adresi nasıl artırılır. Char tipindeki gostericiye x inci adresten itibaren nasil nasıl string yüklenir. Bu string sıra ile nasıl alınır. Bunları öğrenmek istiyorum.
İnternette ccs ile ilgili bir dünya kaynak inceledim ama inanin hepsini denedim.
Aynı şekilde const türünde bir bilgi aktarmak istedim bende yapamadım . Konu açmıştım cevaplar c30 ile yapılmış. Bilgigonder("Deneme") şeklinde bir fonksiyon oluşturayım dedim nafile.
Kendisinin puts() fonksiyonu var açık kaynak kodlarını bulamadım.
Yok Bu iş için özel bir program yaptım. Fonksionun içerisine giden değerleri lcd de yazıyorum. Sonuç yok
#include <main.h>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#include <lcd_driver.c>
void puts(char *s);
void main()
{
set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_adc(ADC_OFF);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_spi(SPI_DISABLED);
lcd_init();
delay_Ms(200);
printf(lcd_putc,"\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Pointer_test!");
while(TRUE)
{
puts("ADFRSG");
}
}
void puts(char *s)
{
while(*s!='\0')
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%c",s);
delay_ms(500);
*s++;
}
}
Şöyle bir kod yazdım.
Çalıştırınca A başlayı alfabetik olarak saymaya başlıyor. Anladığım şudur. *s++ komutu ile göstericinin içeriği değiştiriliyor. A dan başlamasının sebebi Gönderdiğim dizinin ilk karakterinin A olması. İlk Harf B olsa B den saymaya başlıyor. Göstericinin içeriği nasıl arttırılır anlamış oldum. Sorun şu ki gösterici adresini artıramıyorum. Belki arttırıyorum ama içeriğini alamıyorum. Buralar tam bir keşmekeş şuanda benim için.
2006 da picproje ekibinin hazırlamış olduğu ccs kitabını inceliyorum. Oradaki anlatım çok güzel fakat anlatılanların doğru dürüst hiçbir tanesini gerçekte uygulayıp sonuç alamadım. Acaba ccs versiyonu ile ilgili bir sıkıntımı var?
Bu konuda tecrübesi olanlar yardımcı olursa çok iyi olur.
Konu dışında
Burada yapmak istediğimi printf ile yapamazmıyım? Amaç şu, dizideki karakterleri sıra ile bana versin. Vallahi başka hiç birşey istemiyorum..
Burada bir çözüm bulmunmuş ben anlamdım.
https://www.picproje.org/index.php?topic=26465.0 (https://www.picproje.org/index.php?topic=26465.0)
mesaj birleştirme:: 14 Temmuz 2013, 18:41:05
Pointeri ters kullanmışın sanki bende c yi tam kavramış değilim.
Pointer adresini artırmak için S++ yazmalısın
Değerini almak için *S kullanmalısın
#include <main.h>
char veri[30];
void Verigonder(char *Metin)
{
char i,*Metin2;
Metin2=Metin;
For (i=0;i<=29;i++)
{
veri[i]=*Metin2;
Metin2++;
}
#asm
nop
#endasm
}
void main()
{char Mdata[30];
strcpy(Mdata,"Deneme");
Verigonder(MData);
while(TRUE)
{
//TODO: User Code
}
}
strcpy ile birşeyler yapılabiliyor.
Aslında sorunu buldum.
Gostericiye bir string yazdığım zaman sadece 1. Karakter yazılıyor. Sebebini bilmiyorum. Ama ccs ye has birşey bu.
Sebebini bilen varmı?
printf(lcd_putc,"%c",s);
delay_ms(500);
*s++;
Burası hatalı, doğrusu
printf(lcd_putc,"%c",*s);
delay_ms(500);
s++;
veya
printf(lcd_putc,"%c",*s++);
delay_ms(500);
olursa çalışabilir. Denemek için bende CCS C kurulu değil.
%c deyince bir karakter yaz demek. String için %s yazmalısın.
Bunların yerine sadece printf(lcd_putc,"%s",s); yazmayı dene.
merhaba hocam. bu c dilindeki pointer olayına ben takmıs durumdayım. kodu aşağıdaki şekilde denermisiniz lütfen.
#include <main.h>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#include <lcd_driver.c>
void puts(char *s);
void main()
{
set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_adc(ADC_OFF);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_spi(SPI_DISABLED);
lcd_init();
delay_Ms(200);
printf(lcd_putc,"\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Pointer_test!");
while(TRUE)
{
puts("ADFRSG");
}
}
void puts(char s)
{
unsigned char *m;
m=&s;
while(s!='\0')
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%c",s);
delay_ms(500);
m++; s=*m;
}
}
hocam kodunuzda *s++ ile, s pointerinin değerini artırıyorsunuz. yani değer 64 ise 65 artıyor, adresi artmıyor. kodunuz büyük ihtimal bundan dolayı çalışmıyor.deneyip sonucu yazarsnaız sevinirim. benim deneme şansım yok şu anda. kolay gelsin.
Senin kodları biraz değiştirdim.
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=20MHz)
//#use fast_io(a)
//#use fast_io(b)
#include <Lcd_Zafzaf.c>
//void putsx(char *s);
void putsx(char s)
{
unsigned char *m;
m=&s;
while(s!='\0')
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%c",s);
delay_ms(500);
m++; s=*m;
}
}
void main()
{
setup_ccp1(CCP_OFF);
// setup_spi(SPI_DISABLED);
lcd_init();
delay_Ms(200);
lcd_Putc("Usb Araniyor");
putsx("Deneme");
while(TRUE)
{
//puts("ADFRSG");
}
}
Proteus da denedim. Ekrana D # e # n # ......... şeklinde lcd ye yazdı.
mesaj birleştirme:: 14 Temmuz 2013, 23:42:16
Nasıl oldu çalıştı const nasıl tanıdı anlamadım.
proteusda lcd ekranında "Deneme" yazısını gördüm
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=20MHz)
#include <Lcd_Zafzaf.c>
void Verigonder(char s)
{
unsigned char *m;
m=&s;
lcd_Putc(*m);
#asm
nop
#endasm
}
void main()
{
setup_ccp1(CCP_OFF);
lcd_init();
delay_Ms(200);
Verigonder("Deneme");
while(TRUE) { }
}
Deneyeyim hocam
Hocam bu kodlar çalıştı.
void Verigonder(char s)
{
unsigned char *m;
m=&s;
lcd_Putc(*m);
#asm
nop
#endasm
}
void main()
{
setup_ccp1(CCP_OFF);
lcd_init();
delay_Ms(200);
Verigonder("Deneme");
while(TRUE) { }
}
Bazı aklıma takılanlar var. Bu şekilde yapınca Diyelim Fonksiyona DENEME Gönderdiğimizi varsayarsak Verigönder fonksiyonu her işleyişinde altı defa çağrılıyor ve her seferinde gönderdiğimiz string'in bir sonraki karakteri gönderiliyor. Örneğin "DENEME" 6 karakterli olduğu için Verigönder("DENEME") fonksiyonunu çağırdığımızda veri gönder fonksiyonda 6 adet döngü oluşuyor. ilk döngüde D harfi fonksiyona gidiyor, sonrakinde E harfi vs.. karakterler bitene kadar döngü oluşuyor.
Bu C'nin genel bir özelliğimi?
Bu şekilde olması benim işime gelmiyor aslında çünkü Ben diyelim gönderdiğimiz string'in Başlangıç adresini aldıktan sonra adresi arttırıp sonraki adreslerdeki karakterleri alamıyorum. Bu benim işime gelmiyor açıkçası. Amacım aslında budur.
Bu dediğim için iki gündür uğraşıyorum. Bunu nasıl yapabilirim?
Yukarıdaki örnekle *m pointeri ile adresini zatten aldık. Burada lcd_Putc fonksiyonu bizim değişkene string bir yapı gibi null değerini görene kadar gönderiyor. *m pointeri tek tel adresini artırıp bir char değişkenine atama yapılabilir. Seri porta göndereceksek tek byt gönderen bir fonksiyon seçmeliyiz.
putc (cdata)
putchar (cdata)
fputc(cdata, stream)
Bu fonksiyonlardan biri bu işi görmesi gerekir.
void Verigonder(char s)
{
unsigned char *m;
m=&s; // Burada s adresini *m pointere gösterdik.
while(*m!=0) // sıfırı bulana kadar dön
{
putc (*m); // seri porta bir byte gönder
m++; //*m pointerin adresini her döngüde bir artırdım.
}
}
Yada bir dizi yi eşleştirip dizi değerlerini tek tek alabilirsin.
while döngüsü kullanmadan
Döngü yerine tek tek kendinde belirleyebilirsin.
char x;
x=*m //x 'D' karekreini alır
m=m+1; // adresini bir artırdım örneğin
x=*m // x 'e' karekterini alır
Arkadaşlar Merhaba
18F452 ile uğraşıyorum. Kesme olarak şuanda timer0 ve timer1 kesmeleri aktif ve çalışıyorlar. Bunların yanı sıra birde RB0 kesmesi lazım fakat bir türlü çalıştıramadım.
Yaptığım ayarlamalar bu şekilde,
enable_interrupts(GLOBAL);
enable_interrupts(INT_ext);
enable_interrupts(INT_timer0);
ext_int_edge(H_TO_L);
timer1 kesmesini ise program içerisinde açıp kapıyorum. Bundada sıkıntı yok. Fakat ne yaptıysam RB0 kesmesini çalıştıramadım. RB0 da buton bağlı ve pin pull-up yapılmış durumda butona bastığımda pin 0 olacak. Ayarladada kesmenin bu anda oluşacağını belirttim. (ext_int_edge(H_TO_L);)
Kesme alt programınıda bu şekilde yaptım
#int_ext
void external_int(){
output_high(pin_b7);
}
Sorun diğer kesmelerdemi anlamak için RB0 kesmesi dışında bütün kesmeleri kapattım. Ama nafile. Butona bastığımda kesme oluşmuyor.
Sorun ne olabilir. RB0 kesmesinin başka gizemli ayarlarımı var?
mesaj birleştirme:: 27 Temmuz 2013, 21:08:27
Kesme fonksiyonu içerisine girdim sorun kesme fonksiyonu ismindenmiş. Fakat giriş işlemi tek seferlik oldu. Kesme flagı temizlenmiyor olsa gerekki kesmeye girdimmi birdaha giremiyorum. Öylece kalıyor.. :-X
böyle yaptım kesme fonksiyonunu
#int_ext
void EXT_isr(){
output_toggle(pin_d7);
clear_interrupt(int_ext1);
}
"Mucit23" hocam b0 kesmesinde aynı sorunu bende yaşadım çözümü#USE FAST_IO (b)
buldum.
@Halil
Port giriş çıkış yönlendirmelerini program başında zaten yapmışım. Bunun dışında bir problem olmalı
Sorun giriş çıkış tanımlamaları yada fonksiyon ismi değil...clear interrupt bile kullanmanıza gerek yok.Dikkat edilmesi gereken şu..
CCS C' de kesme içerisinde doğrudan işlem yapmaktan kaçının.Bir değişken atayın ve başlangıçta sıfır olsun..Kesme oluştuğunda 1 olsun..Main fonksiyonunda değişken 1 ise işlemi yaptırıp değişkeni sıfırlayın.Kesme sıkıntısız çalışacaktır.Örnek bir program yazdım.Kontrol ettim çalışıyor.
//******************************************************************************
//Program Adı :RB0 Kesme uygulaması
//Program Amacı :Butonla RB0 kesmesi yapılır.
//Açıklama :Kesme geldiğinde portb.3 terslenir.
// :
// :
//Programı Yazan :Osman Görkem YOĞURTÇU
//Tarih :11.03.2012
//******************************************************************************
#include <16f628a.h> // İşlemci tanımlama dosyası çağırılıyor.
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOMCLR // Sigorta ayarları
#use delay(clock=20000000) // Gecikme komutlarında kullanılcak frekans belirlenir.
#use fast_io(b) // giiş çıkış işlemleri manuel olarak yapılacak
int kesme=0;
#int_ext // RB0/Int Dış Kesmesi (EXTERNAL)
//__________________________DIŞ KESME FONKSİYONU______________________________
void ext_kesmesi () // Dış kesme fonksiyonu
{
while(input(pin_b0==0)) // Buton kilitleme
{}
kesme=1; // kesme oluştuğunun işaretçisi
}
//__________________________Main Fonksiyonu______________________________
void main () // Main Fonksiyonu
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_b(0b00000001); // portb.0 giriş diğerleri çıkış
enable_interrupts(INT_EXT); // INT_EXT kesmesini aktif yapar.
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver.
ext_int_edge(H_TO_L); // Kesme düşen kenarda gerçekleşir.
for(;;) // Sonsuz döngü
{
if(kesme==1) // kesme oluştu ise
{
output_toggle(pin_b3); // RB3 ü tersle
kesme=0; // yeni kesme oluşması için sıfırlanır.
}
}
}
Birşey Sorayım,
Kesme alt programında şarta bağlı olarak aşağıdaki kodlar çalışıyor.
saat=zaman/60;
dak=zaman%60;
Bu kodları aynı zamanda yine şarta bağlı olarak main programındada çalıştırmak istediğimde programı derlerken ccs bana aşağıdaki uyarıyı veriyor.
(http://s21.postimg.cc/kenuk1zbb/Ekran_Al_nt_s.png) (http://postimg.cc/)
yükle resim (http://postimg.cc/index.php?lang=turkish)
Buna benzer bir hatayı aynı fonksiyonu şarta bağlı olarak hem main döngüsünde hemde kesme içerisinde çalıştırmak istediğimde de alıyorum..
Hocam burada bir hata gözükmüyor. Uyarı vermesi normal. 16-bitlik bir değişkenle bölme işlemi yapıyorsunuz. Kullandığınız mikrodenetleyici çekirdeği 8-bitlik ise 16bit için ALU emülasyonu yapılacak. Yani yazılım birkaç aşamada bölmeyi gerçekleştirecek. Bu esnada kesme gelirse bölme işlemi yarıda kalabilir. Muhtemelen bunu engellemek için böle işlemi esnasında kesmeler kapatılıyor. Assembly çıktısını incelerseniz durumu anlarsınız.
while(input(pin_b0==0)) // Buton kilitleme
{}
Kesme içerisinde şartlı sonsuz bekleme yapılması ne kadar uygun olur. Ana programda yürütülmesi gereken başka şeyler varsa hep beklemede yada kaçtı.
Uyarı vermesindeki asıl sebep şu: Bölme işlemi bir çeşit fonksiyon olarak gerçekleniyor. Benzer bir uyarıyı örneğin bir a() fonksiyonunu hem ana programda hem de kesmede çağırınca da verir. Zaten yine aynı sebepten dolayı yanlış hatırlamıyorsam CCS C, kesme kodu içinde delay kullanmaya izin vermiyordu. Bir fonksiyon çağrılırken, içinde kullanılan tüm değişkenler için derleyicinin kendi oluşturduğu bir yığında (stack) yer açılması gerekir. Anladığım kadarıyla mikrodenetleyiciler için yazılmış derleyiciler fazla karmaşık değil, veya kaynaklar az olduğu için derinlemesine girmek istemiyorlar ve aynı fonksiyon için iki farklı yığın alanı açamıyorlar. Yani kod bir tane, ve bunun iç değişkenlerinin adresleri de derleme anında belirlenmiş, dinamik bir yer ayırma söz konusu değil. Şimdi bu a() fonksiyonunu ana program işlerken, bu sırada bir kesme gelirse o da aynı a() fonksiyonunu çalıştıracak ve aynı değişkenlere erişmeye çalışacaklar. Kesmede çalışan a(), ana programdaki a()'nın durumunu bozacak, kan gövdeyi götürecek... Bu sebeple ana programdaki a() çalışmadan önce kesmeleri kapatıyor, derleyici de bunun uyarısını veriyor.
Zaten yukarıda bahsettiğim sebep yüzünden, düşük seviyeli işlemcilerin derleyicileri recursion'a (fonksiyonların kendi kendilerini çağırması) genelde izin vermezler. Bilgisayardaki C derleyicilerinde (veya daha gelişmiş işlemcilerin, atıyorum STM32 gibi) böyle bir kısıtlama yoktur, fonksiyonun her çağrılışında sanki farklı bir fonksiyonmuş gibi ayrı bir yığın oluşturulur.
Bu arada, XC8 yukarıdaki sorunu, arka planda iki fonksiyon oluşturarak çözüyor. Yani bir a() fonksiyonu hem ana programda hem de kesme içinde çağrılmışsa, bunlar gizlice a_1() ve a_2() gibi iki fonksiyon oluyor. Elbette bu durumda program hafızasında kapladıkları yer de artıyor. Bu özellik istenirse kapatılabiliyor. Belki kızacaksınız bana ama söylemeden geçemeyeceğim: "Yine CCS C, yine bir eksiklik..."
Ekleme: Az önce imla denetimi için Google'da "recursion" diye arattım da, benimle çok tatlı bir şekilde dalga geçti. Siz de bir deneyin.
Alıntı yapılan: Tagli - 30 Temmuz 2013, 20:04:50
Ekleme: Az önce imla denetimi için Google'da "recursion" diye arattım da, benimle çok tatlı bir şekilde dalga geçti. Siz de bir deneyin.
İlginç. Neden böyle ?
Alıntı yapılan: sadogan - 31 Temmuz 2013, 00:20:41
İlginç. Neden böyle ?
http://googlesystem.blogspot.com/2009/07/google-helps-you-understand-recursion.html (http://googlesystem.blogspot.com/2009/07/google-helps-you-understand-recursion.html)
@fatih6761ve @Tagli açıklamalarınız için teşekkür ederim
Ccs ile ilgili birşey daha sorayım. Ccs bünyesinde random sayı üretme fonsiyonu yokmudur? Aralık vereyim random sayı versin.
Alıntı yapılan: Tagli - 30 Temmuz 2013, 20:04:50
Zaten yukarıda bahsettiğim sebep yüzünden, düşük seviyeli işlemcilerin derleyicileri recursion'a (fonksiyonların kendi kendilerini çağırması) genelde izin vermezler. Bilgisayardaki C derleyicilerinde (veya daha gelişmiş işlemcilerin, atıyorum STM32 gibi) böyle bir kısıtlama yoktur, fonksiyonun her çağrılışında sanki farklı bir fonksiyonmuş gibi ayrı bir yığın oluşturulur.
Hocam aynı sorunu dün yaşadım XC8'de fonk. içinden aynı fonk. çağıramadım, benden fonk. kopyasını çağırdım.
Alıntı yapılan: Mucit23 - 31 Temmuz 2013, 00:39:42
@fatih6761ve @Tagli açıklamalarınız için teşekkür ederim
Ccs ile ilgili birşey daha sorayım. Ccs bünyesinde random sayı üretme fonsiyonu yokmudur? Aralık vereyim random sayı versin.
srand() ve rand() fonksiyonları ile yapılabiliyor olması gerekir ama srand()'ın çalışabilmesi için her seferinde farklı bir sayı ile beslemnesi gerekir ki bu zor bir iş. Bilgisayarda bunun için takvim ve saat kullanılır. PIC'te bunun yapılabilmesi için ya harici bir takvim entegresi olacak (DS1307 gibi), ya da program çalışırken rasgele bir zamanda birisi bir butona basarak o anki timer değerini alıp srand ile kullanacak. Aklıma gelen bir diğer yöntem, boşta floating pin varsa bunların değerini okumak ama ne kadar başarılı olacağı tartışılır. İşin özü, her çalışmada aynı seri gelmesi bir sorun yaratmayacaksa srand herhangi bir sayı ile ayarlanabilir, ama her seferinde farklı bir rasgele seri gerekiyorsa srand()'ın benzer bir şekilde farklı bir değerle beslenmesi gerekiyor.
Hocam sistemde saat benzeri bir yapı yok fakat sürekli çalışan 8 ve 16 bitlik timerler var.
Fonksiyona mesela 8 bitlik timerin değerini gondersem nasıl olur ?
Olur olmasına ama şöyle bir sorun var: O kısmın koddaki yeri belli, muhtemelen başlangıç ayarlarının içinde olacak. Yani PIC enerji alınca oraya hep aynı sürede ulaşacak, bu sebeple timer da hep aynı olacak. Bu durumda sabit sayı vermekten bir farkı kalmıyor. Dışarıdan rasgele bir müdahele olması lazım. Mesela PIC çalıştıktan sonra kullanıcı bir butona basacak, timer değeri o zaman okunarak srand()'a verilecek. Veya dediğim gibi, floating pinlere bakılabilir ama pek güvenilir değil bence. Sisteme bağlı sensörler varsa bunlar da kullanılabilir. CCS C'nin forumlarında birisi örnek olarak, PIC'e seri porttan gelen ilk byte ile timer'ın kaydedilmesini önermiş.
Haklısınız sanırım. Kodların çalışma suresi degismeyecegine göre timer de her seferinde aynı olacaktır.
Şuan en mantıklı olanı saat kullanmak. Olmadı timer ile saat yapıp onu gönderirim.
Srand fonksiyonuna bir deger gonderirken özel bir özel bir işlem yapmamız gerekiyormu. Örneğin saat ve tarihi gonderirken
Saat, dakika, saniye, gün, ay, yıl gibi bilgileri üst üste koyup topladıkdan sonra gondersem olurmu?
Bi sorum olacak,
10 bitlik bir verim var ve bu veriyi paralel olarak Pic'in Portlarına aktarmak istiyorum. Düşük 8Bit PortB'ye Gelecek. Sonra kalan 2 bit ise Porta nın 0. ve 1. bitlerine yönlendirilecek.
Bu iş için Basit bir fonksiyon yazıp yönlendirme yapabilirim ama ben makro şeklinde yapılabilirmi onu öğrenmek istiyorum. Bu tür işlemler makro halinde nasıl yapılır?
Kimsenin fikri yokmu?
#define veri_gonder(x) \ output_b(x&0XFF); \ output_c(x>>8) ;
while(TRUE)
{
veri_gonder(0xF0AA);
}
Alıntı yapılan: sadogan - 21 Eylül 2013, 14:55:38
#define veri_gonder(x) \ output_b(x&0XFF); \ output_c(x>>8) ;
while(TRUE)
{
veri_gonder(0xF0AA);
}
Teşekkürler.
Kullanılan işaretlerin anlamları nelerdir.
\ amaç nedir?
(x&0xFF) niçin and işlemi yaptık
(x>>8) sağa doğru 8 defa kaydırnca data sonucu sıfır olmazmı
Bunları anlatan bir kaynak varmı
ccs de nasıl olduysa sol tarafta bulunan Files ve projects tablarını yanlışlıkla kapattım. Şimdi projedeki dosyalara ulaşamıyorum. Tekrar nasıl açabilirim? Bulamadım bir türlü
View mens den files onayla
Merhaba arkadaşlar.
Şöyle bir sorunum var. Timer0 Kesmesi ile sürekli display tarıyorum. 800uS aralıklarla kesme oluşuyor. 0 ile 1000000 arası değişen bir değeri eeproma kaydetmem gerekiyor. Bu iş için 32 bitlik bir değeri 3 parça halinde eeproma yazdım.
void write_counter(int32 counter){
int part0=0,part1=0,part2=0;
part0 = (counter&0x000000FF);
write_eeprom(1,part0);
part1 = (counter&0x0000FF00)>>8;
write_eeprom(2,part1);
part2 = (counter&0x00FF0000)>>16;
write_eeprom(3,part2);
}
Fonksiyon çalışıyor. Fakat şöyle bir sorun var ki yazma işlemi sırasında kesme sekteye uğruyor. Bunuda ekranın titremeye başlamasıyla anlıyorum. Yazma işlemi bittiğinde titremede duruyor. Herhalde eeprom yazması sırasında işlemci kesmeye cevap veremiyor.
Sorum basit aslında bunu olmasını engellemem lazım. Ne kesme sekteye uğrayacak, nede yazma işlemi sekteye uğrayacak. Neler yapabilirim?
yazma esnasında kesmelerin kapatılması gerek diye biliyorum.
EEPROM işlemleri ile kesmelerin bir bağlantısı yok. EEPROM'a yazma devam ederken işlemci başka işler yapabilir, kesmelere de cevap verebilir. Hatta yazma işleminin bitip bitmediğini anlamak için EEPROM kesmesi bile var.
Ancak, ASM seviyesinde, EEPROM'a yazımı başlatabilmek için bir register'a bölünme olmaksızın arka arkaya 2 anahtar değerin yazılması gerekiyor (ASM komutları ile). Bu sırada kesmelerin geçici olarak kapatılması gerekir. Derleyici elbette anahtarı yazma işini kendisi hallediyor ama bu sırada kesmeleri otomatik olarak kapatıyor mu onu bilemem.
Program hafızasına yazımda iş değişiyor tabi. Program hafızasına yazılırken işlemci çalışamaz.
Alıntı yapılan: rree - 22 Eylül 2013, 12:15:30
Kullanılan işaretlerin anlamları nelerdir.
\ amaç nedir?
(x&0xFF) niçin and işlemi yaptık
(x>>8) sağa doğru 8 defa kaydırnca data sonucu sıfır olmazmı
Bunları anlatan bir kaynak varmı
\ amaç nedir?
Makronun sonlanmadığını belirtiyor.
(x&0xFF) niçin and işlemi yaptık --> Ama sonuç x de deyil x in and lenmiş hali ccs nin belirledigi bir değişkende.
(x>>8) sağa doğru 8 defa kaydırnca data sonucu sıfır olmazmı --> x içeriği and den etkilenmediğinden sonuç sıfır olmaz.
Alıntı yapılan: Tagli - 29 Ekim 2013, 08:56:05
EEPROM işlemleri ile kesmelerin bir bağlantısı yok. EEPROM'a yazma devam ederken işlemci başka işler yapabilir, kesmelere de cevap verebilir. Hatta yazma işleminin bitip bitmediğini anlamak için EEPROM kesmesi bile var.
Ancak, ASM seviyesinde, EEPROM'a yazımı başlatabilmek için bir register'a bölünme olmaksızın arka arkaya 2 anahtar değerin yazılması gerekiyor (ASM komutları ile). Bu sırada kesmelerin geçici olarak kapatılması gerekir. Derleyici elbette anahtarı yazma işini kendisi hallediyor ama bu sırada kesmeleri otomatik olarak kapatıyor mu onu bilemem.
Program hafızasına yazımda iş değişiyor tabi. Program hafızasına yazılırken işlemci çalışamaz.
Hocam eğer eeprom yazma işleminin kesmeyle ilgisi yoksa neden bu bahsettiğim sorun olabilir?
Kodun tamamını görmeden yorum yapmak zor. Zaten CCS C bilmiyorum.
write_counter fonksiyonu nereden çağrılıyor? Bunu kesme içinde çağırıyorsan sorun oradan kaynaklanıyor olabilir. CCS C write_eeprom fonksiyonu içinde kendisi otomatik olarak işlemin bitmesini bekliyor mu?
Bahsi geçen uyarı mesajını nette arayınca ccs forumda ilginç açıklamalara ulaşılabiliyor.Bana biraz karışık geldi.
Geçmiş gün açıklamanın birinde "Aynı fonksiyonu birden fazla yer içinde çağırdığında gerçekleşiyor." yada "fonksiyonu ana programda ve alt programda çağırdığında gerçekleşiyor" (kesmelerin kapatılması olayından bahsediyorum)
Kendi programımda da aynı durum var şuan.Ancak çözemedim neyden kaynaklandığını.Asm çıktısına bakıyorum sadece gie bitini 0 1 yaparak değiştiriyor.Bazı kısımlarda btfsc bile var.Bazen printf satırında bazen write_eeprom satırında oluyor.
Ama tam olarak hangi durumda oluyor belirsiz gibi.
Hocam kodun tümünde birşey yok. Ana programda bir if koşuluna bağlı olarak write_counter fonksiyonunu çağırıyorum. Programda hem timer0 hemde timer1 kesmesi çalışıyor. Timer1 kesmeside 100ms aralıklarla oluşacak şekilde ayarlamışım. Bu kesmede problem oluyormu bilmiyorum.
Sanırım eeprom yazma fonksiyonu içerisinde işlemci bekliyor. Bu konuda herhangi bir bilgiye erişemedim ama beklediğini düşünüyorum.
CCS nin hazır fonksiyonlarının içeriğini görebilme imkanımız varmı?
CCS C rehberinden baktım. write_eeprom fonksiyonu kesmeleri kapatıyormuş. Kapanmaması için programa bir ek ayar koymak gerekiyormuş. Şöyle yazmışlar:
Alıntı YapIn order to allow interrupts to occur while using the write operation, use the #DEVICE option WRITE_EEPROM = NOINT. This will allow interrupts to occur while the write_eeprom() operations is polling the done bit to check if the write operations has completed. Can be used as long as no EEPROM operations are performed during an ISR.
Alıntı yapılan: Tagli - 29 Ekim 2013, 20:01:10
CCS C rehberinden baktım. write_eeprom fonksiyonu kesmeleri kapatıyormuş. Kapanmaması için programa bir ek ayar koymak gerekiyormuş. Şöyle yazmışlar:
Gökçe hocam evet bende farkettim. Umarım bu işlemde yazma işlemini sekteye uğratmaz. Deneyeyim şimdi.
Arkadaşlar ufak bir sıkıntım var;
analog girişe bağladığım, pot ile duty cycle ı değiştirerek dc motor hızı ayarlıyorum, lcd ekrandada duty 0-250 arasında yazdırıyorum..
sorum şu; yeni bir değişken atayıp örneğin duty cycle 250 de iken 2000rpm 125 iken 1000rpm yazdırmak istiyorum başaramadım, kodlarım aşağıdaki şekilde..
bir de merak ettiğim, elimde 2000rpm lik bir motor var programda %50 duty de ekranda 1000rpm yazdırmak yanlış mı olur? gerçek devirini nasıl yazdırabilirim?
while(1)
{
duty=read_adc(); //adc değerini atadık
delay_us(20);
output_high(pin_c3); //c3 high (define da olabilir)
output_low(pin_c4); //c4 low motor ileri>>
if(duty>250)
duty=250;
set_pwm1_duty(duty);
printf(lcd_putc,"\fduty=%u"duty); //unsigned %u
delay_ms(50);
}
Hızı ölçmeden bilemezsin. Duty ile rpm arasında sabit doğrusal bir bağıntı yoktur.
Alıntı yapılan: eR2 - 31 Ekim 2013, 17:43:46
gerçek devirini nasıl yazdırabilirim?
Ölçerek yazdırabilirsiniz mesela...
Alıntı yapılan: fatih6761 - 31 Ekim 2013, 23:11:21
Ölçerek yazdırabilirsiniz mesela...
evet, dediğiniz gibi opto transistör ile ölçerek yazdırmayı düşünüyorum
Alıntı yapılan: Tagli - 29 Ekim 2013, 20:01:10
CCS C rehberinden baktım. write_eeprom fonksiyonu kesmeleri kapatıyormuş. Kapanmaması için programa bir ek ayar koymak gerekiyormuş. Şöyle yazmışlar:
Yazmayı unuttum. Bu işe yaradı. Teşekkür ederim. :)
Bir sorum daha olacak.
signed int16 şeklinde bir değişkenim var.
Bu değişkenin Değerinin negatif olup olmadığını öğrenmek istiyorum.
Şöyle birşey yaptım.
if(time_count<0); //Sayı negatif olmuşsa
Çalışmasına çalışıyor fakat bir uyarı veriyor.
Code has no effect
Üstelik Aynı if yapısına else yapısı eklediğimde hata verip derlemiyor
Yöntem yanlışmı acaba?
Satır sonunda noktalı virgül kalmış.
Alıntı yapılan: JKramer - 06 Kasım 2013, 12:49:33
Satır sonunda noktalı virgül kalmış.
Bu işi bırakacağım. :-[ Normalde bu hatayı yapmam ama o noktalı virgülü görmedim.
Merhaba arkadaşlar
CCS C ile ufak bir kod yazdım. Usart ile kızılötesi kumanda mantığıyla haberleşiyorum. Usart'tan gönderdiğim kod direk karşıya gitmesi gerek.
Normalde Basic ile Seri iletişimde iletişim başlangıcında uyandırma sinyali vs gönderebiliyoruz.
Örnek,
SEROUT2 pin,813,[Rep $AA\5, Rep $00\5, Rep $FF\5]
CCS C de bunu nasıl yaparım.
Bir şekilde iletişim kuruyorum fakat sağlıklı değil. Datalar bazen geliyor bazen gelmiyor. Yada farklı istemediğim datalar geliyor. Nasıl çözerim bunu
Sorunu tam anlayamadım. Usart ile IR LED sürüp kızılötesi iletişim mi yapıyorsun? Usart ile seri iletişim yapıyorsunda başta uyandırma bilgisimi gönderiyorsun?
Ayrıca basic için olan kod 5 defa AA v.s mi gönseriyor?
Evet, HPWM ile Yaklaşık 38Khz sabit kare dalga elde edip, bu sinyali Uart'tan çıkan sinyale bindiriyorum. Öylede sinyali IR led'e veriyorum. Karşı tarafta ise alıcı gözün data çıkışını pull-up yapıp işlemcinin RX pinine bağlamışım. IR'Ledin ve Alıcı gözün çalışmasında sıkıntı yok Fakat sanki senkronizasyon mu yakalanamıyor tam anlam veremedim bazen gelen karakterler saçmalıyor. Uyandırma sinyali ile ilgili olabileceğini düşündüm.
Basic kodu hemen hemen dediğin gibi çalışıyor.
Bende vakti zamanında böyle birşey yapmıştım.
karşıda tsop1238 vardı frekansın normalde 38khz'e ayarladığımda 2-2.5 metreden alırken
frekansı 37 küsura ayarlayınca mesafe birden 7-8 mt'ye çıktı,
birede duty oranında iletişimi etkilediğini hatırlıyorum.
biraz kurcalayınca iyi sonuçlar alınıyor.
baudrate kaç? düşük hızda yakın mesafeden dene yine hata yapacakmı bir bakalım. mesela 2400, 4800
Baudrate ilk başta 9600 dü ama sonradan 2400'e düşürdüm. Birazcık hata azaldı. Birazda alıcıdaki mantığı degistirdim. Önceden gelen datayı direk çıkışa veriyordum. Şimdi geken data A ise şunu yap, B ise bunu yap, C ise onu yap diyorum. Böylece hatalı sonuçlardan kurtuldum.
Mesafeyi daha test etmedim ama aynı ortamda çalışıyorlar.. Tahminimce 4-5 metre rahat alır. Mesafenin fazla artacağını da sanmıyorum çünkü ledin artısına pwm uygulayıp ledin eksisinden ise usart datalarını yolluyorum. Yani Led 20 ma den fazla birşey çekemez.
En son CCS nin versiyonunu 5.019'a yükseltmiştim. Fakat olmadık problemlerle karşılaşıyorum. Hiç memnun değilim.
Timer1 ve Timer0 ile devir okumaya çalışıyorum. Timer 0 ile 10ms aralıklarla kesme oluşturmam gerekiyor. Kodumu yazdım, isiste test ediyorum neredeyse 2 sn aralıklarla kesme oluşuyor.
Kodlarda göze çarpan bir problem varmı?
#include <16F877A.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES XT
#use delay(crystal=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
#include <lcd_driver.c>
unsigned int16 devir=0;
unsigned int8 tim_syc=0;
//****************** Timer0 Kesmesi *****************************
#int_timer0 // Timer0 kesmesi
void Timer0_kesmesi () // Kesme fonksiyonu ismi
{
if(tim_syc>100)
{
devir=(get_timer1()/20)*60;
set_timer1(0);
tim_syc=0;
}
output_toggle(pin_d0);
tim_syc++;
set_timer0(99); // TM0 değeri belirleniyor
}
void main()
{
set_tris_a(0x01);
set_tris_b(0x00);
set_tris_c(0x01);
set_tris_d(0x00);
set_tris_e(0x07);
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_e(0x00);
setup_adc(ADC_CLOCK_DIV_32);
setup_adc_ports(AN0);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_OFF);
setup_spi(SPI_DISABLED);
setup_timer_0(T0_INTERNAl | T0_DIV_64 );
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_4,24,1);
enable_interrupts(INT_timer0);
enable_interrupts(GLOBAL);
set_timer0(99);
set_timer1(0);
set_pwm1_duty((unsigned int16)50);
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"Test");
lcd_gotoxy(1,2);
printf(lcd_putc,"Devir=%4ld",devir);
while(TRUE)
{
//TODO: User Code
}
}
göze çarpan hata isis
Bir konuda sıkıntım var.
CCS C de pointer'lerin yapısını bir türlü anlayamadım. C deki pointer yapısını biliyorum ama CCS C bana bu konuda kök söktürüyor.
128x64 Grafik LCD ye Resim basmaya çalışıyorum.
Resim datalarını aşağıdaki gibi bir dizide tutuyorum.
const unsigned char Resim[1024]={
0XFF,0XFF,0X7F,0XBF,0X5F,0XAF,0X57,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,...........................................
Bu diziyi aşağıdaki yazdığım fonksiyona göndermem gerekiyor.
void glcd_write_image(unsigned char img_data[]){
unsigned int Xaxis=0,Yaxis=0;
for(Yaxis=0;Yaxis<8;Yaxis++)
{
for (Xaxis=0;Xaxis<128;Xaxis++)
{
glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);
}
}
}
Yazdığım fonksiyonun kullanım şeklide böyle
glcd_write_image(&Resim);
Derlemede sıkıntı yok ama çalışmıyor kodum. Yani ekranda saçma iki kutucuktan başka birşey görünmüyor. Üstelik aynı yapıyı yine grafik LCD için keilde kullanabiliyorum. Resim basma rutinlerinde sıkıntı yok. Tek sıkıntı diziyi fonksiyona göndermekte.
Geçen sene P10 panellerle uğraşırkende bu konuda çok başım ağrımıştı
Yukarıda yanlış yaptığım birşey varmı. Doğrusu nasıl olmalı bu işin? Bu konuyu acilen çözmem gerekiyor.
Arkadaşlar konuyu hala çözemedim.
Ccs c de fonksiyona dizi gönderemiyorum. Su pointer ların nasıl çalıştığını anlayamıyorum.
String kütüphanelerinin içerisinde her yerde pointer kullanılıyor. Aynı yapıları bile düzgün çalıştıramıyorum. >:(
Bana fonksiyona dizi gonderme ile ilgili bir örnek gösterirmisiniz.
@Mucit23 hocam bu link işinizi görebilir fonksiyonlarla da örnekler ve açıklamalar var.Bir bakın derim ben de bu konuyu anlamadım hala uğraşıyorum.Kolay gelsin.
http://www.kadirga.k12.tr/egitim/c_programlama/ders.php-id=10.htm (http://www.kadirga.k12.tr/egitim/c_programlama/ders.php-id=10.htm)
Aynı şeyler bendeki kitaplardada anlatılıyor. Konuyu biliyorum fakat nedense bir türlü olmuyor. Dedigim gibi bir örnek olsa süper olacak.
Örnek verebilecek kimse yokmu?
glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);
yerine
glcd_write(Yaxis,Xaxis, Resim[((unsigned int16)Yaxis*128)+Xaxis]);
img_data yerine Resim yazarak deneyebilir misin?
Birde tam kod ve isis simülasyonu varsa paylaşırsan bende deneyip yazabilirim,
kodların sadece glcd ile ilgili olan kısımlarıda yeterli olur.
Birde glcd ye resim basmak için glcd_pixel( a,b, ON );
pixel on off komutunu kullanmak gerekebilir,
örnek; https://www.picproje.org/index.php/topic,44032.15.html (https://www.picproje.org/index.php/topic,44032.15.html)
Buradaki mucit23 sen misin hocam?
https://320volt.com/i2c-eeprom-kullanarak-128x64-glcdye-resim-basma/ (https://320volt.com/i2c-eeprom-kullanarak-128x64-glcdye-resim-basma/)
Ben glcd ye resim basma uygulaması yapmıştım ama asm kullanmıştım,
sonuçta pixel on of kullanmak zorunda olduğum için benim yöntem pixel ile yapmaktı.
void glcd_write_image(const unsigned char img_data[]){
veya
void glcd_write_image(const unsigned char* img_data){
yazmayi dener misin.
@Ramu
Evet o linkteki yazıyı yazan benim, Biraz abes bir durum gibi ama ozaman protonla yapıyordum. Protonda zaten pointer meseleleri yok.
Her bir resmi basmak için aşağıdaki kodları kullanıyordum
for(Yaxis=0;Yaxis<8;Yaxis++)
{
for (Xaxis=0;Xaxis<128;Xaxis++)
{
glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);
}
}
Yukarıdaki rutinler çalışıyor. Yani bu kodları mainde çalıştırıp img_data yerine Resim yazsam dizi içerisindeki datalar sorunsuz bir şekilde LCD de görüntüleniyor.
Yani anlayacağınız benim GLCD ye resim basmakta sıkıntım yok. Sıkıntı bu iş için hazırladığım bir fonksiyona boyutu belli bir dizi yollamakta. Bunu beceremiyorum.
@ahmets, Denedim fark eden birşey olmuyor malesef.
Uzun zamandır CCS C kullanmadım, hatırlamıyorum. const yazman diziyi rom'da tanımlamak için değil mi?
http://www.ccsinfo.com/forum/viewtopic.php?t=45132 (http://www.ccsinfo.com/forum/viewtopic.php?t=45132)
Bu adreste rom keyword'ü kullanarak V4.119 için çalışan bir örnek var.
#include <16F1824.h>
#fuses INTRC_IO,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, UART1, ERRORS)
char rom version[] = "PRODUCT ID V1.01";
char rom *ptr;
void display_string(rom *str)
{
printf("%s \r", str);
}
//=====================
void main()
{
ptr = version;
printf("ptr = %lx \r", ptr);
display_string(version);
display_string(ptr);
while(1);
}
Sizin kodları denemedim henüz. Sabah bakayım artık.
Bu arada ben bir iki deneme yaptım.
Biri pointer diğer 3 elemanlı bir dizi olmak üzere iki adet char tipi değişken tanımladım
unsigned char *p;
unsigned char i[3]={25,30,78};
Sonra i dizisinin adresinin p pointerine kopyaladım.
p=(char *)&i;
Sonra P pointerinin değerlerine bakıyorum.
P[0]=25
P[1]=30
P[2]=78
Hiçbir sıkıntı yok.
Ama mesela 1024 elemanlı Resim dizisinin adresini p pointerine kopyalıyorum aynı şekilde
p=(char *)&Resim;
Dizinin içeriği aşağıdaki gibi
const unsigned char Resim[1024]={
0XFF,0XFF,0X7F,0XBF,0X5F,0XAF,0X57,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,........................................
Sonuç olarak yine p pointerinin sırayla değerlerine bakıyorum
p[0]=0x00
p[1]=0x00
p[2]=0x00
p[3]=0x00
.
.
.
Yanlış birşeyler var. Çünkü Resim Dizisinin ilk iki elemanı 0xFF, 3. eleman 0x7F, 4. 0xBF şeklinde gidiyor. İşte burada gelip takılıyorum.
Henüz fonksiyona dizi göndermeye çalışmıyorum bu dediklerimin hepsi main içerisinde gerçekleşiyor. Sadece Resim dizisi ayrıca bir c dosyası içerisinde. Bunuda main programına include etmişim. Çözemedim meseleyi ??? ???
Acaba Resim dizisi Const olmasındamı kaynaklanıyor? Yardım ederseniz sevinirim.
Alıntı YapDerlemede sıkıntı yok ama çalışmıyor kodum. Yani ekranda saçma iki kutucuktan başka birşey görünmüyor.
Hocam şimdi senin kod ccs c de sıkıntısız resim basabiliyor mu basamıyor mu?
Yani bu sorunu çözdün mü?
Birde glcd_write fonksiyonunuda sen yazdın sanırım,
verdiğin kodda bu kısmın nasıl çalıştığını göremiyoruz.
Sorun artık sadece pointer ise
maalesef o konuda benimde kafam karışıyor,
pointer ı tek kullanabildiğim dil asm oldu.
Hocam yok basabiliyorum elbette. Benim resim basmada hiçbir zaman sıkıntım olmadı. O dediğim kutucuklar pointer üzerinden resim basarsam gerçekleşiyor. Resim basma rutinlerinde direk dizi'yi kullanırsam resim basmada problem olmuyor. Zaten glcd_write fonksiyonunuda ben yazdım. Çalışması protondaki glcd write fonksiyonuyla aynı
İçeriği böyle
void glcd_write(unsigned int Ypos, unsigned int Xpos, unsigned int Data)
#ifdef FAST_GLCD
{
int16 temp=(unsigned int16)Ypos*64;
if(Xpos>63)
{
displayData.Right[temp+(Xpos-64)]=Data;
}
else
{
displayData.Left[temp+Xpos]=Data;
}
}
#else
{
output_low(GLCD_DI); // Set for instruction
if(Xpos<64)
{
glcd_writeByte(GLCD_LEFT, Xpos | 0x40); // Set horizontal address to 0
}
else
{
glcd_writeByte(GLCD_RIGHT, Xpos | 0x40); // Set horizontal address to 0
}
glcd_writeByte(GLCD_LEFT, Ypos | 0xB8); // Set page address
glcd_writeByte(GLCD_RIGHT, Ypos | 0xB8);
output_high(GLCD_DI); // Set for data
if(Xpos<64)
{
glcd_writeByte(GLCD_LEFT,Data);
}
else
{
glcd_writeByte(GLCD_RIGHT,Data);
}
}
#endif
Benim şuanda iki problemim var
1-) Uzun boyutlu bir diziyi başka bir pointer'a kopyalamak. (Sanırım temel problem bu)
2-) Fonksiyona dizi göndermek.
Tahminimce 1. sorunu çözersem 2. problemde kendiliğinden çözülecek.
Sizce problem ne olabilir?
Edit;
@ahmets, sizin mesajınızda anlatılan rom yazma yönteminide denedim. Tanımladığım dizileri aşağıdaki gibi yaptım
unsigned char rom *p;
unsigned char rom i[3]={25,30,78};
Değişen birşey yok, i dizisindeki değerleri p pointeri üzerinden alabiliyorum . Aslında problemi buldum.
Bundan önceki mesajımıda 3 elemanlı bir i dizisi tanımlamıştım.
unsigned char i[3]={25,30,78};
Bu dizi bu şekilde MCU'nun Ram'inde yer kaplar. Ama ben başına Const ekleyince (Resim dizisinde olduğu gibi), Dizi program hafızasına gömülür. Ben yukarıdaki i dizisini const türünden tanımlayınca yine 0x00 alıyorum hep. Demekki Resim dizisi const türünden olduğu için bu sorunlar yaşanıyor.
Const dizileri kopyalamakta neden sıkıntı yaşanıyor olabilir. Dizinin program hafızasına yazılması ne gibi bir problem yaratıyor olabilir?
Const dizi tanımlama ile rom keyword'u CCS'de ayni şeyi yapıyor galiba.
Hangi işlemci için kod yazıyorsun?
Bu işlemcide page boyu ne kadar?
Derleyici versiyonun ne?
"Uzun boyutlu bir diziyi başka bir pointer'a kopyalamak" demişsin, ROM'dan ROM'a kopyalamaya çalışıyorsan olmaz. ROM, sadece okunabilir anlamına geliyor, işlemciyi programlarken yazılıyor. Const ile tanımladığın diziyi const olmayan bir diziye kopyalayabilirsin.
Derleyici yapamayacağın bazı şeylere uyarı vermeli. CCS C uyarı vermeyip hatalı kod üretiyor olabilir.
Fazlalıkları çıkararak sadece dizini tanımlayıp adresini kopyalayıp ilk üç değerini yazdırdığın kodu kullan. Bu kod için derleyiciye asm kod ürettirip bak bakalım, dizi için PCLATH değerlerini doğru set ediyor mu? Dizi bir page içinde mi yoksa daha geniş bir alana mı yayılmış ve doğru kullanılıyor mu?
Hocam kullandığım işlemci pic18f4620. CCS versiyonuda galiba 4.140 dı. Aksam tekrar bi bakayım.
Benim yapmaya çalıştığım romdaki değeri yani const olarak tanımadığım diziyi ramde bulunan bur pointer'a kopyalamak. Şuanda geldiğim nokta itibari ile hem dizi hemde pointer ramde tanımlı ise sıkıntı olmuyor. Gerçi ram de tanımadığım dizi 3 elemanlıydı. Derleyici hic uyarı vermiyor. Birde asm çıktısına bakayım. Başka birşeyler olmasi lazim.
Birşey sormak istiyorum.
CCS nin mcu'ların header dosyaları içerisinde aşağıdaki gibi port bit tanımlamaları var
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_A5 45
#define PIN_A6 46
#define PIN_A7 47
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
Buradaki yanda verilen sayısal değerlerin veriliş mantığını bilen varmı. Yapmak istediğim şöyle birşey var. Örneğin SPI ile haberleşen bir çipim var. CS, SCK, DIN,DOUT olmak üzere haberleşmek için 4 pin kullansın.
haberleşme için gerekli olan pinleri aşağıdaki gibi tanımlıyorum.
#define CS PIN_C2
#define DIN PIN_C4
#define DOUT PIN_C5
#define SCK PIN_C3
Benim amacım çipin init edildiği sırada bu tanımlamalara bakılarak kullanılan portun gerekli olan giriş çıkış yönlendirmesini yapayım. Tabi portun diğer bitlerine karışmadan. Yani set_tris_x fonksiyonuna yukarıdaki tanımlamalara bakarak bir değer yazmalıyım. Bu değeri program kendi bulsun. DIN giriş olacak diğerleri çıkış olacak vs..
Bu yüzden port bit tanımlamalarının yanındaki değerleri sordum. Bunu nasıl yaparım?
O değerler datasheette yazan register adresleri olsa gerek. (ccs c bilmiyorum)
Maskeleme yaparak diğer pinlerin etkilenmemesini sağlayabilirsiniz, zaten bu işlerin mantığı maskelemedir. Çünkü 1 bit olarak işlem yapılmaz, minimum 8 bit işlem yapılır.
örneğin:
trisa nın değeri 0b10110000;
siz 1. biti(en sağdakinin bir öncesi olan bit) 1 yapmak istiyosanız
trisa|=0b00000010; yazarsınız
ama 1. biti 0 yapmak istiyorsunuz diyelim
trisa&=~0b00000010; yazarsınız
output_high(48);
output_high(pin_b0);
aynıdır.
set_tris_a (get_tris_A()|0b00000001));//1. bit giriş olarak değiştirildi. diğerlerine dokulunulmadı
set_tris_a (get_tris_A()&0b11111110));//1. bit çıkış olarak değiştirildi. diğerlerine dokulunulmadı
Ömer hocam işte tanımlanan değerlerin mantığını çözemedim.
tamam 48=pin_b0 olsun. output_high() sonuç olarak bir fonksiyon. Bu fonksiyon içerisine 48'gönderirsek b0 lojik1 olacak.
bu değerlerin adres olduğunu sanmam çünkü her bit için ayrı bir tanımlama yapılmış. Portların adresi varda bitlerin adresi yok diye biliyorum.
Aslında şu output_high() fonksiyonunun içini görebilseydim anlardım meseleyi
https://www.picproje.org/index.php/topic,35128.0.html (https://www.picproje.org/index.php/topic,35128.0.html)
Jkramer Yönlendirme için teşekkürler, @Gerbay'e'de açıklama için teşekkürler
Formülü anladım.
ccs forumda bir kod parçası buldum
void My_Output_High(char bitaddress)
{
char byteaddr,bitaddr;
byteaddr = bitaddress >> 3;
bitaddr = bitaddress & 0x07;
bit_set(*byteaddr,bitaddr);
}
Burada yapılan işlemlerde @gerbay'ın anlattıklarını destekliyor.
http://katzen.me.uk/Books/sidssite/PIC/pic16f87x_register_set.pdf (http://katzen.me.uk/Books/sidssite/PIC/pic16f87x_register_set.pdf)
Teşekkürler. Aynı veriler kullandığım mcu'nun Datasheetindede var. ;)
Arkadaşlar merhaba,
Pic16F886'da ADC için Referans girişini aktif etmek istiyorum. Daha önce hiç referans ile uğraşmamıştım. CCS de bunun için aşağıdaki ayarlamaları yaptım.
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_spi(SPI_DISABLED);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0 | VSS_VREF);
Analog giriş ile Referans girişini giriş olarak tanımladım. Amacım ADC nin referans voltajını 2.8V olarak belirlemek. Bunu gelirim bölücü dirençler ile ayarlayacağım.
Daha önce CCS ile Referans girişi kullanan oldumu sıkıntı nedir?
mesaj birleştirme:: 13 Kasım 2014, 00:46:52
Edit;Çözdüm ama gariplik var
benim istediğim 0-VREF arası ölçüm yapmak. Bunun için VREF_VDD şeklinde tanımlama vermek gerekiyor. Bu durumda mantıken düşünürsek -vref ile VDD arasını dönüştürmesi gerekir.
Gerçekten ADCON1 de 5. biti aktif etmek gerekiyor.
5. Bit açıklaması
VCFG1: Voltage Reference bit
1 = VREF- pin
0 = VSS
Buda 4. bit açıklaması
VCFG0: Voltage Reference bit
1 = VREF+ pin
0 = VDD
Ben ilk başta 4. biti 1 yapmıştım.
5.bit 0 olursa zaten vss ye bağlı olur ve normal ölçümü yapması gerek.Olmazsa 5.biti 1 yapıp vref- pinini şaseye bağla o şekilde dene.
Hocam ne ilginçtirki gerçekte olması gerektiği gibi çalışıyor
birde şöyle bir sıkıntı var. Referans voltaj girişine ve ADC girişine pot bağladım. Referans voltajıyla oynayarak değişimleri gözlemliyorum.
Referanstaki voltajı 3.130V yapıyorum. Sonra analog girişteki pot ile oynuyorum. Analog girişteki voltajı yaklaşık 3.002 volta getirdiğimde adc max değerini alıyor. Arada yaklaşık 130mv bir fark var.
Bu konuda yorumu olan varmı?
Selam,
Sizinde bildiğiniz gibi adc çevrim sonucunu şu şekilde hesaplıyor.
AdcDigitalVal = read_adc();
AdcAnalogVal = ( (float)(VREF+ - VREF-) / (float)1023) * AdcDigitalVal;
//Burada (VREF+ - VREF-) bu sonuç işleme ne kadar dogru degerlerle sokulursa sonuçta okadar dogru çıkar. Siz VREF'leri çalışma zamanında dinamik olarak degiştiriyorsunuz anladığım kadarıyla. (VREF+ - VREF-) bu kısmı nasıl degiştiriyorsunuz?.
Esen kalın.
Hocam ben böyle birşey kullanmıyordum aslında.
Doğrudan read_adc() fonksiyonundan gelen değerlere bakıyorum.
Selam,
Anladım aslında siz 0-1023 arasındaki degeri ekranda gösteriyorsunuz. Formule ihtiyacınız yok. (digital deger için). Bu sorun proteus dan kaynaklanabilir.(Eger orada deniyorsanız). Proteus devresi varsa paylaşın belki orda birşey vardır. Anlamak için soruyorum bunu neden deniyorsunuz. Değişken referans biraz garip geldi bana. Eğer öğrenmek amaçlı böyle birşey deniyorsanız şöyle yapın. Oraya trimpot yerine batarya bağlayın ve bir referansa set edip simulasyonu çalıştırın deneyin. Daha sonra referansı degistirip tekrar similasyonu çalıştırın. Çünkü referansın çalışma zamanında değişmesi bana pek doğru gelmedi.
Belki bu yaptıgınız dogrudur ve biryerlerde kullanılıyordur öyleyse sorun proteusdan kaynalabilir.
Esen kalın.
Hocam değişken referansa ihtiyacım yok. :) Gerçekte deneme yapıyorum.
Ben sadece referans girişinin çalışmasını anlamak istedim. Aslında bir sensör var çıkış voltajı max. 2.8V Referansı 2.8V yapıp ölçümü hassaslaştırmak amacım.
Selam,
Şöyle bir deneme yapabilirmisiniz. Hani demiştiniz ya "Referanstaki voltajı 3.130V yapıyorum. Sonra analog girişteki pot ile oynuyorum. Analog girişteki voltajı yaklaşık 3.002 volta getirdiğimde adc max değerini alıyor. Arada yaklaşık 130mv bir fark var. "
Bu sorunun oldugu anda kartın enerjisini kesip tekrar verin(reset değil) ve hiçbir şeye dokunmadan ekrana tekrar bakın. Bir öncesi sorun devam ediyor mu yani aynı degerler mi var yoksa düzeliyor mu. Merak ettim.
Esen kalın.
Hocam yok sorun aynı. Bilmiyorum belki deney kartındanda kaynaklanabilir. Gerçi doğrudan pic bacaklarından gelirim okuyorum. Pek anlam veremedim.
Olçum noltası ile gnd arasına 100nf kondansator baglayıp oyle deneyin birde.
Birşey sorayım
CCS de aşağıdaki gibi bir tanımlama var
#device adc=10
Buradaki sabiti 10 verisem read_adc fonksiyonu 10bitlik bir değer gönderiyor. 16 yaparsam 16 bitlik bir değer gönderiyor. ADC 10 bit olmasıyla birlikte nasıl 16 bit değerleri alıyorum?
10 bitlik değer zaten 2bayt yani 16 bit.
Fakat 1023 maksimum değer oluyor.
16 bit okuduğu zaman gelen maksimum değer bu değil mi? Değilse 65535 olabilir. Bunun anlamı da 6kere sola kaydırma yapılmış demektir.
Selam,
Genel olarak 8bit, 16bit,32bit şeklinde ifadeler kullanılır.
8 bit = 0-255 degeri alır. 2^8.
16bit = 0-6535. 2^16.
Burada değer 8 bitin üzerindeyse 16bit tir. 10bit 1024 değerini temsil ediyor ve 255'den büyük ozaman bunu 16 bitlik değişkende tutabiliriz.
00000000 00000000 Görüldüğü gibi 16 bitlik değişkenin içinde sadece 10 bit alan kullanılıyor. Bunu C dilinde ancak 16bitlik değişken içinde tutabilirsiniz.
Esen kalın.
#device adc=10
sonuc= 00000000 00000000
#device adc=16
sonuc= 00000000 00000000
gibi olması lazım
Selam,
Alıntı yapılan: aliveli - 22 Kasım 2014, 23:41:10
#device adc=10
sonuc= 00000000 00000000
#device adc=16
sonuc= 00000000 00000000
gibi olması lazım
Ben sizin yazdığınızdan şunu anlıyorum. #device adc=16 yazınca değeri sola dayıyor, #device adc=10 yazınca değeri sağa dayıyor.
Ben bu ifadenin adc'nin kaç bitlik olması gerektiğini tanımlamak için yazıldıgını biliyordum. Değeri sola dayamak için ADFM registerini 1 yapmanız gerekir normal şartlarda.
Esen kalın.
Sabah Sabah CCS ye birşeyler oldu. Hiçbir projeyi derleyemiyorum.
Bilgisayarımdan tamamiyle kaldırıp yeniden kurdum fakat düzelmedi.
Yeni bir boş proje oluşturuyorum.
#include <16F877A.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=20000000)
void main()
{
while(TRUE)
{
//TODO: User Code
}
}
Hiçbirşey ile oynamadan compile ettiğimde aşağıdaki hataları alıyorum.
(http://s13.postimg.cc/b00xx95gj/Ekran_Al_nt_s.jpg) (http://postimg.cc/image/b00xx95gj/)
Bütün satırlara hata veriyor. Ne oldu bu programa anlamadım daha önce hiç böyle birşeyle kaşılaşmadım.
Hocam PATH'e CCS nin kütüphane klasörünü eklemeyi dener misiniz?
(Bilgisayar>Özellikler>Gelişmiş Sistem Ayarları>Ortam Değişkenleri>Sistem Değişkenlerindeki Path)
bunun sonuna CCS kütüphane dosyalarının bulunduğu(mesela 16f877a.h dosyası) klasörü ekleyin bakalım olacak mı.
Fatih hocam gerek kalmadı desem umarım bana kızmazsınız.
CCS ara sıra böyle yapıyor. Sebebsiz bir şekilde. 2 defa silip yeniden kurdum patch felan yaptım düzelmedi.
Önceden 4.140 kullanıyordum. Şimdi interneti biraz araştırdım 5.040 çıkmış en son. Arada 6-7 sürüm çıkarmışlar. Bayağı bi geride kalmışım. Bende internetten 5.024 bulup kurdum patch felan yaptım. Şuan bir problem yok gibi.
Alıntı yapılan: Mucit23 - 31 Ocak 2015, 13:19:21
Fatih hocam gerek kalmadı desem umarım bana kızmazsınız.
CCS ara sıra böyle yapıyor. Sebebsiz bir şekilde. 2 defa silip yeniden kurdum patch felan yaptım düzelmedi.
Önceden 4.140 kullanıyordum. Şimdi interneti biraz araştırdım 5.040 çıkmış en son. Arada 6-7 sürüm çıkarmışlar. Bayağı bi geride kalmışım. Bende internetten 5.024 bulup kurdum patch felan yaptım. Şuan bir problem yok gibi.
Kızmak ne demek hocam? :) Sorun çözüldükten sonrası önemli değil. Yeni sürüm önemli tabi :)
Bu CCS 'yi yapan mühendisleri meşeden yapılmış bir sopa ile dövmek lazım. Şu programı bi adam edemediler.
5.019 sürümünü kullanıyorum. Kod tamamlama hala düzgün çalışmıyor. Birde While içerisinde Printf komutu yazıyorum printf içerisine strin girmek isteriz ya string girmek için tırnak("") açtığımda derleyici donuyor. Kod yazarken bunu yapıyor. Bunuda yeni gördüm.
Ayrıca bir projede projenin bulunduğu dizin değişirse proje açılmıyor. Kendimi bildim bileli bu sorun var. Hala düzeltemediler. Ciddi ciddi sopayı hakediyorlar.
Belkide ciddi bir gelir kaynağı olmayınca malum geliştirmeyi bırakmışlardır hocam. :)
ben CCS yerine arduino yu tercih ediyorum.
Geliştiriyorlar fakat beceremiyorlar gibi geliyor bana.. Geliştirmiyor olsalardı sürekli bir sonraki versiyonu çıkmazdı..versiyon Değişiyor fakat kronik sorunlar değişmiyor.
Alıntı yapılan: X-Fi - 15 Eylül 2015, 11:08:28
ben CCS yerine arduino yu tercih ediyorum.
Gayet mantıklı. CCS C ile uğraşılacaksa ardunino daha konforlu.
Arduinoda da kod tamamlama yok. Birde. Atmel işlemcileri bana göre değil. Arduino dışında program yüklemişliğim yok. Bana esneklik sağlamıyor.
Ccs de cod tamamlama için herhangi bir ayarmı var.
Dende bu özelik aktif deyil.
Birgün çok param olursa Notepad++ programını yazan adamları bulup "Kardeşim, şu IDE yazan adamlara bi yardım edin, sizin program onların IDE'sinden daha iyi iş görüyor, alın size istediğiniz kadar para" diyeceğim.
Sublime Text de notepad++ kadar iyi bilginiz olsun :)
microchip icin ccs biçilmiş kaptan proje geliştirme ve esneklik yeterince iyi bu güne kadar büyük bazlı 5 projemde ccs ile çalıştım ve hicbir sorun yaşamadım.yaptıgım projelerde modbus,pwm,akım,rtc encoder gibi bir cok çevresel donamımların altından cok kolayca kalktım.microchip ile ilerlemek isteyenler benim fikrim ccs ile yola devam etmesidir.
hatalarına gelince timer modüllerinde biraz sıkıntıları vardı benim gözlemledigim kadarıyla birden fazla donanımsal modüller kullanıldıgı zaman timer bölme oranları bir kac defa sıkıntı yaratmıstı.timer bolme oranlarını 1 yapararak çözmüştüm.
basit donanım ve güclü tasarımlar icin şiddetle psoc öneririm. şuanda bende denemeler yapmaktayım.herhangi bir proje geliştirmedim.
Bende şimdiye kadar bütün ticari projelerimde CCS kullandım. Dediğiniz gibi oldukça esnek. Ama bu dediğim sorunlarda olmasa tadından yenmeyecek.
Ben 5.025 versiyonunu kullanıyorum,
bahsettiğin problem diğer versiyonlarda benimde başıma gelmişti,
şu ana kadar denediğim bana göre en iyi versiyon 5.025.
Yeni versiyonlarıda vaktim oldukça deniyorum.
İndirme linki Varmı ? Onu yükleyeyim.
pic ile uğraşılacaksa ccs c nin ilerisine gerek yok diye düşünüyorum bende.
Alıntı yapılan: Mucit23 - 15 Eylül 2015, 18:27:01
İndirme linki Varmı ? Onu yükleyeyim.
Aşağıdaki konuyu favorilerime eklemiştim,
CcsC nin yeni versiyonları sürekli güncelleniyor,
konudaki 5.025 e ait mesajın linki:
https://www.picproje.org/index.php/topic,4523.msg400286.html#msg400286 (https://www.picproje.org/index.php/topic,4523.msg400286.html#msg400286)
Alıntı yapılan: frederic - 15 Eylül 2015, 21:19:03
pic ile uğraşılacaksa ccs c nin ilerisine gerek yok diye düşünüyorum bende.
Bende CcsC yi kullanıyorum ama
yetmediği yerler oluyor.
@RaMu Hocam Yetmediği yerler crack olduğundan kaynaklı olabilirmi ?
Alıntı yapılan: RaMu - 15 Eylül 2015, 22:28:46
Bende CcsC yi kullanıyorum ama
yetmediği yerler oluyor.
Mesala nerde Ramu ?
Alıntı yapılan: CORTEX - 15 Eylül 2015, 22:32:19
@RaMu Hocam Yetmediği yerler crack olduğundan kaynaklı olabilirmi ?
Alıntı yapılan: sadogan - 15 Eylül 2015, 22:58:17
Mesala nerde Ramu ?
Hayır,
misal
https://www.picproje.org/index.php/topic,59178.0.html (https://www.picproje.org/index.php/topic,59178.0.html)
bu konudaki gibi, 16F18xx için IOC (Interrupt On Change)
portb nin herbir pininden ayrı ayrı kesme alma özelliği desteklenmemiş halen.
( IOC = herbir pinde RB0 kesmesi var gibi düşünülebilir.)
mesaj birleştirme:: 15 Eylül 2015, 23:04:33
Birde projenin başında kullandığımız,
Project Wizard ın aslında ayrı bir program olarak sunulması lazım,
programı yazmaya başladıktan sonra
misal timer1 ayarlayıp kesme için kurmak istedim,
veya timer0 ın ayarlarını değiştirmek istedim,
veya osilatörü harici-dahili, frekansını değiştirmek istedim,
vs. vs.
bunları manuel yapmak zorunda kalıyoruz,
program ayrı olarak çalışabilse
kodu o program üretir
bizde kopyalar yapıştırırız.
Belkide ayırmış sunmuşlardır, vardır, ama ben rastlamadım.
mesaj birleştirme:: 15 Eylül 2015, 23:09:51
Birde PIC32 yoktur.
+
MPLAB 8 IDE deki gibi güzel bir debugger kısmı yok.
MPLABx i pek kullanmadım aslında onunla kıyaslamak lazım debug kısmını.
Anladım
@RaMu Hocam acaba lisanslarda ne tür farklılıklar olabilir alıp görmek lazım
Selamlar,
Pic18 Serisinde TFT LCD kütüphanemi yapılandırıyorum. Circle fonksiyonunda problem yaşamaktayım.
Daire çizmek için Line Fonksiyonu kullanılıyor
/******************************************************************************
* Çizigi çizme fonksiyonu *
* Parameter: x1, x2, y1, y2 *
* Return: *
******************************************************************************/
void LCD_Line(unsigned int16 x1, unsigned int16 y1, unsigned int16 x2, unsigned int16 y2)
{
signed int32 addx=1, addy=1, P=0;
signed int16 i, dy, dx, diff;
if(x2>x1) {
dx = x2 - x1;
}else{
dx = x1 - x2;
addx = -1;
}
if(y2>y1){
dy = y2 - y1;
}else{
dy = y1 - y2;
addy = -1;
}
if(dx >= dy)
{
dy *= 2;
P = dy - dx;
diff = P - dx;
for(i=0; i<=dx; ++i)
{
LCD_PutPixel(x1, y1, TextColor);
if(P < 0)
{
P += dy;
x1 += addx;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
else
{
dx *= 2;
P = dx - dy;
diff = P - dy;
for(i=0; i<=dy; ++i)
{
LCD_PutPixel(x1, y1,TextColor);
if(P < 0)
{
P += dx;
y1 += addy;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
}
Buda Circle Fonksiyonu
/******************************************************************************
* circle Dravinf function *
* Parameter: x, y, Size *
* Return: *
******************************************************************************/
void LCD_Circle(unsigned int16 x, unsigned int y, unsigned int size, int1 fill)
{
signed int16 a,b,P;
a=0;
b=size;
P=1-size;
do
{
if(fill)
{
LCD_Line(x-a, y+b, x+a, y+b);
LCD_Line(x-a, y-b, x+a, y-b);
LCD_Line(x-b, y+a, x+b, y+a);
LCD_Line(x-b, y-a, x+b, y-a);
}
else
{
LCD_PutPixel(a+x, b+y, TextColor);
LCD_PutPixel(b+x, a+y, TextColor);
LCD_PutPixel(x-a, b+y, TextColor);
LCD_PutPixel(x-b, a+y, TextColor);
LCD_PutPixel(b+x, y-a, TextColor);
LCD_PutPixel(a+x, y-b, TextColor);
LCD_PutPixel(x-a, y-b, TextColor);
LCD_PutPixel(x-b, y-a, TextColor);
}
if(P < 0)
P+= 3 + 2*a++;
else
P+= 5 + 2*(a++ - b--);
}while(a<=b);
}
Kodları STM32 & SSD1289 kütüphanemden aldım. Pic18'de daire çizmek istiyorum ama 45 derece çevrilmiş bir dikdörtgen çiziyor daire yerine. Daire çizmenin mantığı nedir? Neden köşeler yuvarlatılmıyor? Kodlardan birşey çıkartamadım
Int32 int16 veri aktarimlarinda veya islemlerinde
" (Int32)variable " olarak kullanmayi dene
Evet aklıma o durum geldi ama kodlarda da o konuda gözüme çarpan bir yer olmadı. Verilerin hemen hemen hepsi aynı tür