baud rate ayarı ccs c canbus kit yardımm:(

Başlatan tufican, 10 Mart 2011, 21:31:40

tufican

merhaba arkadaslar can bus kit aldım simdi kurcalamaya başladım ufaktan frameler gondermeye basladım fakat şu dosyada anlayan birisi bana baud rate ayarının ve hesabını quanta olayının nasıl yapıldıgını anlatabilirmi cok makbule geçer teşekkürler.

bu dosya can baud rate ayarı alt dosyası




#include <can-18xxx8.h>

#if CAN_DO_DEBUG
 #define can_debug printf
#else
 #define can_debug
#endif


//macros
#define can_kbhit()                 (RXB0CON.rxful || RXB1CON.rxful)
#define can_tbe()                   (!TXB0CON.txreq || !TXB1CON.txreq || !TXB2CON.txreq)
#define can_abort()                 (CANCON.abat=1)


////////////////////////////////////////////////////////////////////////
//
// can_init()
//
// Initializes PIC18xxx8 CAN peripheral.  Sets the RX filter and masks so the
// CAN peripheral will receive all incoming IDs.  Configures both RX buffers
// to only accept valid valid messages (as opposed to all messages, or all
// extended message, or all standard messages).  Also sets the tri-state
// setting of B2 to output, and B3 to input (apparently the CAN peripheral
// doesn't keep track of this)
//
// The constants (CAN_USE_RX_DOUBLE_BUFFER, CAN_ENABLE_DRIVE_HIGH,
// CAN_ENABLE_CAN_CAPTURE) are given a default define in the can-18xxx8.h file.
// These default values can be overwritten in the main code, but most
// applications will be fine with these defaults.
//
//////////////////////////////////////////////////////////////////////////////
void can_init(void) {
   can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
   can_set_baud();

   RXB0CON=0;
   RXB0CON.rxm=CAN_RX_VALID;
   RXB0CON.rxb0dben=CAN_USE_RX_DOUBLE_BUFFER;
   RXB1CON=RXB0CON;

   CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
   CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;

   can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 0
   can_set_id(RX0FILTER0, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 0
   can_set_id(RX0FILTER1, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 0

   can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 1
   can_set_id(RX1FILTER2, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 1
   can_set_id(RX1FILTER3, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 1
   can_set_id(RX1FILTER4, 0, CAN_USE_EXTENDED_ID);  //set filter 2 of mask 1
   can_set_id(RX1FILTER5, 0, CAN_USE_EXTENDED_ID);  //set filter 3 of mask 1

   set_tris_b((*0xF93 & 0xFB ) | 0x08);   //b3 is out, b2 is in

   can_set_mode(CAN_OP_NORMAL);
}

////////////////////////////////////////////////////////////////////////
//
// can_set_baud()
//
// Configures the baud rate control registers.  All the defines here
// are defaulted in the can-18xxx8.h file.  These defaults can, and
// probably should, be overwritten in the main code.
//
// Current defaults are set to work with Microchip's MCP250xxx CAN
// Developers Kit if this PIC is running at 20Mhz.
//
////////////////////////////////////////////////////////////////////////
void can_set_baud(void) {
   BRGCON1.brp=CAN_BRG_PRESCALAR;
   BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;

   BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
   BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
   BRGCON2.sam=CAN_BRG_SAM;
   BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;

   BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
   BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
}

void can_set_mode(CAN_OP_MODE mode) {
   CANCON.reqop=mode;
   while( (CANSTAT.opmode) != mode );
}


////////////////////////////////////////////////////////////////////////
//
// can_set_id()
//
// Configures the xxxxEIDL, xxxxEIDH, xxxxSIDL and xxxxSIDH registers to
// configure the defined buffer to use the specified ID
//
//   Paramaters:
//     addr - pointer to first byte of ID register, starting with xxxxEIDL.
//            For example, a pointer to RXM1EIDL
//     id - ID to set buffer to
//     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
//
////////////////////////////////////////////////////////////////////////
void can_set_id(int* addr, int32 id, int1 ext) {
   int *ptr;

   ptr=addr;

   if (ext) {  //extended
      //eidl
      *ptr=make8(id,0); //0:7

      //eidh
      ptr--;
      *ptr=make8(id,1); //8:15

      //sidl
      ptr--;
      *ptr=make8(id,2) & 0x03;   //16:17
      *ptr|=(make8(id,2) << 3) & 0xE0; //18:20
      *ptr|=0x08;


      //sidh
      ptr--;
      *ptr=((make8(id,2) >> 5) & 0x07 ); //21:23
      *ptr|=((make8(id,3) << 3) & 0xF8);//24:28
   }
   else {   //standard
      //eidl
      *ptr=0;

      //eidh
      ptr--;
      *ptr=0;

      //sidl
      ptr--;
      *ptr=(make8(id,0) << 5) & 0xE0;

      //sidh
      ptr--;
      *ptr=(make8(id,0) >> 3) & 0x1F;
      *ptr|=(make8(id,1) << 5) & 0xE0;
   }
}

////////////////////////////////////////////////////////////////////////
//
// can_get_id()
//
// Returns the ID of the specified buffer.  (The opposite of can_set_id())
// This is used after receiving a message, to see which ID sent the message.
//
//   Paramaters:
//     addr - pointer to first byte of ID register, starting with xxxxEIDL.
//            For example, a pointer to RXM1EIDL
//     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
//
//   Returns:
//     The ID of the buffer
//
////////////////////////////////////////////////////////////////////////
int32 can_get_id(int * addr, int1 ext) {
   int32 ret;
   int * ptr;

   ret=0;
   ptr=addr;

   if (ext) {
      ret=*ptr;  //eidl

      ptr--;     //eidh
      ret|=((int32)*ptr << 8);

      ptr--;     //sidl
      ret|=((int32)*ptr & 0x03) << 16;
      ret|=((int32)*ptr & 0xE0) << 13;

      ptr--;     //sidh
      ret|=((int32)*ptr << 21);

   }
   else {
      ptr-=2;    //sidl
      ret=((int32)*ptr & 0xE0) >> 5;

      ptr--;     //sidh
      ret|=((int32)*ptr << 3);
   }

   return(ret);
}

////////////////////////////////////////////////////////////////////////
//
// can_putd()
//
// Puts data on a transmit buffer, at which time the CAN peripheral will
// send when the CAN bus becomes available.
//
//    Paramaters:
//       id - ID to transmit data as
//       data - pointer to data to send
//       len - length of data to send
//       priority - priority of message.  The higher the number, the
//                  sooner the CAN peripheral will send the message.
//                  Numbers 0 through 3 are valid.
//       ext - TRUE to use an extended ID, FALSE if not
//       rtr - TRUE to set the RTR (request) bit in the ID, false if NOT
//
//    Returns:
//       If successful, it will return TRUE
//       If un-successful, will return FALSE
//
////////////////////////////////////////////////////////////////////////
int1 can_putd(int32 id, int * data, int len, int priority, int1 ext, int1 rtr) {
   int i;
   int * txd0;
   int port;

   txd0=&TXRXBaD0;

    // find emtpy transmitter
    //map access bank addresses to empty transmitter
   if (!TXB0CON.txreq) {
      CANCON.win=CAN_WIN_TX0;
      port=0;
   }
   else if (!TXB1CON.txreq) {
      CANCON.win=CAN_WIN_TX1;
      port=1;
   }
   else if (!TXB2CON.txreq) {
      CANCON.win=CAN_WIN_TX2;
      port=2;
   }
   else {
      #if CAN_DO_DEBUG
         can_debug("\r\nCAN_PUTD() FAIL: NO OPEN TX BUFFERS\r\n");
      #endif
      return(0);
   }

   //set priority.
   TXBaCON.txpri=priority;

   //set tx mask
   can_set_id(TXRXBaID, id, ext);

   //set tx data count
   TXBaDLC=len;
   TXBaDLC.rtr=rtr;

    for (i=0; i<len; i++) {
      *txd0=*data;
      txd0++;
      data++;
    }

   //enable transmission
   TXBaCON.txreq=1;

   CANCON.win=CAN_WIN_RX0;

   #if CAN_DO_DEBUG
            can_debug("\r\nCAN_PUTD(): BUFF=%U ID=%LX LEN=%U PRI=%U EXT=%U RTR=%U\r\n", port, id, len, priority, ext, rtr);
            if ((len)&&(!rtr)) {
               data-=len;
               can_debug("  DATA = ");
               for (i=0;i<len;i++) {
                  can_debug("%X ",*data);
                  data++;
               }
               can_debug("\r\n");
            }
   #endif

   return(1);
}

////////////////////////////////////////////////////////////////////////
//
// can_getd()
//
// Gets data from a receive buffer, if the data exists
//
//    Returns:
//      id - ID who sent message
//      data - pointer to array of data
//      len - length of received data
//      stat - structure holding some information (such as which buffer
//             recieved it, ext or standard, etc)
//
//    Returns:
//      Function call returns a TRUE if there was data in a RX buffer, FALSE
//      if there was none.
//
////////////////////////////////////////////////////////////////////////
int1 can_getd(int32 & id, int * data, int & len, struct rx_stat & stat)
{
    int i;
    int * ptr;

    if (RXB0CON.rxful) {
        CANCON.win=CAN_WIN_RX0;
        stat.buffer=0;

        CAN_INT_RXB0IF=0;

        stat.err_ovfl=COMSTAT.rx0ovfl;
        COMSTAT.rx0ovfl=0;

        if (RXB0CON.rxb0dben) {
         stat.filthit=RXB0CON.filthit0;
        }
    }
    else if ( RXB1CON.rxful )
    {
        CANCON.win=CAN_WIN_RX1;
        stat.buffer=1;

        CAN_INT_RXB1IF=0;

        stat.err_ovfl=COMSTAT.rx1ovfl;
        COMSTAT.rx1ovfl=0;

        stat.filthit=RXB1CON.filthit;
    }
    else {
      #if CAN_DO_DEBUG
         can_debug("\r\nFAIL ON CAN_GETD(): NO MESSAGE IN BUFFER\r\n");
      #endif
      return (0);
    }

    len = RXBaDLC.dlc;
    stat.rtr=RXBaDLC.rtr;

    stat.ext=TXRXBaSIDL.ext;
    id=can_get_id(TXRXBaID,stat.ext);

    ptr = &TXRXBaD0;
    for ( i = 0; i < len; i++ ) {
        *data = *ptr;
        data++;
        ptr++;
    }

    // return to default addressing
    CANCON.win=CAN_WIN_RX0;

    stat.inv=CAN_INT_IRXIF;
    CAN_INT_IRXIF = 0;

    if (stat.buffer) {
      RXB1CON.rxful=0;
    }
    else {
      RXB0CON.rxful=0;
    }

    #if CAN_DO_DEBUG
       can_debug("\r\nCAN_GETD(): BUFF=%U ID=%LX LEN=%U OVF=%U ", stat.buffer, id, len, stat.err_ovfl);
       can_debug("FILT=%U RTR=%U EXT=%U INV=%U", stat.filthit, stat.rtr, stat.ext, stat.inv);
       if ((len)&&(!stat.rtr)) {
          data-=len;
          can_debug("\r\n    DATA = ");
          for (i=0;i<len;i++) {
            can_debug("%X ",*data);
            data++;
          }
       }
       can_debug("\r\n");
    #endif

    return(1);
}

[code/]
insanın gerçekten isteyipte yapamıcağı bişey oldugunu düşünmüyorum

tufican

arkadaslar konuyu ccs info forumlarına yazıp detaylı şekilde ogrendim problemi olan arkadaslara yardım edebilirim
insanın gerçekten isteyipte yapamıcağı bişey oldugunu düşünmüyorum

saucompeng

@Tufican  ,

Merhabalar, Benim baudrate hakkında problemim var , Can hattım 1Mbit/s 18F4585(20MHz OSC) ve MCP2551 kullanıyorum.  Can-18xx8.c dosyasındaki set_baud fonksiyonundaki ayarlar sebebiyle sistemin okuma yapmadığını düşünüyuorum. Bu konuda bana yardımcı olabilir misin?

Selamlar...
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

gambit1244

ustam sana tavsiye önce can hattını 250 k yada 100 k ya düşür 1mb izlenmede pic veya kullandıgın trans reciever problem yaratabiliyor once 100k ya ayarla sonra 1 mbit e çıkartırsın şimdi sana ayarları soyluyorum
oncelikle prescalar degerini belirlemen gerekiyor bunu çalışma frekansına gore bikez ayarlıyorsun sonra cokta ellemen gerekmiyor
20 mhz kristalin varsa: ( Tq = (2 x (PRE + 1))/Fosc ) formülünden
prescalar degerine 1 yazarsan...
tq=(2x( 1 + 1 ))/20.000.000)
tq=1/5000000 çıkyıor yani okadar saniyede bir tq üretiyorsun bunun tersi
saniyede 5 milyon tq üretiyorsun demek oluyor

şimdi saniyede 5 milyon quanta üretebiliyorsun. eğer haberleşmek istedigin hız 100 kb ise

5000000 / 100000 = 50 saniyede 50 quanta da bir pals atarsan 100 kb hızında çalışmış olursun
şimdi 50 tane quanta vakit harcaman lazım 1 tanesini start anında harcıyorsun geriye 49 tane kalıyor
bunları harcamak için The propagation time, seg1, and seg2. ayarlarını degiştirmelisin

(SEGMENT_1 e yazdığın değer + 1) + (PROPAGATION_TIME 'a yazdığın değer + 1) + ( SEGMENT_2 ye yazdığın değer +1) = 49 olması lazım

NOT( seg1 ve seg2 degerlerini eşit ver nedenini bilmiyorum ama herkez oyle yapıyor eşit olmayınca 1 - 0 degerleri bozuluyor olabilir)

şimdi benim baud hesaplamada kullandıgım basit bir yontemi paylaşayım 49 quantayı 3 degişkene paylaştırmam gerekiyor 49 dan 3 yada 5 çıkart kalan çift değeri 2 ye böl birer eksiklerini programa yaz yani...

49 - 5 = 44        burdaki beş propogation time unutma burda 5 yazıyor ama sen programa 4 yazıcaksın çünkü +1 hesaplıyor

44 / 2 = 22       2 parçaya boldüm bunlar eşit seg1 ve seg2 parçaları unutma 22 yazıyor ama sen 21 yazıcaksın
program onu zaten 22 olarak kaydedicek

prescelar               1
seg1                     21
propogation time  4
seg2                     21

ayarları bu şekilde yaparsan yüzde 90 100 kb ile haberleşir yüzde 90 diyorum cünkü bazen ayarlar tutmayabiliyor tutmazsa sayı sistemini degiştirmeyi dene yani
prescalar degerini 1 degilde 3 yap mesela ozaman nolucak
başka bir ornekle anlatayım

(4+1)x2 = 10 
20.000.000 / 10 = saniyede 2 milyon time quanta yapar
şimdi
saniyede 2 milyon time quantan varsa saniyede 1 milyon tane can mesajı gondermen imkansız gibi birşey çünkü 3 tane degişkenin var oyüzden bunu arttırdıkca hızını sınırlarsın

2milyon / 50kb =  40 time quanta yapar bir tanesi startta gitti geriye kaldı 39 tane quanta
prescalar degerin                                                         4
39 - 9 = 30           propogation degerin 9-1                 8
30 / 2 = 15           seg1 ve seg 2 degerin 15-1           14
hızın                                                                           50 kb/sn


şimdi birde 1mb için ornek yapalım
frekansın 20 mhz

prescalar degerin 1 ollsun
20000000/ (1+1)x2

5000000 tq - per second yapar
5000000 / 1 000 000               burdaki 1 milyon 1 megabit hızındaki can mesajının rakamı
5        time quantada bir mesaj gondermelisin
birtanesi start ta gitti kaldımı 4
şimdi

hepsine en az bir versen ve 2 ile çarpsan en az 6 tane tq lazım ama elinde 4 tane var
işte burda 1mb ile gondermen imkansız
ama şunu bir dene

seg1 = 0
propogation = 1
seg2 =0

boyle yazarsan program bunu
seg1 = 0+1 =1
propogation = 1+1 =2
seg2 = 0+1 =1
burdanda 1+2+1 = 4 verir sana ama bunu kabul edermi bilmiyorum dene eger kabul ederse verir kabul etmezse 40 mhz lık bir kristal kullanmayı dene
umarım anlatabilmişimdir matematik kısmında hatalarım varsa düzeltin arkadaşlarım
başarılar...
bu arada yeni hesap aldım forum kurallarını okumadıgım için yazdıgım mesajı düzeltmesini bilmiyordum farkında olmadan flood yapıyormuşum artık ogrendik :)
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

saucompeng

Selamlar; Bİlgiler için öncelikle zahmet verdin çok teşekkür ederim. İkinci olarak benim mevcut hattı okumam gerekiyor, hatta birşey vermeyeceğim. Bu konuda yine sıkıntı mı yapar mı 1mBit?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

gambit1244

#5
dedigim gibi transcieverin 1 mb için uygunsa pic in uygunsa ve yeterli mhz de çalışan kristal ile okuma yazılımın varsa sorun olmaz
benim aldıgım kitte mesela ben yapamadım 1mb ile çalışmayı. çokta ugraşmadıgım için olabilir en fazla 500 mhz e çıkmıştım elimde bikaç yazdıgım program var istersen paylaşabilirim

ayrıca dostum simdi dusundumde 1mb hızı izlemek için bence profesyonel bir cihaza ihtiyacın var bunu ne yapıcaksın izleyip usb ile bilgisayara atabilirsin bukadar bilgiyi ancak seri porttan alamazsın boyle bir bilgi akışını seri porttan izlemen çok zor gibime geliyor anca işine yarayanları filtreleyerek seri porta aktarabilirsin oda baya sıkıntılı olur tam olarak ne izlicegini ozel mesaj ile yazarsan daha iyi yardımcı olabilirim
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

Okan AKÇA

canbus end. haberleşme yöntemidir.canbus tasarlanırken hız ön planda olarak yapılmış protol degildir. yüksek hızda veri aktaracam diyorsan canbus bu iş icin uygun degil kaldiki canbus mesafesi rs485 gibi degil canbus veri güvenligi onceligi gibi kavramlar icin tasarlanmıs bir sistemdir. dedigin hızda kullandıgın zaman bir cok sorun yasayacaksın mesafende uzun olursa  sorunlardan basını kurtaramıyacaksın bizde ilk başladıgımızda bu işlere aynı sizin gibi düsünüyorduk hızlı olsun takıntılarımız oluyordu.ancak ögrencem diyorsan ayrı bir konu bende meraktan canbus kit aldım kurcaladım bir şeyler yaptım daha sonra köşeye koydum bir dahada ilgilenmedim.ticari bir iş yapacaksan bütün riskleri göze almalısın

saucompeng

ELimde bir endüstriyel ürün mevcut ve 1Mbit/s çıkış vermekte. Osebeple bu ürünü okumak için başka çarem yok. Piyasada ürünler var fakat ben kendim picle okuyup grafik Lcdye basmam gerekiyor.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

gambit1244

#8
uğraşıp yapabilirsin 20 metreye kadar hiç sorun yaşamadan okuma filtreleme ve lcd ye basma yapabilirsin ben otomotiv haberleşmesi yapıyorum araç içi can networkuyle ilgili araçlarda max hız 500kb oldugu için hiç 1 denemedim ama c biliyorsan ve grafik lcd ye basma kısmını biliyorsan yaparsın kafanı yorma bende yardımcı olurum
önemli olan nokta şuki filtreledigin adresten saniyede kaçtane bilgi geliyor eger bu bilgi akışı ciddi hızlı bi adres ise tüm dataları alamayabilirsin tek sorun o olabilir yüzde 10 bi ihtimal
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.