25 Ağustos 2019, 12:59:47

Haberler:

Picproje Pazar Sohbetleri: https://bit.ly/2GHsjAK


STM32F103 CANBus Problemi

Başlatan baran123, 26 Nisan 2017, 01:29:57

CLR

ST'nin sample projelerindeki kod kesinlikle çalışıyordur ama yinede benim yazdığım kısımdan kısmen paylaşayım.

2008'deki aşağıdaki gibi kendi yazdığım bir ST library, muhtemelen işinizi görmez çünkü her şey bit bazında yapılıyor, register düzeyinde programlama yapabiliyor olmanız lazım.


void
Can_Setup
(u8 can_mode){
    
u16 over_time=0xFFFF;
    
can_reset();                // can ayarları reset
    
can_enable();               // can modulu enable
// PB8 ve PB9 kullanılacak, remap yapacağız, AFIOEN enable olmalı, 
    
afio_enable();       
    
afio_mapr.bits.CAN_REMAP=0x2// remap, PB8(RX),PB9(TX) : can için kullanılacak
//  afio_mapr.bits.CAN_REMAP=0x0; // default durum zaten, remapsiz, PA11,PA12: can için kullanılacak
//  afio_mapr.bits.CAN_REMAP=0x3; // remap, PD0(RX),PD1(TX): can için kullanılacak
// GPIOB enable olmalı, port setupta enable edilmişti
//  gpiob_enable();
    
gpiob_crh.bits.MODE8=GpioMODE_input;            // input
    
gpiob_crh.bits.CNF8=GpioCNF_PUPD_in_APP_out;    // pull-up/pulldown input, 
    
    
gpiob_crh.bits.MODE9=GpioMODE_50mhz_out;        // 50mhz out
    
gpiob_crh.bits.CNF9=GpioCNF_PUPD_in_APP_out;    // Alternate  push-pull, 

//    gpiob_odr.bits.ODR8=0;      // pull-down
//    gpiob_odr.bits.ODR8=1;      // pull-up 

// sleep modundan çıkılmadıkça 
	
sleep bit clear edilemiyor
    
can_mcr.bits.SLEEP=0;
// can init isteği
    
can_mcr.bits.INRQ=1;   
    
can_mcr.bits.NART=1;            // yeniden otomatik gönderme devre dışı
// init ok mi?
    
Can_Flags.InitFail=0;
    while(!
can_msr.bits.INAK){          // 0 iken bekle
        
if(over_time==0){
            
Can_Flags.InitFail=1;       // hata var
            
break;     
        } 
        
over_time--;
    }
// 28Mhz'de bitrate 250Kbps
    
can_btr.bits.SJW=2;
    
can_btr.bits.TS1=8;
    
can_btr.bits.TS2=3;
    
can_btr.bits.BRP=7
// can modunu ayarla
    
switch(can_mode&0x3) {
        case 
NormalMode:    can_btr.bits.SILM=0can_btr.bits.LBKM=0; break;    // Normal mod
        
case LoopbackMode:  can_btr.bits.SILM=0can_btr.bits.LBKM=1; break;    // loopback mod
        
case SilentMode:    can_btr.bits.SILM=1can_btr.bits.LBKM=0; break;    // silent mod
        
case TestMode:      can_btr.bits.SILM=1can_btr.bits.LBKM=1; break;    // test mod (loop and silent
    
}
/*   
    can_mcr.bits.INRQ=0;
    over_time=0xFFFF;
    while(can_msr.bits.INAK){           // 1 iken bekle
        if(over_time==0){
            Can_Flags.InitFail=1;       // Initial gerçekleşmediyse hata var
            break;     
        } 
        over_time--;
    }

*/
// sadece fifo0'ı kullanacağız dolayısıyla sadece transmit mailbox 0 kullanılacak
    
can_ier.bits.TMEIE=1;           // Transmit mailbox boş olduğunda interrupt oluşsun
    
can_ier.bits.FMPIE0=1;          // fifo0'a mesaj geldiğinde interrupt oluşsun

    
usbhp_cantx_int_set(pri_2);     // 2. öncelikli can tx enable
                                    
    
usb_lp_can_rx0_int_set(pri_1);  // 1. öncelikli can rx, data alımı önemli

}



Standart ST lib içeren bir projemden bir paylaşım yapayım. Bu şekilde TX yapabiliyor olmanız lazım



void CAN_GPIO_Configuration
(void)
{
	
GPIO_InitTypeDef GPIO_InitStructure;
	

	
/* Configure CAN pin: RX */
	
GPIO_InitStructure.GPIO_Pin GPIO_Pin_11;
	
GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;
	
GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;
	
GPIO_Init(GPIOA, &GPIO_InitStructure);   
	
/* Configure CAN pin: TX */
	
GPIO_InitStructure.GPIO_Pin GPIO_Pin_12;
	
GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;
	
GPIO_Init(GPIOA, &GPIO_InitStructure);
	
     
}


void CAN_NVIC_Configuration(void)
{
	
NVIC_InitTypeDef NVIC_InitStructure;

	
// Enable CAN1 RX0 interrupt IRQ channel 
	
NVIC_InitStructure.NVIC_IRQChannel USB_LP_CAN1_RX0_IRQn;
	
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0;
	
NVIC_InitStructure.NVIC_IRQChannelSubPriority 0;
	
NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;
	
NVIC_Init(&NVIC_InitStructure);
}

void CAN_Configuration(void)
{
	

	
CAN_InitTypeDef        CAN_InitStructure;

	
/* CAN Periph clock enable */
	
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1ENABLE);

	
CAN_NVIC_Configuration();
	
	
	
	
	
	
	
	
	
	
// Can interrupt
	
CAN_GPIO_Configuration();
	
	
	
	
	
	
	
	
	
	
// Gpio settings ok

	
CAN_DeInit(CAN1);
	
	
	
	
	
	
	
	

	
CAN_StructInit(&CAN_InitStructure);

	
CAN_InitStructure.CAN_TTCM DISABLE;
	
CAN_InitStructure.CAN_ABOM DISABLE;
	
CAN_InitStructure.CAN_AWUM DISABLE;
	
CAN_InitStructure.CAN_NART DISABLE;
	
CAN_InitStructure.CAN_RFLM DISABLE;
	
CAN_InitStructure.CAN_TXFP DISABLE;
	
CAN_InitStructure.CAN_Mode CAN_Mode_Normal;
	
CAN_InitStructure.CAN_SJW CAN_SJW_1tq;
	
CAN_InitStructure.CAN_BS1 CAN_BS1_8tq;
	
	
// tBS1=8 olur
	
CAN_InitStructure.CAN_BS2 CAN_BS2_3tq;
	
	
// tBS2=3 olur
	
CAN_InitStructure.CAN_Prescaler 30;
	
	
	
        
// 100KBps 
// sample point %75 oluyor

	
if (
CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED){
	
	

	
}
	


    
CanRxFifo_Init();

	
//int enable
	
CAN_ITConfig(CAN1,CAN_IT_FMP0ENABLE);
	
CanFilterSettings();
	

	

}


void CanTxDataSend(MyCanTxMsg_TypedefCanTxMessage)
{
	
u8
	
TxMailBoxu16 TimeOut=0x3FFF;
	
TxMailBox CAN_Transmit(CAN1, (CanTxMsg *)CanTxMessage);
	
while((
CAN_TransmitStatus(CAN1,TxMailBox)!=CAN_TxStatus_Ok) && (TimeOut != 0)){
	
	
TimeOut--;
	
}
	
if(
TimeOut == ) {
	
	
	
	
	
	
	
	
// ACK gelmeşse haberleşmesi kes
	
	
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
	
}

}


Knowledge and Experience are Power

eeburakdemir

@CLR teşekkür ederim paylaşımların için.
Asla pes etme...

eeburakdemir

@CLR hocam aklıma bişi geldi, sizin bu çalışıyor dediğiniz projede mcp2551 Vref bacağı bağlantısı nasıl ?
Asla pes etme...

CLR

Vref boş, RS(slewrate) pini 10K ile ground'a bağlı, yani maksimum slewrate
Knowledge and Experience are Power

eeburakdemir

Asla pes etme...

baran123

Ben RS pinlerini 10K ile çektim GND ye VREF pinlerinde 1.64V falan okuyorum. 120 ohm'larda takılı
Beslemedede sorun yok ama hala çalışmıyor. Çoook enteresan.
Ya bu Trancerecieverlar bozuk yada başka bir problem var

CLR

07 Mayıs 2017, 03:52:37 #36 Son düzenlenme: 07 Mayıs 2017, 03:53:39 CLR
Anladığım kadarıyla stm32'nin can tx pininden çıkış işini çözdünüz, tekrar mcp2551'e döndüğünüze göre, Emin değilseniz Cantx pini ile can Rx pini arası 22ohm-47ohm ile birbirine bağlayın,isterseniz kısadevrede edebilirsiniz ama ben temkinli olmayı severim.  can tx yapıyorsa canrx interrupt oluşur. (normal modda, loopback gibi)

o kartlardan elimde 2-3 tane var, fotosunu atacaktım ama fotoda çiplerin yazıları okunmuyor. Üzerlerinde stm32f103c8t6 + mcp2551 dizili, hatta 11 adet kart aynı can bus'ına bağlı, birbirleri ile haberleşiyorlar, O zamanlar 3V3 transceiver kullanmadım çünkü her karta 5V geliyor, bir LDO ile 3V3'e düşüyor, 5V ile mcp2551'ler besleniyorlar, 3V3 ile stm32 ve diğer komponentler(PGA,opamplar vs var)
Şimdiki projelerde herşey 3V3 olduğundan TI'ın 3V3'lük transceiver'larını kullanıyorum, mcp2551'i kullanmam için sistemde 5V olması lazım ve pic18f4580 gibi can module içeren 5V'luk bir işlemci.
Knowledge and Experience are Power

emin.kiran

Ben forumda baska bir bilgi ararken bu konuda yanlislik oldugunu farkettim konu hortlayacak ama arayan arkadaslarin bilgisi olsun diye ekliyorum STMf103 de usb ve canbus ayni anda calismiyor diye manuelde bilgi var dolayisi ile kullanilamiyor onun yerine spi uzerinden canbus modul kullanilmasi uygun olur

mehmetkazakli

10 Şubat 2019, 22:01:53 #38 Son düzenlenme: 10 Şubat 2019, 22:17:16 mehmetkazakli
konu biraz eski ama yinede sormak istiyorum. Bende  şuanda CAN bus iletişim protokolünü kullanarak bir tasarım gerçekleştiriyorum. Burda belirttiğiniz mikrodenetleyicinin (STM32F103) besleme voltajı 3.3V . bu logic seviyesi 1 = 3.3 V anlamına geliyor galiba. Can Transiver'in (MCP2551) beslemesi ise 5V. MCP2551'in mikroişlemciye giden pinlerinden RXD nin high değeri min 2V - max VDD yazıyor. Yani mikrodentleyicinin pininden 3.3V gelince MCP2551 bunu high olarak algılıycak. Aynı şekilde mikrodenetleyiciye bağlı diğer pin TXD ise mikrodenetleyiciye bilgi göndericek ve high değeri min:0.7xVDD yani 3.5V Mikrodenetleyicinin pinine zarar vermez galiba çünki + tolerans değeri vardır. Ben bu konuda ilk tasarımı yapıacm ve böyle yorumladım. Yanlış mı düşündüm. Tasarımı yaptınız mı ve çalış mı? Başka bir entegre mi kullandınız ?

dumansiz

11 Şubat 2019, 17:29:02 #39 Son düzenlenme: 11 Şubat 2019, 17:33:50 dumansiz







Pinler zaten 5V toleranslı. Eğer MCP2551 3.3V toleranslı değilse 3.3V toleranslı bir "CAN Transceiver" kullanabilirsiniz.

Mucit23

Alıntı yapılan: mehmetkazakli - 10 Şubat 2019, 22:01:53konu biraz eski ama yinede sormak istiyorum. Bende  şuanda CAN bus iletişim protokolünü kullanarak bir tasarım gerçekleştiriyorum. Burda belirttiğiniz mikrodenetleyicinin (STM32F103) besleme voltajı 3.3V . bu logic seviyesi 1 = 3.3 V anlamına geliyor galiba. Can Transiver'in (MCP2551) beslemesi ise 5V. MCP2551'in mikroişlemciye giden pinlerinden RXD nin high değeri min 2V - max VDD yazıyor. Yani mikrodentleyicinin pininden 3.3V gelince MCP2551 bunu high olarak algılıycak. Aynı şekilde mikrodenetleyiciye bağlı diğer pin TXD ise mikrodenetleyiciye bilgi göndericek ve high değeri min:0.7xVDD yani 3.5V Mikrodenetleyicinin pinine zarar vermez galiba çünki + tolerans değeri vardır. Ben bu konuda ilk tasarımı yapıacm ve böyle yorumladım. Yanlış mı düşündüm. Tasarımı yaptınız mı ve çalış mı? Başka bir entegre mi kullandınız ?
MCP2551 yerine SN65HVD230 kullanın. Doğrudan 3.3V uyumlu.

mehmetkazakli

TJA1050T/CM,118  var. Bunu kullanmayı düşündüm. Fİyatı uygun, 5V ve 3.3V uyumlu ve özdisanda bolca var diye. Daha önceden kullanan var mı bu entegreyi?

baran123

@emin.kiran foruma bir süredir bakamadım.
Konuda herhangi bir hata yok çünkü ben USB ve CanBus'ı aynı anda zaten kullanmamıştım.
Bu sorunun asıl sebebi benim kullandığım MCP2551'in "büyük ihtimal" sahte olmasıydı.

Benim tavsiyem direk 3.3V uyumlu Transceiver kullanın olsun bitsin.
Ben bir sürü farklı CAN TJA1050T denedim hepsi düzgün çalışıyor değişik bir durum yok bu yüzden TJA1050 kullanabilirsiniz