STM32F103 CANBus Problemi

Başlatan baran123, 25 Nisan 2017, 22:29:57

eeburakdemir

@CLR ve @baran123 hocam loopback mode çalışıyor fakat mcp takınca hattan veri göremiyoruz. Logic ile kontrol ediyoruz.
Asla pes etme...

magnetron


bende bu kodlar çalıştı

    /* CAN register init */
CAN_Initialize(void){

  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);


  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM=DISABLE;
  CAN_InitStructure.CAN_ABOM=DISABLE;
  CAN_InitStructure.CAN_AWUM=DISABLE;
  CAN_InitStructure.CAN_NART=ENABLE;
  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_3tq;
  CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;
  CAN_InitStructure.CAN_Prescaler=4;
  RAM[PARAMETERS+142*2]=CAN_Init(CAN1, &CAN_InitStructure);


  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=0;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=(0x00001234L<<3)&0xffff0000L;
  CAN_FilterInitStructure.CAN_FilterIdLow=((0x00001234L<<3)|0x4)&0x0000ffffL;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);


  /* CAN FIFO0 message pending interrupt enable */   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

return ;
}


void USB_LP_CAN_RX0_IRQHandler(void)
{
  CanRxMsg RxMessage;


  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;


while(CAN_MessagePending(CAN1, CAN_FIFO0)){
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);}


    RAM[PARAMETERS+140*2]=RxMessage.Data[1];
}



baran123

@magnetron verdiğin kodlar sadece alıcı kısmı.


Ben veri gönderme yapamıyorum bir türlü.


Demin loopback moda alıp cantx gözlemledim. ayarladığım baudrate'de veriyi görebiliyorum.Ama verinin sonunda NAK ifadesi mevcut. Bu ne anlama geliyor ?



CLR

 stm tx pininde hareket yoksa kurulum hatası vardır mesela remap gerektiren gpioya bağlamış olabilirsin yani kısacası görmek lazım, eklersen kodları inceleyebilirim
Knowledge and Experience are Power

baran123

Hocam init kodları ektedir.
void main (void)
{
    Clock_Config();
    RCC_Config();
    GPIO_Config();
    CAN_Config();

    TxMessage.StdId = 0;
    TxMessage.ExtId = 0;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 2;
    TxMessage.Data[0] = 'A';
    TxMessage.Data[1] = 'B';

    LED_Off();

    for(;;)
    {
        CAN_Transmit(CAN1, &TxMessage);

        while ((CAN_TransmitStatus(CAN1, 0) != CANTXOK));

        Delay_ms(500);
    }
}
static void RCC_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

static void GPIO_Config(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;

    GPIO_DeInit(GPIOA);
    GPIO_DeInit(GPIOB);
    GPIO_DeInit(GPIOC);
    GPIO_StructInit(&GPIO_InitStructure);

     /** ADC Pins **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /** CAN1 RX **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /** CAN1 TX **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /** LED Pin **/
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /**
     * GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
     * GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
     */
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}

static void CAN_Config(void)
{
    /**
      * CAN Baudrate = 200 kBit/s
      * Bit Rate = (CanBus Freq = APB1) / (Prescaler * (SJW + BS1 + BS2)
      * SJW must be 1
      * 36 MHz / (9 * (1 + 11 + 8))
      * 200 kBit/s
      **/
    CAN_InitTypeDef         CAN_InitStructure;
    CAN_FilterInitTypeDef   CAN_FilterInitStructure;
    NVIC_InitTypeDef        NVIC_InitStructure;

    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /** CAN cell init */
    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_11tq;
    CAN_InitStructure.CAN_BS2       = CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = 9;
    canInitStatus = CAN_Init(CAN1, &CAN_InitStructure);

    /** CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber            = 0;
    CAN_FilterInitStructure.CAN_FilterMode              = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale             = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh            = 0;
    CAN_FilterInitStructure.CAN_FilterIdLow             = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh        = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow         = 0;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment    = CAN_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation        = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel                    = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0xFF;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0xFF;
    NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

CLR

Açıkçası buraya yapıştırdığın kodlarda bir sıkıntı yok gibi ama hatanın yerini şöyle bulabilirsin,


1) Öncelikle TX pininden logic analyzer ile bir sinyal okumadığın için sorunun MCP2551 kaynaklı değil

2) Can tx pinine bağlı pull-up'ı sök

3) Can modulü init kısmını kontrol et (canInitStatus == CAN_InitStatus_Success olmalı)



canInitStatus = CAN_Init(CAN1, &CAN_InitStructure);
if(canInitStatus != CAN_InitStatus_Success)             //
  // fail


Burası fail ( CAN_InitStatus_Failed ) ise can init kısmında  gözden kaçan bir hata vardır.

4) Ok ise, tx kısmını kontrol et, CAN_TxStatus_Ok dönmeli

TxMailBox = CAN_Transmit(CAN1, &TxMessage);
while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok) && (TimeOut != 0)) {
    TimeOut--;
}

Bu şekilde çözebiliyor olmalısın.
Knowledge and Experience are Power

baran123

@CLR Hocam pull up söktüm ve init kontrolünü yaptım başarılı gözüküyor. STM32+MCP karşıda sadece MCP2551(TX RX kısa devre)

Tx kısmını kontrol ettiğimde while döngüsünde takılıyor yani nedense veri gitmiyor.
while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok));

CLR

Can init ok olup, loopback'te çalışıp normal modda çalışmaması garip bir durum.
Can portlarını ve remap'i değiştirip/düzenleyip başka bir gpio'da dener misin?


Knowledge and Experience are Power

baran123

@CLR  Hocam işlemcide başka bir pine CANTX-RX atayamam kullandığım işlemcide böyle bir seçenek yok. Büyük pinli modellerde var :/

CLR

Olmaz olurmu, sen remap yapmışsın zaten, remap'in amacı asıl pinlerin yerine 2ncil pinleri kullanmak, yani remap varsa başka pinlerde vardır. pa11-pa12 kullanabilirsin.
Knowledge and Experience are Power

baran123

@CLR  Hocam ben onu görmedim kusura bakmayın. Fakat o pinlerde USB ye denk geliyor. Fakat yinede denedim ama sonuç aynı.
Bu arada remap'ı nasıl yapmam lazım ?
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
şeklindemi ?

iki türlüde yaptım fakat olmadı ama loopback moda alınca led yandı yani loopback çalışıyor
int main(void)
{
    Clock_Config();
    RCC_Config();
    GPIO_Config();
    CAN_Config();
    //ADC_Config();
    //DMA_Config();

    TxMessage.StdId = 0;
    TxMessage.ExtId = 0;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 2;
    TxMessage.Data[0] = 'A';
    TxMessage.Data[1] = 'B';

    LED_Off();

    /*ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    while (!status);

    ADC_SoftwareStartConvCmd(ADC1, DISABLE);*/

    for(;;)
    {
        TxMailBox = CAN_Transmit(CAN1, &TxMessage);

        while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok));

        LED_On();

        Delay_ms(500);
    }
}

static void RCC_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

static void GPIO_Config(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;

    GPIO_DeInit(GPIOA);
    GPIO_DeInit(GPIOB);
    GPIO_DeInit(GPIOC);
    GPIO_StructInit(&GPIO_InitStructure);

    /** ADC Pins **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /** ADC Pins **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

//    /** CAN RX **/
//    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_8;
//    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_IPU;
//    GPIO_Init(GPIOB, &GPIO_InitStructure);
//
//    /** CAN TX **/
//    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_9;
//    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_PP;
//    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
//    GPIO_Init(GPIOB, &GPIO_InitStructure);


        /** CAN RX **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /** CAN TX **/
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /** LED Pin **/
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /** LED Pin **/
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /**
     * GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
     * GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
     */
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}

static void CAN_Config(void)
{
    /**
      * CAN Baudrate = 200 kBit/s
      * Bit Rate = (CanBus Freq = APB1) / (Prescaler * (SJW + BS1 + BS2)
      * SJW must be 1
      * 36 MHz / (9 * (1 + 11 + 8))
      * 200 kBit/s
      **/
    CAN_InitTypeDef         CAN_InitStructure;
    CAN_FilterInitTypeDef   CAN_FilterInitStructure;
    NVIC_InitTypeDef        NVIC_InitStructure;

    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /** CAN cell init */
    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_11tq;
    CAN_InitStructure.CAN_BS2       = CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = 9;
    canInitStatus = CAN_Init(CAN1, &CAN_InitStructure);

    /** CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber            = 0;
    CAN_FilterInitStructure.CAN_FilterMode              = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale             = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh            = 0;
    CAN_FilterInitStructure.CAN_FilterIdLow             = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh        = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow         = 0;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment    = CAN_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation        = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel                    = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0xFF;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0xFF;
    NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

CLR

Led ile test yapıyorsan canbus testini anlayamazsın, can modulü init olmuşsa mutlaka tx yapar, senin init fonksiyonun bir kez data gönderiyor, başarısız olursa tekrar tekrar göndermiyor yani datayı ancak lojik analyzer ile görebilirsin pa11 ve pa12 içinse remap fonksiyonunu hiç kullanmaman lazım yani onu kapat ve pinleri ayarla ve derle
Knowledge and Experience are Power

baran123

@CLR Hocam o satırı aldırdım ve A portunda logicde veriler gözüküyor ama loopbackde normal moda aldım bus da hiçbir şey yok.
Kafayı sıyırıcam :)

CLR

Neyse bundan sonrası sana ait, testte vs bir yerlerde hata yapıyorsundur, stm32f103c8t6 ile mcp2551'i 2008'de bir cihaz yaparken kullandım, sorunsuz çalışıyor.
Knowledge and Experience are Power

eeburakdemir

@CLR  hocam bu konuda bizimle en azından yapmış olduğunuz cihazınızda bulunan can bus modulunun init , transmit ve receive kısmından paylaşım yapabilir misiniz ? En azından karşılaştırıp hatanın nerede olduğuna karar veririz.
Asla pes etme...