STM32F103 CANBus Problemi

Başlatan baran123, 25 Nisan 2017, 22: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=0; can_btr.bits.LBKM=0; break;    // Normal mod
        case LoopbackMode:  can_btr.bits.SILM=0; can_btr.bits.LBKM=1; break;    // loopback mod
        case SilentMode:    can_btr.bits.SILM=1; can_btr.bits.LBKM=0; break;    // silent mod
        case TestMode:      can_btr.bits.SILM=1; can_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_CAN1, ENABLE);

	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_FMP0, ENABLE);
	CanFilterSettings();
	
	
}


void CanTxDataSend(MyCanTxMsg_Typedef* CanTxMessage)
{
	u8	TxMailBox; u16 TimeOut=0x3FFF;
	TxMailBox = CAN_Transmit(CAN1, (CanTxMsg *)CanTxMessage);
	while((CAN_TransmitStatus(CAN1,TxMailBox)!=CAN_TxStatus_Ok) && (TimeOut != 0)){
		TimeOut--;
	}
	if(TimeOut == 0 ) {								// 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

#36
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

#38
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

#39







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, 19: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