XC8 Başlangıç

Başlatan Mucit23, 04 Mayıs 2014, 01:08:52

Mucit23

Şimdiye kadar pic ile CCS kullanıyordum. XC8 Hiç kullanmadım. Başlangıç için ne yapmam gerekiyor? Bu konuda bir yazı olmasını isterdim açıkçası.

t2

mplabx son versiyon kuruyoruz
xc8 son versiyon kuruyoruz.
sonsivriden ilaç kuruyoruz.

böylece başlamış oluyoruz.

subram

Hocam temel konular için blogdaki yazıları inceleyebilirsiniz. Zaman ayırıp devam edemiyorum. Fırsat bulursam bir ara devam ederim konulara.

http://ramazansubasi.net/
http://www.elektronark.org  Türkiyede Elektronik Kültürünü Değiştirmeye Geliyoruz

Mucit23

Hocam Basit işleri halletsem devam ederim zaten. Mesela Proje dosyası oluşturma, Projeye kütüphane ekleme vs.

Donanım kütüphanelerim yok. Örneğin 2x16 lcd vs.
Altyapım hiç yok.

subram

o zaman blog tam size göre, ilk yazılar başlamanız için gerekli konuları içeriyor.
http://www.elektronark.org  Türkiyede Elektronik Kültürünü Değiştirmeye Geliyoruz

galenga

            @subram hocam ccs c ye başlamak nasip olmadı daha , okul tatile girince başlamayı düşünüyorum ama biraz ufak tefek detaylarla çok uğraşan birisiyim kalktım araştırma yaptım forumda da

okumuştum xc8 iyi gibi bana kısa öneride bulurmusunuz acaba , amacım mikrodenetliyicide donanıma iyice hakim olup sonrasında arm a geçmek ve büyük projelerle uğraşmak ,  sonradan bir daha ondan

buna bundan şuna geçeyim gibi bir durum olsun istemiyorum , bu 1 numara büyüğünü al seneyede giyersin mantığından mı geliyor bilmiyorum ama bir yön gösterirseniz sevinirim .

subram

xc8 için öneride bulunacağım tekşey; Kullanın. Gerisi size kalmış birşey. Yukarıda da yazdım Xc8'e başlamak için temel bilgiler blogumda mevcut, oradan başlayabilirsiniz kullanmak için. Takıldığınız bir yer olursa yardımcı olmaya çalışırım.
http://www.elektronark.org  Türkiyede Elektronik Kültürünü Değiştirmeye Geliyoruz

Gökhan BEKEN

Öncelikle IDE'yi tanıyın, bu adımda netbeans tutorial'leri veya mplabx TV işinizi görecektir: http://www.microchip.com/pagehandler/en-us/family/mplabx/#VideoContent



MPLABX'te yeni bir proje oluşturup, derleyici olarak xc8′i seçip, dilediğiniz bir mcu seçip(bu derste 18F4685 kullandık) kaydediniz.
Projelerimizde kodların karman çorman olmaması için header dosyaları kullanacağız, ve tekrarlanan işlemleri tekrar tekrar yazmamak için fonksiyonel yapılar kullanacağımızı şimdiden belirtelim.

Projemizi açtıktan sonra, Header files kısmından "main.h" adında yeni bir dosya ekleyelim:




Sıradaki yapacağımız işlem ise, configuration bits işlemidir. Daha önceden ezbere bilmiyorsak veya programlayacağımız pic ile ilk defa çalışıyorsak mplabx imdadımıza yetişiyor ve istediğimiz özelliklere göre kod üretiyor. Aşağıdaki adımları takip ederek, configuration bits'leri ayarlayabiliriz.

1- Window menüsünden, PIC Memory Views / Configurations Bits yolunu takip ediyoruz



2-Settings kısmından internal(dahili) osilatörü seçip, WDT'yi disable seçiyoruz. Varsa, başka ayarlarıda seçerek, "Generate Source Code to Output" butonuna tıklıyoruz:


3-Output kısmından üretilen kodları kopyalayıp, main.h dosyamıza yapıştırıyoruz.


4-Aşağıda göreceğiniz üzere 4. satırın altı çizili, bunun sebebi main.c dosyamızda henüz hiç bir kod olmadığı için, dolayısıyla main.h dosyamızı çağırmadığımız için hata vermesidir.


Configuratin bitlerini 2 farklı şekilde yazabiliriz. İster alt alta yazarız, ister yan yana virgül ile ayırarak... Alt alta yazmanın avantajı tek tek açıklama yapabilmemizdir. Yan yana yazmanın avantajı tek satırda bütün konfigürasyonu yapabilmemizdir. Eğer eklediğiniz konfigurasyonun ne işe yaradığını tek tek biliyorsanız ve unutmayacağınıza inanıyorsanız, en iyisi yan yana yazmaktır.

Aşağıdaki tek satırlık kod ile, 3 satırlık kodlar birbirine eştir:


Configuration bits kodlarını da ekledikten sonra kullandığımız pic'in header dosyasınıda çağırmamız gerekiyor. Bunun için

#include <pic18f4685.h>


satırını eklememiz yeterlidir.
Bekleme fonksiyonlarının kaç herz'e göre yapılacağını bildirmemiz gerekmektedir. Çünkü derleyici bizim kullandığımız osilatörün frekansını bilemez. Aşağıdaki tanımlama ile 4000000 hz'lik osilatör kullandığımızı belirtiyoruz.

   
#define _XTAL_FREQ 4000000


Sonuç olarak main.h dosyamızın son hali aşağıdaki gibi olacaktır.

/*
 * File:   main.h
 * Author: M. Gokhan BEKEN
 * [url=http://www.GokhanBeken.com]www.GokhanBeken.com[/url]
 *
 * Created on 14 Aralik 2013 Cumartesi, 21:55
 */
// PIC18F4685 Configuration Bit Settings
#include <pic18f4685.h> //pic 18f4620 seçiliyor
#include <xc.h>
#define _XTAL_FREQ 4000000 //Bekleme fonksiyonlarini 4mhz kristal için ayarlar
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
 
// CONFIG1H
#pragma config OSC = IRCIO67    // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
 
// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = BOHW     // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (VBOR set to 2.1V)
 
// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)
 
// CONFIG3H
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
 
// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config BBSIZ = 1024     // Boot Block Size Select bits (1K words (2K bytes) Boot Block)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
 
// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (00C000-00FFFFh) not code-protected)
#pragma config CP4 = OFF        // Code Protection bit (Block 4 (010000-013FFFh) not code-protected)
#pragma config CP5 = OFF        // Code Protection bit (Block 5 (014000-017FFFh) not code-protected)
 
// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
 
// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (00C000-00FFFFh) not write-protected)
#pragma config WRT4 = OFF       // Write Protection bit (Block 4 (010000-013FFFh) not write-protected)
#pragma config WRT5 = OFF       // Write Protection bit (Block 5 (014000-017FFFh) not write-protected)
 
// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
 
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR4 = OFF      // Table Read Protection bit (Block 4 (010000-013FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR5 = OFF      // Table Read Protection bit (Block 5 (014000-017FFFh) not protected from table reads executed in other blocks)
 
// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)


Yaptığı tek iş bütün ledleri yakmak olan main.c dosyası aşağıdaki gibidir:
#include "main.h"
 
void main(void)
{
    TRISA=0x00; //A PORT'unun bütün pinleri çıkış olsun
    TRISB=0x00; //B PORT'unun bütün pinleri çıkış olsun
    TRISC=0x00; //C PORT'unun bütün pinleri çıkış olsun
    TRISD=0x00; //D PORT'unun bütün pinleri çıkış olsun
    TRISE=0x00; //E PORT'unun bütün pinleri çıkış olsun
 
    LATA=0xFF; //A PORT'unun bütün pinleri HIGH olsun
    LATB=0xFF; //B PORT'unun bütün pinleri HIGH olsun
    LATC=0xFF; //C PORT'unun bütün pinleri HIGH olsun
    LATD=0xFF; //D PORT'unun bütün pinleri HIGH olsun
    LATE=0xFF; //E PORT'unun bütün pinleri HIGH olsun
 
    for(;;); //sonsuz döngü
}


İlk programımızın görüntüsü aşağıdaki gibi olacaktır:


Şimdi TRIS, LAT ve PORT tanımlamalarını inceleyelim.
TRIS: Portların yani pic'in giriş çıkış olarak kullanabildiğimiz pinlerinin, giriş mi yoksa çıkış mı olarak kullanacağımızı belirttiğimiz yazmaçlardır. Giriş olarak kullanacağımız pinlerin tris değeri 1, çıkışların ise 0 dır. TRISA demek A portu ile ilgili tris ayarları demektir. TRISA=0b00001111 der isek; a0,a1,a2 ve a3 pinlerine 1 verdiğimiz için giriş olacak, a4,a5,a6 ve a7 pinleri çıkış olacaktır. Giriş olan pinler buton bağlantıları veya herhangi bir dış tetikleme için kullanılabilir. Çıkış olanları ise led yakma gibi işler için kullanabiliriz.

Diğer pinleri karıştırmadan sadece tek bir pinin tris'ini ayarlamak için aşağıdaki gibi bir kullanım şekli vardır:

TRISAbits.RA0=0; //a0 pini çıkış olsun
TRISAbits.RA1=1; //a1 pini giriş olsun 
TRISBbits.RB0=1; //b0 pini giriş olsun
TRISCbits.RC3=0; //c3 pini çıkış olsun


LAT: Çıkış olarak ayarladığımız pinlerin yönetimi çin kullanılır. LATA=0xFF demek a portunun bütün bitlerini HIGH yap demektir.

Tris'te olduğu gibi bit bit ayarlama şansımız da vardır:

LATAbits.LATA1=1; //a1=high
LATBbits.LATB3=0; //b3=low
LATCbits.LATC5=0; //c5=low
LATDbits.LATD2=1; //d2=high


PORT:  Giriş olarak ayarladığımız pinlerin durumunu öğrenmek için kullanılır genelde ancak tek kullanımı bu değildir. Eski piclerde lat olayı olmadığı için port kullanımı hem çıkış vermek hem de pin okumak içindi. Portlar sanal olarak değil gerçekten okuma yapıyordu. LAT'ın çıkış amacıda bu idi.

programda PORTA=PORTA; derseniz mantıken porta nın değişmemesini beklersiniz ancak portayı önce okuyor sonra direkt porta ya yazdığı için sorun oluyordu. Çünkü bir portu okuduktan hemen sonra yazamazsınız arada çok ufak ta olsa bir zaman gerekir. Bu gibi sorunları aşmak için yazma yapmak için LAT , okuma yazmak için PORT kullanmalıyız. örneğin: LATA=PORTA şeklinde kullanmamız daha verimli olacaktır. Tabiki PORTA=0xFF; gibi bir kullanım hala mevcuttur ancak önerilmez. PORTA nın 3. bitindeki butonun basılı olup olmadığını anlamak için aşağıdaki gibi bir kullanım vardır:

if(PORTAbits.RA0==1)//a0'ın değeri high ise
{
    //yapılacak işlemler
}




EK projeler:
http://gokhanbeken.com/ds1302-projesi-xc8-ve-c18-derleyicileri-icin-tek-program
http://gokhanbeken.com/lcd-kutuphanesic18-ve-xc8-icin
Özel mesaj okumuyorum, lütfen göndermeyin.

Tagli

#include <pic18f4685.h>
Bunu yazmaya gerek yok. xc.h'ı dahil etmek yeterli.

Ayrıca, ben main.h kullanmıyorum. Header dosyaları daha çok bir arayüzü tanımlamak için kullanılır. main dışarıdan erişilip çağrılan bir öğe barındırmadığı için bir header dosyasının olması pek mantıklı gelmiyor. config tanımlamalarını config.c gibi bir dosyada yapıyorum. Aslında iki yaklaşım arasında teknik olarak bir fark yok galiba.
Gökçe Tağlıoğlu

kantirici


sigmoid

Alıntı yapılan: Mucit23 - 04 Mayıs 2014, 01:34:41
Hocam Basit işleri halletsem devam ederim zaten. Mesela Proje dosyası oluşturma, Projeye kütüphane ekleme vs.

Donanım kütüphanelerim yok. Örneğin 2x16 lcd vs.
Altyapım hiç yok.
PIC16 için donanım kütüphanelerini yazıyorum. 8bit modda lcdye erişim tamam. 4 bit mod için düzenlemelere devam ediyorum.

Mucit23

@meftun Teşekkür ederim. Açıkçası böyle bir yazı yazmanı bekliyordum :)

@sigmoid hocam 8 bit ile lcd yi çalıştırdıysanız 4bit ile çalışacak şekilde ben düzenleyebilirim

sigmoid

bitmek üzere, 4 bitte LCDden veri okuma ve geriyede biraz test yapmak kalıyor.

Tagli

Gökçe Tağlıoğlu

Mucit23

ilk proje için çalışmalara başladım. main.h dosyası oluşturdum. main.c de oluşturdum. Şimdi main.c  içerisine main fonksiyonunu ekleyip main.h'ı dahil etmeden derleyebiliyorum ama main.h dosyasını ekleyince aşağıdaki hatayı alıyorum.

main.c:7: error: (141) can't open include file "main.h": No such file or directory

Sanırım main.h dosyasını bulamıyor ama proje ağacında header files altında main.h görünüyor.

main.h'ı başka bir yerdemi tanıtmam gerekiyor. Problem nedir

XC8'in arayüzü açıkçası çok hoşuma gitti. Alışırsam CCS ye bakmam bile. Fakat kullanmayı öğrenmem gerek.
Mesela şunu sorayım.

Bir library ekleyeceğim. Örneğin DS1302 Library'si

DS1302.c ve DS1302.h diye iki adet dosyam var.

Ben Proje ağacında DS1302 diye bir klasör açıp DS1302 ile ilgili dosyaları orada tutmak istiyorum. Yani Bütün library dosyalarını Header files ve Source Files altında toplamak istemiyorum. (Karmaşa olmaması için)

Nasıl yaparım?